⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 head.s

📁 xen虚拟机源代码安装包
💻 S
📖 第 1 页 / 共 3 页
字号:
/* * Here is where the ball gets rolling as far as the kernel is concerned. * When control is transferred to _start, the bootload has already * loaded us to the correct address.  All that's left to do here is * to set up the kernel's global pointer and jump to the kernel * entry point. * * Copyright (C) 1998-2001, 2003, 2005 Hewlett-Packard Co *	David Mosberger-Tang <davidm@hpl.hp.com> *	Stephane Eranian <eranian@hpl.hp.com> * Copyright (C) 1999 VA Linux Systems * Copyright (C) 1999 Walt Drummond <drummond@valinux.com> * Copyright (C) 1999 Intel Corp. * Copyright (C) 1999 Asit Mallick <Asit.K.Mallick@intel.com> * Copyright (C) 1999 Don Dugger <Don.Dugger@intel.com> * Copyright (C) 2002 Fenghua Yu <fenghua.yu@intel.com> *   -Optimize __ia64_save_fpu() and __ia64_load_fpu() for Itanium 2. * Copyright (C) 2004 Ashok Raj <ashok.raj@intel.com> *   Support for CPU Hotplug */#include <linux/config.h>#include <asm/asmmacro.h>#include <asm/fpu.h>#include <asm/kregs.h>#include <asm/mmu_context.h>#include <asm/offsets.h>#include <asm/pal.h>#include <asm/pgtable.h>#include <asm/processor.h>#include <asm/ptrace.h>#include <asm/system.h>#include <asm/mca_asm.h>#ifdef CONFIG_HOTPLUG_CPU#define SAL_PSR_BITS_TO_SET				\	(IA64_PSR_AC | IA64_PSR_BN | IA64_PSR_MFH | IA64_PSR_MFL)#define SAVE_FROM_REG(src, ptr, dest)	\	mov dest=src;;						\	st8 [ptr]=dest,0x08#define RESTORE_REG(reg, ptr, _tmp)		\	ld8 _tmp=[ptr],0x08;;				\	mov reg=_tmp#define SAVE_BREAK_REGS(ptr, _idx, _breg, _dest)\	mov ar.lc=IA64_NUM_DBG_REGS-1;; 			\	mov _idx=0;; 								\1: 												\	SAVE_FROM_REG(_breg[_idx], ptr, _dest);;	\	add _idx=1,_idx;;							\	br.cloop.sptk.many 1b#define RESTORE_BREAK_REGS(ptr, _idx, _breg, _tmp, _lbl)\	mov ar.lc=IA64_NUM_DBG_REGS-1;;			\	mov _idx=0;;							\_lbl:  RESTORE_REG(_breg[_idx], ptr, _tmp);;	\	add _idx=1, _idx;;						\	br.cloop.sptk.many _lbl#define SAVE_ONE_RR(num, _reg, _tmp) \	movl _tmp=(num<<61);;	\	mov _reg=rr[_tmp]#define SAVE_REGION_REGS(_tmp, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) \	SAVE_ONE_RR(0,_r0, _tmp);; \	SAVE_ONE_RR(1,_r1, _tmp);; \	SAVE_ONE_RR(2,_r2, _tmp);; \	SAVE_ONE_RR(3,_r3, _tmp);; \	SAVE_ONE_RR(4,_r4, _tmp);; \	SAVE_ONE_RR(5,_r5, _tmp);; \	SAVE_ONE_RR(6,_r6, _tmp);; \	SAVE_ONE_RR(7,_r7, _tmp);;#define STORE_REGION_REGS(ptr, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7) \	st8 [ptr]=_r0, 8;; \	st8 [ptr]=_r1, 8;; \	st8 [ptr]=_r2, 8;; \	st8 [ptr]=_r3, 8;; \	st8 [ptr]=_r4, 8;; \	st8 [ptr]=_r5, 8;; \	st8 [ptr]=_r6, 8;; \	st8 [ptr]=_r7, 8;;#define RESTORE_REGION_REGS(ptr, _idx1, _idx2, _tmp) \	mov		ar.lc=0x08-1;;						\	movl	_idx1=0x00;;						\RestRR:											\	dep.z	_idx2=_idx1,61,3;;					\	ld8		_tmp=[ptr],8;;						\	mov		rr[_idx2]=_tmp;;					\	srlz.d;;									\	add		_idx1=1,_idx1;;						\	br.cloop.sptk.few	RestRR#define SET_AREA_FOR_BOOTING_CPU(reg1, reg2) \	movl reg1=sal_state_for_booting_cpu;;	\	ld8 reg2=[reg1];;/* * Adjust region registers saved before starting to save * break regs and rest of the states that need to be preserved. */#define SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(_reg1,_reg2,_pred)  \	SAVE_FROM_REG(b0,_reg1,_reg2);;						\	SAVE_FROM_REG(b1,_reg1,_reg2);;						\	SAVE_FROM_REG(b2,_reg1,_reg2);;						\	SAVE_FROM_REG(b3,_reg1,_reg2);;						\	SAVE_FROM_REG(b4,_reg1,_reg2);;						\	SAVE_FROM_REG(b5,_reg1,_reg2);;						\	st8 [_reg1]=r1,0x08;;								\	st8 [_reg1]=r12,0x08;;								\	st8 [_reg1]=r13,0x08;;								\	SAVE_FROM_REG(ar.fpsr,_reg1,_reg2);;				\	SAVE_FROM_REG(ar.pfs,_reg1,_reg2);;					\	SAVE_FROM_REG(ar.rnat,_reg1,_reg2);;				\	SAVE_FROM_REG(ar.unat,_reg1,_reg2);;				\	SAVE_FROM_REG(ar.bspstore,_reg1,_reg2);;			\	SAVE_FROM_REG(cr.dcr,_reg1,_reg2);;					\	SAVE_FROM_REG(cr.iva,_reg1,_reg2);;					\	SAVE_FROM_REG(cr.pta,_reg1,_reg2);;					\	SAVE_FROM_REG(cr.itv,_reg1,_reg2);;					\	SAVE_FROM_REG(cr.pmv,_reg1,_reg2);;					\	SAVE_FROM_REG(cr.cmcv,_reg1,_reg2);;				\	SAVE_FROM_REG(cr.lrr0,_reg1,_reg2);;				\	SAVE_FROM_REG(cr.lrr1,_reg1,_reg2);;				\	st8 [_reg1]=r4,0x08;;								\	st8 [_reg1]=r5,0x08;;								\	st8 [_reg1]=r6,0x08;;								\	st8 [_reg1]=r7,0x08;;								\	st8 [_reg1]=_pred,0x08;;							\	SAVE_FROM_REG(ar.lc, _reg1, _reg2);;				\	stf.spill.nta [_reg1]=f2,16;;						\	stf.spill.nta [_reg1]=f3,16;;						\	stf.spill.nta [_reg1]=f4,16;;						\	stf.spill.nta [_reg1]=f5,16;;						\	stf.spill.nta [_reg1]=f16,16;;						\	stf.spill.nta [_reg1]=f17,16;;						\	stf.spill.nta [_reg1]=f18,16;;						\	stf.spill.nta [_reg1]=f19,16;;						\	stf.spill.nta [_reg1]=f20,16;;						\	stf.spill.nta [_reg1]=f21,16;;						\	stf.spill.nta [_reg1]=f22,16;;						\	stf.spill.nta [_reg1]=f23,16;;						\	stf.spill.nta [_reg1]=f24,16;;						\	stf.spill.nta [_reg1]=f25,16;;						\	stf.spill.nta [_reg1]=f26,16;;						\	stf.spill.nta [_reg1]=f27,16;;						\	stf.spill.nta [_reg1]=f28,16;;						\	stf.spill.nta [_reg1]=f29,16;;						\	stf.spill.nta [_reg1]=f30,16;;						\	stf.spill.nta [_reg1]=f31,16;;#else#define SET_AREA_FOR_BOOTING_CPU(a1, a2)#define SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(a1,a2, a3)#define SAVE_REGION_REGS(_tmp, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7)#define STORE_REGION_REGS(ptr, _r0, _r1, _r2, _r3, _r4, _r5, _r6, _r7)#endif#ifdef XEN#define SET_ONE_RR(num, pgsize, _tmp1, _tmp2, vhpt) \	movl _tmp1=(num << 61);;	\	movl _tmp2=((ia64_rid(IA64_REGION_ID_KERNEL, (num<<61)) << 8) | (pgsize << 2) | vhpt);; \	mov rr[_tmp1]=_tmp2#else#define SET_ONE_RR(num, pgsize, _tmp1, _tmp2, vhpt) \	movl _tmp1=(num << 61);;	\	mov _tmp2=((ia64_rid(IA64_REGION_ID_KERNEL, (num<<61)) << 8) | (pgsize << 2) | vhpt);; \	mov rr[_tmp1]=_tmp2#endif	.section __special_page_section,"ax"	.global empty_zero_pageempty_zero_page:	.skip PAGE_SIZE#ifndef XEN	.global swapper_pg_dirswapper_pg_dir:	.skip PAGE_SIZE#endif#if defined(XEN) && defined(CONFIG_VIRTUAL_FRAME_TABLE)	.global frametable_pg_dirframetable_pg_dir:	.skip PAGE_SIZE#endif	.rodatahalt_msg:	stringz "Halting kernel\n"	.text	.global start_ap	/*	 * Start the kernel.  When the bootloader passes control to _start(), r28	 * points to the address of the boot parameter area.  Execution reaches	 * here in physical mode.	 */GLOBAL_ENTRY(_start)start_ap:	.prologue	.save rp, r0		// terminate unwind chain with a NULL rp	.body	rsm psr.i | psr.ic	;;	srlz.i	;;	/*	 * Save the region registers, predicate before they get clobbered	 */	SAVE_REGION_REGS(r2, r8,r9,r10,r11,r12,r13,r14,r15);	mov r25=pr;;	/*	 * Initialize kernel region registers:	 *	rr[0]: VHPT enabled, page size = PAGE_SHIFT	 *	rr[1]: VHPT enabled, page size = PAGE_SHIFT	 *	rr[2]: VHPT enabled, page size = PAGE_SHIFT	 *	rr[3]: VHPT enabled, page size = PAGE_SHIFT	 *	rr[4]: VHPT enabled, page size = PAGE_SHIFT	 *	rr[5]: VHPT enabled, page size = PAGE_SHIFT	 *	rr[6]: VHPT disabled, page size = IA64_GRANULE_SHIFT	 *	rr[7]: VHPT disabled, page size = IA64_GRANULE_SHIFT	 * We initialize all of them to prevent inadvertently assuming	 * something about the state of address translation early in boot.	 */	SET_ONE_RR(0, PAGE_SHIFT, r2, r16, 1);;	SET_ONE_RR(1, PAGE_SHIFT, r2, r16, 1);;	SET_ONE_RR(2, PAGE_SHIFT, r2, r16, 1);;	SET_ONE_RR(3, PAGE_SHIFT, r2, r16, 1);;	SET_ONE_RR(4, PAGE_SHIFT, r2, r16, 1);;	SET_ONE_RR(5, PAGE_SHIFT, r2, r16, 1);;	SET_ONE_RR(6, IA64_GRANULE_SHIFT, r2, r16, 0);;	SET_ONE_RR(7, IA64_GRANULE_SHIFT, r2, r16, 0);;	/*	 * Now pin mappings into the TLB for kernel text and data	 */	mov r18=KERNEL_TR_PAGE_SHIFT<<2	movl r17=KERNEL_START	;;	mov cr.itir=r18	mov cr.ifa=r17	mov r16=IA64_TR_KERNEL	mov r3=ip	movl r18=PAGE_KERNEL	;;	dep r2=0,r3,0,KERNEL_TR_PAGE_SHIFT	;;	or r18=r2,r18	;;	srlz.i	;;	itr.i itr[r16]=r18	;;	itr.d dtr[r16]=r18	;;	srlz.i	/*	 * Switch into virtual mode:	 */	movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \		  |IA64_PSR_DI)	;;	mov cr.ipsr=r16	movl r17=1f	;;	mov cr.iip=r17	mov cr.ifs=r0	;;	rfi	;;1:	// now we are in virtual mode	SET_AREA_FOR_BOOTING_CPU(r2, r16);	STORE_REGION_REGS(r16, r8,r9,r10,r11,r12,r13,r14,r15);	SAL_TO_OS_BOOT_HANDOFF_STATE_SAVE(r16,r17,r25)	;;	// set IVT entry point---can't access I/O ports without it	movl r3=ia64_ivt	;;	mov cr.iva=r3	movl r2=FPSR_DEFAULT	;;	srlz.i	movl gp=__gp	;;	mov ar.fpsr=r2	;;#define isAP	p2	// are we an Application Processor?#define isBP	p3	// are we the Bootstrap Processor?#ifdef XEN# define init_task	init_task_mem#endif#ifdef CONFIG_SMP	/*	 * Find the init_task for the currently booting CPU.  At poweron, and in	 * UP mode, task_for_booting_cpu is NULL.	 */	movl r3=task_for_booting_cpu 	;;	ld8 r3=[r3]	movl r2=init_task	;;	cmp.eq isBP,isAP=r3,r0	;;(isAP)	mov r2=r3#else	movl r2=init_task	cmp.eq isBP,isAP=r0,r0#endif	;;	tpa r3=r2		// r3 == phys addr of task struct	mov r16=-1#ifndef XEN(isBP)	br.cond.dpnt .load_current // BP stack is on region 5 --- no need to map it#endif	// load mapping for stack (virtaddr in r2, physaddr in r3)	rsm psr.ic	movl r17=PAGE_KERNEL	;;	srlz.d	dep r18=0,r3,0,12	;;	or r18=r17,r18#ifdef XEN	dep r2=-1,r3,60,4       // IMVA of task #else	dep r2=-1,r3,61,3	// IMVA of task#endif	;;	mov r17=rr[r2]	shr.u r16=r3,IA64_GRANULE_SHIFT	;;	dep r17=0,r17,8,24	;;	mov cr.itir=r17	mov cr.ifa=r2	mov r19=IA64_TR_CURRENT_STACK	;;	itr.d dtr[r19]=r18	;;	ssm psr.ic	srlz.d  	;;	.load_current:	// load the "current" pointer (r13) and ar.k6 with the current task	mov IA64_KR(CURRENT)=r2		// virtual address	mov IA64_KR(CURRENT_STACK)=r16	mov r13=r2	/*	 * Reserve space at the top of the stack for "struct pt_regs".  Kernel	 * threads don't store interesting values in that structure, but the space	 * still needs to be there because time-critical stuff such as the context	 * switching can be implemented more efficiently (for example, __switch_to()	 * always sets the psr.dfh bit of the task it is switching to).	 */	addl r12=IA64_STK_OFFSET-IA64_PT_REGS_SIZE-16,r2	addl r2=IA64_RBS_OFFSET,r2	// initialize the RSE	mov ar.rsc=0		// place RSE in enforced lazy mode	;;	loadrs			// clear the dirty partition	;;	mov ar.bspstore=r2	// establish the new RSE stack	;;	mov ar.rsc=0x3		// place RSE in eager mode#ifdef XEN(isBP)	dep r28=-1,r28,60,4	// make address virtual#else(isBP)	dep r28=-1,r28,61,3	// make address virtual#endif(isBP)	movl r2=ia64_boot_param	;;(isBP)	st8 [r2]=r28		// save the address of the boot param area passed by the bootloader#ifdef CONFIG_SMP(isAP)	br.call.sptk.many rp=start_secondary.ret0:(isAP)	br.cond.sptk self#endif	// This is executed by the bootstrap processor (bsp) only:#ifdef CONFIG_IA64_FW_EMU	// initialize PAL & SAL emulator:	br.call.sptk.many rp=sys_fw_init.ret1:#endif	br.call.sptk.many rp=start_kernel.ret2:	addl r3=@ltoff(halt_msg),gp	;;	alloc r2=ar.pfs,8,0,2,0	;;	ld8 out0=[r3]	br.call.sptk.many b0=console_printself:	hint @pause#ifdef XEN	;;	br.sptk.many self		// endless loop	;;#else	br.sptk.many self		// endless loop#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -