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

📄 entry.s

📁 讲述linux的初始化过程
💻 S
📖 第 1 页 / 共 3 页
字号:
	.globl	do_reg_accessdo_reg_access:	SAVE_ALL	wr	%l0, PSR_ET, %psr		! re-enable traps	WRITE_PAUSE	add	%sp, REGWIN_SZ, %o0	mov	%l1, %o1	mov	%l2, %o2	call	C_LABEL(handle_reg_access)	 mov	%l0, %o3	RESTORE_ALL	/* This routine handles Co-Processor Disabled Exceptions. */	.align	4	.globl	do_cp_disableddo_cp_disabled:	SAVE_ALL	wr	%l0, PSR_ET, %psr		! re-enable traps	WRITE_PAUSE	add	%sp, REGWIN_SZ, %o0	mov	%l1, %o1	mov	%l2, %o2	call	C_LABEL(handle_cp_disabled)	 mov	%l0, %o3	RESTORE_ALL	/* This routine handles Co-Processor Exceptions. */	.align	4	.globl	do_cp_exceptiondo_cp_exception:	SAVE_ALL	wr	%l0, PSR_ET, %psr		! re-enable traps	WRITE_PAUSE	add	%sp, REGWIN_SZ, %o0	mov	%l1, %o1	mov	%l2, %o2	call	C_LABEL(handle_cp_exception)	 mov	%l0, %o3	RESTORE_ALL	/* This routine handles Hardware Divide By Zero Exceptions. */	.align	4	.globl	do_hw_divzerodo_hw_divzero:	SAVE_ALL	wr	%l0, PSR_ET, %psr		! re-enable traps	WRITE_PAUSE	add	%sp, REGWIN_SZ, %o0	mov	%l1, %o1	mov	%l2, %o2	call	C_LABEL(handle_hw_divzero)	 mov	%l0, %o3	RESTORE_ALL	.align	4	.globl	do_flush_windowsdo_flush_windows:	SAVE_ALL	wr	%l0, PSR_ET, %psr	WRITE_PAUSE	andcc	%l0, PSR_PS, %g0	bne	dfw_kernel	 nop	call	C_LABEL(flush_user_windows)	 nop	/* Advance over the trap instruction. */	ld	[%sp + REGWIN_SZ + PT_NPC], %l1	add	%l1, 0x4, %l2	st	%l1, [%sp + REGWIN_SZ + PT_PC]	st	%l2, [%sp + REGWIN_SZ + PT_NPC]	RESTORE_ALL	.globl	flush_patch_one	/* We get these for debugging routines using __builtin_return_address() */dfw_kernel:flush_patch_one:	FLUSH_ALL_KERNEL_WINDOWS	/* Advance over the trap instruction. */	ld	[%sp + REGWIN_SZ + PT_NPC], %l1	add	%l1, 0x4, %l2	st	%l1, [%sp + REGWIN_SZ + PT_PC]	st	%l2, [%sp + REGWIN_SZ + PT_NPC]	RESTORE_ALL	/* The getcc software trap.  The user wants the condition codes from	 * the %psr in register %g1.	 */	.align	4	.globl	getcc_trap_handlergetcc_trap_handler:	srl	%l0, 20, %g1	! give user	and	%g1, 0xf, %g1	! only ICC bits in %psr	jmp	%l2		! advance over trap instruction	rett	%l2 + 0x4	! like this...	/* The setcc software trap.  The user has condition codes in %g1	 * that it would like placed in the %psr.  Be careful not to flip	 * any unintentional bits!	 */	.align	4	.globl	setcc_trap_handlersetcc_trap_handler:	sll	%g1, 0x14, %l4	set	PSR_ICC, %l5	andn	%l0, %l5, %l0	! clear ICC bits in %psr	and	%l4, %l5, %l4	! clear non-ICC bits in user value	or	%l4, %l0, %l4	! or them in... mix mix mix	wr	%l4, 0x0, %psr	! set new %psr	WRITE_PAUSE		! TI scumbags...	jmp	%l2		! advance over trap instruction	rett	%l2 + 0x4	! like this...	.align	4	.globl	linux_trap_nmi_sun4clinux_trap_nmi_sun4c:	SAVE_ALL	/* Ugh, we need to clear the IRQ line.  This is now	 * a very sun4c specific trap handler...	 */	sethi	%hi(C_LABEL(interrupt_enable)), %l5	ld	[%l5 + %lo(C_LABEL(interrupt_enable))], %l5	ldub	[%l5], %l6	andn	%l6, INTS_ENAB, %l6	stb	%l6, [%l5]	/* Now it is safe to re-enable traps without recursion. */	or	%l0, PSR_PIL, %l0	wr	%l0, PSR_ET, %psr	WRITE_PAUSE	/* Now call the c-code with the pt_regs frame ptr and the	 * memory error registers as arguments.  The ordering chosen	 * here is due to unlatching semantics.	 */	sethi	%hi(AC_SYNC_ERR), %o0	add	%o0, 0x4, %o0	lda	[%o0] ASI_CONTROL, %o2	! sync vaddr	sub	%o0, 0x4, %o0	lda	[%o0] ASI_CONTROL, %o1	! sync error	add	%o0, 0xc, %o0	lda	[%o0] ASI_CONTROL, %o4	! async vaddr	sub	%o0, 0x4, %o0	lda	[%o0] ASI_CONTROL, %o3	! async error	call	C_LABEL(sparc_lvl15_nmi)	 add	%sp, REGWIN_SZ, %o0	RESTORE_ALL	.align	4	.globl	C_LABEL(invalid_segment_patch1_ff)	.globl	C_LABEL(invalid_segment_patch2_ff)C_LABEL(invalid_segment_patch1_ff):	cmp	%l4, 0xffC_LABEL(invalid_segment_patch2_ff):	mov	0xff, %l3	.align	4	.globl	C_LABEL(invalid_segment_patch1_1ff)	.globl	C_LABEL(invalid_segment_patch2_1ff)C_LABEL(invalid_segment_patch1_1ff):	cmp	%l4, 0x1ffC_LABEL(invalid_segment_patch2_1ff):	mov	0x1ff, %l3	.align	4	.globl	C_LABEL(num_context_patch1_16), C_LABEL(num_context_patch2_16)C_LABEL(num_context_patch1_16):		mov	0x10, %l7C_LABEL(num_context_patch2_16):		mov	0x10, %l7	.align	4	.globl	C_LABEL(vac_linesize_patch_32)C_LABEL(vac_linesize_patch_32):		subcc	%l7, 32, %l7	.align	4	.globl	C_LABEL(vac_hwflush_patch1_on), C_LABEL(vac_hwflush_patch2_on)/* * Ugly, but we cant use hardware flushing on the sun4 and we'd require * two instructions (Anton) */#ifdef CONFIG_SUN4C_LABEL(vac_hwflush_patch1_on):		nop#elseC_LABEL(vac_hwflush_patch1_on):		addcc	%l7, -PAGE_SIZE, %l7#endifC_LABEL(vac_hwflush_patch2_on):		sta	%g0, [%l3 + %l7] ASI_HWFLUSHSEG	.globl	C_LABEL(invalid_segment_patch1), C_LABEL(invalid_segment_patch2)	.globl	C_LABEL(num_context_patch1), C_LABEL(num_context_patch2)	.globl	C_LABEL(vac_linesize_patch), C_LABEL(vac_hwflush_patch1)	.globl	C_LABEL(vac_hwflush_patch2)	.align	4	.globl	sun4c_fault! %l0 = %psr! %l1 = %pc! %l2 = %npc! %l3 = %wim! %l7 = 1 for textfault! We want error in %l5, vaddr in %l6sun4c_fault:#ifdef CONFIG_SUN4	sethi	%hi(C_LABEL(sun4c_memerr_reg)), %l4	ld	[%l4+%lo(C_LABEL(sun4c_memerr_reg))], %l4  ! memerr ctrl reg addr	ld	[%l4], %l6		! memerr ctrl reg	ld	[%l4 + 4], %l5		! memerr vaddr reg	andcc	%l6, 0x80, %g0		! check for error type	st	%g0, [%l4 + 4]		! clear the error	be	0f			! normal error	 sethi	%hi(AC_BUS_ERROR), %l4	! bus err reg addr	call	C_LABEL(prom_halt)	! something weird happened					! what exactly did happen?					! what should we do here?0:	or	%l4, %lo(AC_BUS_ERROR), %l4	! bus err reg addr	lduba	[%l4] ASI_CONTROL, %l6	! bus err reg	cmp    %l7, 1			! text fault?	be	1f			! yes	 nop	ld     [%l1], %l4		! load instruction that caused fault	srl	%l4, 21, %l4	andcc	%l4, 1, %g0		! store instruction?	be	1f			! no	 sethi	%hi(SUN4C_SYNC_BADWRITE), %l4 ! yep					! %lo(SUN4C_SYNC_BADWRITE) = 0	or	%l4, %l6, %l6		! set write bit to emulate sun4c1:#else	sethi	%hi(AC_SYNC_ERR), %l4	add	%l4, 0x4, %l6			! AC_SYNC_VA in %l6	lda	[%l6] ASI_CONTROL, %l5		! Address	lda	[%l4] ASI_CONTROL, %l6		! Error, retained for a bit#endif	andn	%l5, 0xfff, %l5			! Encode all info into l7	srl	%l6, 14, %l4	and	%l4, 2, %l4	or	%l5, %l4, %l4	or	%l4, %l7, %l7			! l7 = [addr,write,txtfault]	andcc	%l0, PSR_PS, %g0	be	sun4c_fault_fromuser	 andcc	%l7, 1, %g0			! Text fault?	be	1f	 sethi	%hi(KERNBASE), %l4	mov	%l1, %l5			! PC1:	cmp	%l5, %l4	blu	sun4c_fault_fromuser	 sethi	%hi(~((1 << SUN4C_REAL_PGDIR_SHIFT) - 1)), %l4	/* If the kernel references a bum kernel pointer, or a pte which	 * points to a non existant page in ram, we will run this code	 * _forever_ and lock up the machine!!!!! So we must check for	 * this condition, the AC_SYNC_ERR bits are what we must examine.	 * Also a parity error would make this happen as well.  So we just	 * check that we are in fact servicing a tlb miss and not some	 * other type of fault for the kernel.	 */	andcc	%l6, 0x80, %g0	be	sun4c_fault_fromuser	 and	%l5, %l4, %l5	/* Test for NULL pte_t * in vmalloc area. */	sethi   %hi(VMALLOC_START), %l4	cmp     %l5, %l4	blu,a   C_LABEL(invalid_segment_patch1)	 lduXa	[%l5] ASI_SEGMAP, %l4	sethi   %hi(C_LABEL(swapper_pg_dir)), %l4	srl     %l5, SUN4C_PGDIR_SHIFT, %l6	or      %l4, %lo(C_LABEL(swapper_pg_dir)), %l4	sll     %l6, 2, %l6	ld      [%l4 + %l6], %l4#ifdef CONFIG_SUN4	sethi	%hi(PAGE_MASK), %l6	andcc	%l4, %l6, %g0#else	andcc   %l4, PAGE_MASK, %g0#endif	be      sun4c_fault_fromuser	 lduXa  [%l5] ASI_SEGMAP, %l4C_LABEL(invalid_segment_patch1):	cmp	%l4, 0x7f	bne	1f	 sethi	%hi(C_LABEL(sun4c_kfree_ring)), %l4	or	%l4, %lo(C_LABEL(sun4c_kfree_ring)), %l4	ld	[%l4 + 0x18], %l3	deccc	%l3			! do we have a free entry?	bcs,a	2f			! no, unmap one.	 sethi	%hi(C_LABEL(sun4c_kernel_ring)), %l4	st	%l3, [%l4 + 0x18]	! sun4c_kfree_ring.num_entries--	ld	[%l4 + 0x00], %l6	! entry = sun4c_kfree_ring.ringhd.next	st	%l5, [%l6 + 0x08]	! entry->vaddr = address	ld	[%l6 + 0x00], %l3	! next = entry->next	ld	[%l6 + 0x04], %l7	! entry->prev	st	%l7, [%l3 + 0x04]	! next->prev = entry->prev	st	%l3, [%l7 + 0x00]	! entry->prev->next = next	sethi	%hi(C_LABEL(sun4c_kernel_ring)), %l4	or	%l4, %lo(C_LABEL(sun4c_kernel_ring)), %l4					! head = &sun4c_kernel_ring.ringhd	ld	[%l4 + 0x00], %l7	! head->next	st	%l4, [%l6 + 0x04]	! entry->prev = head	st	%l7, [%l6 + 0x00]	! entry->next = head->next	st	%l6, [%l7 + 0x04]	! head->next->prev = entry	st	%l6, [%l4 + 0x00]	! head->next = entry	ld	[%l4 + 0x18], %l3	inc	%l3			! sun4c_kernel_ring.num_entries++	b	4f	 ld	[%l6 + 0x08], %l52:	or	%l4, %lo(C_LABEL(sun4c_kernel_ring)), %l4					! head = &sun4c_kernel_ring.ringhd	ld	[%l4 + 0x04], %l6	! entry = head->prev	ld	[%l6 + 0x08], %l3	! tmp = entry->vaddr	! Flush segment from the cache.#ifdef CONFIG_SUN4	sethi	%hi((128 * 1024)), %l7#else	sethi	%hi((64 * 1024)), %l7#endif9:C_LABEL(vac_hwflush_patch1):C_LABEL(vac_linesize_patch):	subcc	%l7, 16, %l7	bne	9bC_LABEL(vac_hwflush_patch2):	 sta	%g0, [%l3 + %l7] ASI_FLUSHSEG	st	%l5, [%l6 + 0x08]	! entry->vaddr = address	ld	[%l6 + 0x00], %l5	! next = entry->next	ld	[%l6 + 0x04], %l7	! entry->prev	st	%l7, [%l5 + 0x04]	! next->prev = entry->prev	st	%l5, [%l7 + 0x00]	! entry->prev->next = next	st	%l4, [%l6 + 0x04]	! entry->prev = head	ld	[%l4 + 0x00], %l7	! head->next	st	%l7, [%l6 + 0x00]	! entry->next = head->next	st	%l6, [%l7 + 0x04]	! head->next->prev = entry	st	%l6, [%l4 + 0x00]	! head->next = entry	mov	%l3, %l5		! address = tmp4:C_LABEL(num_context_patch1):	mov	0x08, %l7	ld	[%l6 + 0x08], %l4	ldub	[%l6 + 0x0c], %l3	or	%l4, %l3, %l4		! encode new vaddr/pseg into l4	sethi	%hi(AC_CONTEXT), %l3	lduba	[%l3] ASI_CONTROL, %l6	/* Invalidate old mapping, instantiate new mapping,	 * for each context.  Registers l6/l7 are live across	 * this loop.	 */3:	deccc	%l7	sethi	%hi(AC_CONTEXT), %l3	stba	%l7, [%l3] ASI_CONTROLC_LABEL(invalid_segment_patch2):	mov	0x7f, %l3	stXa	%l3, [%l5] ASI_SEGMAP	andn	%l4, 0x1ff, %l3	bne	3b	 stXa	%l4, [%l3] ASI_SEGMAP	sethi	%hi(AC_CONTEXT), %l3	stba	%l6, [%l3] ASI_CONTROL	andn	%l4, 0x1ff, %l51:	sethi	%hi(VMALLOC_START), %l4	cmp	%l5, %l4	bgeu	1f	 mov	1 << (SUN4C_REAL_PGDIR_SHIFT - PAGE_SHIFT), %l7	sethi	%hi(KERNBASE), %l6	sub	%l5, %l6, %l4	srl	%l4, PAGE_SHIFT, %l4	sethi	%hi((SUN4C_PAGE_KERNEL & 0xf4000000)), %l3	or	%l3, %l4, %l3	sethi	%hi(PAGE_SIZE), %l42:	sta	%l3, [%l5] ASI_PTE	deccc	%l7	inc	%l3	bne	2b	 add	%l5, %l4, %l5	b	7f	 sethi	%hi(C_LABEL(sun4c_kernel_faults)), %l41:	srl	%l5, SUN4C_PGDIR_SHIFT, %l3	sethi	%hi(C_LABEL(swapper_pg_dir)), %l4	or	%l4, %lo(C_LABEL(swapper_pg_dir)), %l4	sll	%l3, 2, %l3	ld	[%l4 + %l3], %l4#ifndef CONFIG_SUN4	and	%l4, PAGE_MASK, %l4#else	sethi	%hi(PAGE_MASK), %l6	and	%l4, %l6, %l4#endif	srl	%l5, (PAGE_SHIFT - 2), %l6	and	%l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6	add	%l6, %l4, %l6	sethi	%hi(PAGE_SIZE), %l42:	ld	[%l6], %l3	deccc	%l7	sta	%l3, [%l5] ASI_PTE	add	%l6, 0x4, %l6	bne	2b	 add	%l5, %l4, %l5	sethi	%hi(C_LABEL(sun4c_kernel_faults)), %l47:	ld	[%l4 + %lo(C_LABEL(sun4c_kernel_faults))], %l3	inc	%l3	st	%l3, [%l4 + %lo(C_LABEL(sun4c_kernel_faults))]	/* Restore condition codes */	wr	%l0, 0x0, %psr	WRITE_PAUSE	jmp	%l1	 rett	%l2sun4c_fault_fromuser:	SAVE_ALL	 nop		mov	%l7, %o1		! Decode the info from %l7	mov	%l7, %o2	and	%o1, 1, %o1		! arg2 = text_faultp	mov	%l7, %o3	and	%o2, 2, %o2		! arg3 = writep	andn	%o3, 0xfff, %o3		! arg4 = faulting address	wr	%l0, PSR_ET, %psr	WRITE_PAUSE	call	C_LABEL(do_sun4c_fault)	 add	%sp, REGWIN_SZ, %o0	! arg1 = pt_regs ptr	RESTORE_ALL	.align	4	.globl	C_LABEL(srmmu_fault)C_LABEL(srmmu_fault):	mov	0x400, %l5	mov	0x300, %l4	lda	[%l5] ASI_M_MMUREGS, %l6	! read sfar first	lda	[%l4] ASI_M_MMUREGS, %l5	! read sfsr last	andn	%l6, 0xfff, %l6	srl	%l5, 6, %l5			! and encode all info into l7	and	%l5, 2, %l5	or	%l5, %l6, %l6	or	%l6, %l7, %l7			! l7 = [addr,write,txtfault]	SAVE_ALL	mov	%l7, %o1	mov	%l7, %o2	and	%o1, 1, %o1		! arg2 = text_faultp	mov	%l7, %o3	and	%o2, 2, %o2		! arg3 = writep	andn	%o3, 0xfff, %o3		! arg4 = faulting address	wr	%l0, PSR_ET, %psr	WRITE_PAUSE	call	C_LABEL(do_sparc_fault)	 add	%sp, REGWIN_SZ, %o0	! arg1 = pt_regs ptr	RESTORE_ALL#ifdef CONFIG_SUNOS_EMUL	/* SunOS uses syscall zero as the 'indirect syscall' it looks	 * like indir_syscall(scall_num, arg0, arg1, arg2...);  etc.	 * This is complete brain damage.	 */	.globl	C_LABEL(sunos_indir)C_LABEL(sunos_indir):	mov	%o7, %l4	cmp	%o0, NR_SYSCALLS	blu,a	1f	 sll	%o0, 0x2, %o0	sethi	%hi(C_LABEL(sunos_nosys)), %l6	b	2f	 or	%l6, %lo(C_LABEL(sunos_nosys)), %l61:	set	C_LABEL(sunos_sys_table), %l7	ld	[%l7 + %o0], %l62:		mov	%o1, %o0	mov	%o2, %o1	mov	%o3, %o2	mov	%o4, %o3	mov	%o5, %o4	call	%l6	 mov	%l4, %o7#endif	.align	4	.globl	C_LABEL(sys_nis_syscall)C_LABEL(sys_nis_syscall):	mov	%o7, %l5	add	%sp, REGWIN_SZ, %o0		! pt_regs *regs arg	call	C_LABEL(c_sys_nis_syscall)	 mov	%l5, %o7	.align 4	.globl	C_LABEL(sys_ptrace)C_LABEL(sys_ptrace):	call	C_LABEL(do_ptrace)	 add	%sp, REGWIN_SZ, %o0	ld	[%curptr + AOFF_task_ptrace], %l5	andcc	%l5, 0x02, %g0	be	1f	 nop	call	C_LABEL(syscall_trace)	 nop1:	RESTORE_ALL	.align	4	.globl	C_LABEL(sys_execve)C_LABEL(sys_execve):	mov	%o7, %l5	add	%sp, REGWIN_SZ, %o0		! pt_regs *regs arg	call	C_LABEL(sparc_execve)	 mov	%l5, %o7	.align	4	.globl	C_LABEL(sys_pipe)C_LABEL(sys_pipe):	mov	%o7, %l5	add	%sp, REGWIN_SZ, %o0		! pt_regs *regs arg	call	C_LABEL(sparc_pipe)	 mov	%l5, %o7	.align	4	.globl	C_LABEL(sys_sigaltstack)C_LABEL(sys_sigaltstack):	mov	%o7, %l5	mov	%fp, %o2	call	C_LABEL(do_sigaltstack)	 mov	%l5, %o7	.align	4	.globl	C_LABEL(sys_sigstack)C_LABEL(sys_sigstack):	mov	%o7, %l5	mov	%fp, %o2	call	C_LABEL(do_sys_sigstack)	 mov	%l5, %o7	.align	4	.globl	C_LABEL(sys_sigpause)C_LABEL(sys_sigpause):	/* Note: %o0 already has correct value... */	call	C_LABEL(do_sigpause)	 add	%sp, REGWIN_SZ, %o1	ld	[%curptr + AOFF_task_ptrace], %l5	andcc	%l5, 0x02, %g0	be	1f	 nop	call	C_LABEL(syscall_trace)	 nop1:	/* We are returning to a signal handler. */	RESTORE_ALL	.align	4	.globl	C_LABEL(sys_sigsuspend)C_LABEL(sys_sigsuspend):	call	C_LABEL(do_sigsuspend)	 add	%sp, REGWIN_SZ, %o0

⌨️ 快捷键说明

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