cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

head.S (7159B)


      1/*
      2 * arch/xtensa/kernel/head.S
      3 *
      4 * Xtensa Processor startup code.
      5 *
      6 * This file is subject to the terms and conditions of the GNU General Public
      7 * License.  See the file "COPYING" in the main directory of this archive
      8 * for more details.
      9 *
     10 * Copyright (C) 2001 - 2008 Tensilica Inc.
     11 *
     12 * Chris Zankel <chris@zankel.net>
     13 * Marc Gauthier <marc@tensilica.com, marc@alumni.uwaterloo.ca>
     14 * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com>
     15 * Kevin Chea
     16 */
     17
     18#include <asm/asmmacro.h>
     19#include <asm/processor.h>
     20#include <asm/page.h>
     21#include <asm/cacheasm.h>
     22#include <asm/initialize_mmu.h>
     23#include <asm/mxregs.h>
     24
     25#include <linux/init.h>
     26#include <linux/linkage.h>
     27
     28/*
     29 * This module contains the entry code for kernel images. It performs the
     30 * minimal setup needed to call the generic C routines.
     31 *
     32 * Prerequisites:
     33 *
     34 * - The kernel image has been loaded to the actual address where it was
     35 *   compiled to.
     36 * - a2 contains either 0 or a pointer to a list of boot parameters.
     37 *   (see setup.c for more details)
     38 *
     39 */
     40
     41/*
     42 *  _start
     43 *
     44 *  The bootloader passes a pointer to a list of boot parameters in a2.
     45 */
     46
     47	/* The first bytes of the kernel image must be an instruction, so we
     48	 * manually allocate and define the literal constant we need for a jx
     49	 * instruction.
     50	 */
     51
     52	__HEAD
     53	.begin	no-absolute-literals
     54
     55ENTRY(_start)
     56
     57	/* Preserve the pointer to the boot parameter list in EXCSAVE_1 */
     58	wsr     a2, excsave1
     59	_j	_SetupOCD
     60
     61	.align	4
     62	.literal_position
     63_SetupOCD:
     64	/*
     65	 * Initialize WB, WS, and clear PS.EXCM (to allow loop instructions).
     66	 * Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow
     67	 * xt-gdb to single step via DEBUG exceptions received directly
     68	 * by ocd.
     69	 */
     70#if XCHAL_HAVE_WINDOWED
     71	movi	a1, 1
     72	movi	a0, 0
     73	wsr	a1, windowstart
     74	wsr	a0, windowbase
     75	rsync
     76#endif
     77
     78	movi	a1, LOCKLEVEL
     79	wsr	a1, ps
     80	rsync
     81
     82	.global _SetupMMU
     83_SetupMMU:
     84	Offset = _SetupMMU - _start
     85
     86#ifdef CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX
     87	initialize_mmu
     88#if defined(CONFIG_MMU) && XCHAL_HAVE_PTP_MMU && XCHAL_HAVE_SPANNING_WAY
     89	rsr	a2, excsave1
     90	movi	a3, XCHAL_KSEG_PADDR
     91	bltu	a2, a3, 1f
     92	sub	a2, a2, a3
     93	movi	a3, XCHAL_KSEG_SIZE
     94	bgeu	a2, a3, 1f
     95	movi	a3, XCHAL_KSEG_CACHED_VADDR
     96	add	a2, a2, a3
     97	wsr	a2, excsave1
     981:
     99#endif
    100#endif
    101
    102	movi	a0, _startup
    103	jx	a0
    104
    105ENDPROC(_start)
    106	.end	no-absolute-literals
    107
    108	__REF
    109	.literal_position
    110
    111ENTRY(_startup)
    112
    113	/* Set a0 to 0 for the remaining initialization. */
    114
    115	movi	a0, 0
    116
    117#if XCHAL_HAVE_VECBASE
    118	movi    a2, VECBASE_VADDR
    119	wsr	a2, vecbase
    120#endif
    121
    122	/* Clear debugging registers. */
    123
    124#if XCHAL_HAVE_DEBUG
    125#if XCHAL_NUM_IBREAK > 0
    126	wsr	a0, ibreakenable
    127#endif
    128	wsr	a0, icount
    129	movi	a1, 15
    130	wsr	a0, icountlevel
    131
    132	.set	_index, 0
    133	.rept	XCHAL_NUM_DBREAK
    134	wsr	a0, SREG_DBREAKC + _index
    135	.set	_index, _index + 1
    136	.endr
    137#endif
    138
    139	/* Clear CCOUNT (not really necessary, but nice) */
    140
    141	wsr	a0, ccount	# not really necessary, but nice
    142
    143	/* Disable zero-loops. */
    144
    145#if XCHAL_HAVE_LOOPS
    146	wsr	a0, lcount
    147#endif
    148
    149	/* Disable all timers. */
    150
    151	.set	_index, 0
    152	.rept	XCHAL_NUM_TIMERS
    153	wsr	a0, SREG_CCOMPARE + _index
    154	.set	_index, _index + 1
    155	.endr
    156
    157	/* Interrupt initialization. */
    158
    159	movi	a2, XCHAL_INTTYPE_MASK_SOFTWARE | XCHAL_INTTYPE_MASK_EXTERN_EDGE
    160	wsr	a0, intenable
    161	wsr	a2, intclear
    162
    163	/* Disable coprocessors. */
    164
    165#if XCHAL_HAVE_CP
    166	wsr	a0, cpenable
    167#endif
    168
    169	/*  Initialize the caches.
    170	 *  a2, a3 are just working registers (clobbered).
    171	 */
    172
    173#if XCHAL_DCACHE_LINE_LOCKABLE
    174	___unlock_dcache_all a2 a3
    175#endif
    176
    177#if XCHAL_ICACHE_LINE_LOCKABLE
    178	___unlock_icache_all a2 a3
    179#endif
    180
    181	___invalidate_dcache_all a2 a3
    182	___invalidate_icache_all a2 a3
    183
    184	isync
    185
    186	initialize_cacheattr
    187
    188#ifdef CONFIG_HAVE_SMP
    189	movi	a2, CCON	# MX External Register to Configure Cache
    190	movi	a3, 1
    191	wer	a3, a2
    192#endif
    193
    194	/* Setup stack and enable window exceptions (keep irqs disabled) */
    195
    196	movi	a1, start_info
    197	l32i	a1, a1, 0
    198
    199	/* Disable interrupts. */
    200	/* Enable window exceptions if kernel is built with windowed ABI. */
    201	movi	a2, KERNEL_PS_WOE_MASK | LOCKLEVEL
    202	wsr	a2, ps
    203	rsync
    204
    205#ifdef CONFIG_SMP
    206	/*
    207	 * Notice that we assume with SMP that cores have PRID
    208	 * supported by the cores.
    209	 */
    210	rsr	a2, prid
    211	bnez	a2, .Lboot_secondary
    212
    213#endif  /* CONFIG_SMP */
    214
    215	/* Unpack data sections
    216	 *
    217	 * The linker script used to build the Linux kernel image
    218	 * creates a table located at __boot_reloc_table_start
    219	 * that contains the information what data needs to be unpacked.
    220	 *
    221	 * Uses a2-a7.
    222	 */
    223
    224	movi	a2, __boot_reloc_table_start
    225	movi	a3, __boot_reloc_table_end
    226
    2271:	beq	a2, a3, 3f	# no more entries?
    228	l32i	a4, a2, 0	# start destination (in RAM)
    229	l32i	a5, a2, 4	# end destination (in RAM)
    230	l32i	a6, a2, 8	# start source (in ROM)
    231	addi	a2, a2, 12	# next entry
    232	beq	a4, a5, 1b	# skip, empty entry
    233	beq	a4, a6, 1b	# skip, source and dest. are the same
    234
    2352:	l32i	a7, a6, 0	# load word
    236	addi	a6, a6, 4
    237	s32i	a7, a4, 0	# store word
    238	addi	a4, a4, 4
    239	bltu	a4, a5, 2b
    240	j	1b
    241
    2423:
    243	/* All code and initialized data segments have been copied.
    244	 * Now clear the BSS segment.
    245	 */
    246
    247	movi	a2, __bss_start	# start of BSS
    248	movi	a3, __bss_stop	# end of BSS
    249
    250	__loopt	a2, a3, a4, 2
    251	s32i	a0, a2, 0
    252	__endla	a2, a3, 4
    253
    254#if XCHAL_DCACHE_IS_WRITEBACK
    255
    256	/* After unpacking, flush the writeback cache to memory so the
    257	 * instructions/data are available.
    258	 */
    259
    260	___flush_dcache_all a2 a3
    261#endif
    262	memw
    263	isync
    264	___invalidate_icache_all a2 a3
    265	isync
    266
    267#ifdef CONFIG_XIP_KERNEL
    268	/* Setup bootstrap CPU stack in XIP kernel */
    269
    270	movi	a1, start_info
    271	l32i	a1, a1, 0
    272#endif
    273
    274	movi	abi_arg0, 0
    275	xsr	abi_arg0, excsave1
    276
    277	/* init_arch kick-starts the linux kernel */
    278
    279	abi_call	init_arch
    280	abi_call	start_kernel
    281
    282should_never_return:
    283	j	should_never_return
    284
    285#ifdef CONFIG_SMP
    286.Lboot_secondary:
    287
    288	movi	a2, cpu_start_ccount
    2891:
    290	memw
    291	l32i	a3, a2, 0
    292	beqi	a3, 0, 1b
    293	movi	a3, 0
    294	s32i	a3, a2, 0
    2951:
    296	memw
    297	l32i	a3, a2, 0
    298	beqi	a3, 0, 1b
    299	wsr	a3, ccount
    300	movi	a3, 0
    301	s32i	a3, a2, 0
    302	memw
    303
    304	movi	abi_arg0, 0
    305	wsr	abi_arg0, excsave1
    306
    307	abi_call	secondary_start_kernel
    308	j	should_never_return
    309
    310#endif  /* CONFIG_SMP */
    311
    312ENDPROC(_startup)
    313
    314#ifdef CONFIG_HOTPLUG_CPU
    315
    316ENTRY(cpu_restart)
    317
    318#if XCHAL_DCACHE_IS_WRITEBACK
    319	___flush_invalidate_dcache_all a2 a3
    320#else
    321	___invalidate_dcache_all a2 a3
    322#endif
    323	memw
    324	movi	a2, CCON	# MX External Register to Configure Cache
    325	movi	a3, 0
    326	wer	a3, a2
    327	extw
    328
    329	rsr	a0, prid
    330	neg	a2, a0
    331	movi	a3, cpu_start_id
    332	memw
    333	s32i	a2, a3, 0
    334#if XCHAL_DCACHE_IS_WRITEBACK
    335	dhwbi	a3, 0
    336#endif
    3371:
    338	memw
    339	l32i	a2, a3, 0
    340	dhi	a3, 0
    341	bne	a2, a0, 1b
    342
    343	/*
    344	 * Initialize WB, WS, and clear PS.EXCM (to allow loop instructions).
    345	 * Set Interrupt Level just below XCHAL_DEBUGLEVEL to allow
    346	 * xt-gdb to single step via DEBUG exceptions received directly
    347	 * by ocd.
    348	 */
    349	movi	a1, 1
    350	movi	a0, 0
    351	wsr	a1, windowstart
    352	wsr	a0, windowbase
    353	rsync
    354
    355	movi	a1, LOCKLEVEL
    356	wsr	a1, ps
    357	rsync
    358
    359	j	_startup
    360
    361ENDPROC(cpu_restart)
    362
    363#endif  /* CONFIG_HOTPLUG_CPU */
    364
    365/*
    366 * DATA section
    367 */
    368
    369	__REFDATA
    370	.align  4
    371ENTRY(start_info)
    372	.long	init_thread_union + KERNEL_STACK_SIZE
    373
    374/*
    375 * BSS section
    376 */
    377	
    378__PAGE_ALIGNED_BSS
    379#ifdef CONFIG_MMU
    380ENTRY(swapper_pg_dir)
    381	.fill	PAGE_SIZE, 1, 0
    382END(swapper_pg_dir)
    383#endif
    384ENTRY(empty_zero_page)
    385	.fill	PAGE_SIZE, 1, 0
    386END(empty_zero_page)