diff options
Diffstat (limited to 'arch/sparc/kernel/entry.S')
| -rw-r--r-- | arch/sparc/kernel/entry.S | 552 | 
1 files changed, 134 insertions, 418 deletions
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 1504df8ddf7..33c02b15f47 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S @@ -7,6 +7,7 @@   * Copyright (C) 1997 Anton Blanchard (anton@progsoc.uts.edu.au)   */ +#include <linux/linkage.h>  #include <linux/errno.h>  #include <asm/head.h> @@ -17,10 +18,8 @@  #include <asm/asm-offsets.h>  #include <asm/psr.h>  #include <asm/vaddrs.h> -#include <asm/memreg.h>  #include <asm/page.h>  #include <asm/pgtable.h> -#include <asm/pgtsun4c.h>  #include <asm/winmacro.h>  #include <asm/signal.h>  #include <asm/obio.h> @@ -125,22 +124,11 @@ floppy_tdone:  	set	auxio_register, %l7  	ld	[%l7], %l7 -	set	sparc_cpu_model, %l5 -	ld	[%l5], %l5 -	subcc   %l5, 1, %g0		/* enum { sun4c = 1 }; */ -	be	1f -	 ldub	[%l7], %l5 +	ldub	[%l7], %l5  	or	%l5, 0xc2, %l5  	stb	%l5, [%l7]  	andn    %l5, 0x02, %l5 -	b	2f -	 nop - -1: -	or      %l5, 0xf4, %l5 -	stb     %l5, [%l7] -	andn    %l5, 0x04, %l5  2:  	/* Kill some time so the bits set */ @@ -229,7 +217,7 @@ real_irq_entry:  #ifdef CONFIG_SMP  	.globl	patchme_maybe_smp_msg -	cmp	%l7, 12 +	cmp	%l7, 11  patchme_maybe_smp_msg:  	bgu	maybe_smp4m_msg  	 nop @@ -266,22 +254,30 @@ smp4m_ticker:  	WRITE_PAUSE  	RESTORE_ALL +#define GET_PROCESSOR4M_ID(reg)	\ +	rd	%tbr, %reg;	\ +	srl	%reg, 12, %reg;	\ +	and	%reg, 3, %reg; +  	/* Here is where we check for possible SMP IPI passed to us  	 * on some level other than 15 which is the NMI and only used  	 * for cross calls.  That has a separate entry point below. +	 * +	 * IPIs are sent on Level 12, 13 and 14. See IRQ_IPI_*.  	 */  maybe_smp4m_msg:  	GET_PROCESSOR4M_ID(o3)  	sethi	%hi(sun4m_irq_percpu), %l5  	sll	%o3, 2, %o3  	or	%l5, %lo(sun4m_irq_percpu), %o5 -	sethi	%hi(0x40000000), %o2 +	sethi	%hi(0x70000000), %o2	! Check all soft-IRQs  	ld	[%o5 + %o3], %o1  	ld	[%o1 + 0x00], %o3	! sun4m_irq_percpu[cpu]->pending  	andcc	%o3, %o2, %g0  	be,a	smp4m_ticker  	 cmp	%l7, 14 -	st	%o2, [%o1 + 0x04]	! sun4m_irq_percpu[cpu]->clear=0x40000000 +	/* Soft-IRQ IPI */ +	st	%o2, [%o1 + 0x04]	! sun4m_irq_percpu[cpu]->clear=0x70000000  	WRITE_PAUSE  	ld	[%o1 + 0x00], %g0	! sun4m_irq_percpu[cpu]->pending  	WRITE_PAUSE @@ -290,9 +286,27 @@ maybe_smp4m_msg:  	WRITE_PAUSE  	wr	%l4, PSR_ET, %psr  	WRITE_PAUSE -	call	smp_reschedule_irq +	srl	%o3, 28, %o2		! shift for simpler checks below +maybe_smp4m_msg_check_single: +	andcc	%o2, 0x1, %g0 +	beq,a	maybe_smp4m_msg_check_mask +	 andcc	%o2, 0x2, %g0 +	call	smp_call_function_single_interrupt  	 nop - +	andcc	%o2, 0x2, %g0 +maybe_smp4m_msg_check_mask: +	beq,a	maybe_smp4m_msg_check_resched +	 andcc	%o2, 0x4, %g0 +	call	smp_call_function_interrupt +	 nop +	andcc	%o2, 0x4, %g0 +maybe_smp4m_msg_check_resched: +	/* rescheduling is done in RESTORE_ALL regardless, but incr stats */ +	beq,a	maybe_smp4m_msg_out +	 nop +	call	smp_resched_interrupt +	 nop +maybe_smp4m_msg_out:  	RESTORE_ALL  	.align	4 @@ -307,7 +321,7 @@ linux_trap_ipi15_sun4m:  	ld	[%o5 + %o0], %o5  	ld	[%o5 + 0x00], %o3	! sun4m_irq_percpu[cpu]->pending  	andcc	%o3, %o2, %g0 -	be	1f			! Must be an NMI async memory error +	be	sun4m_nmi_error		! Must be an NMI async memory error  	 st	%o2, [%o5 + 0x04]	! sun4m_irq_percpu[cpu]->clear=0x80000000  	WRITE_PAUSE  	ld	[%o5 + 0x00], %g0	! sun4m_irq_percpu[cpu]->pending @@ -321,27 +335,6 @@ linux_trap_ipi15_sun4m:  	 nop  	b	ret_trap_lockless_ipi  	 clr	%l6 -1: -	/* NMI async memory error handling. */ -	sethi	%hi(0x80000000), %l4 -	sethi	%hi(sun4m_irq_global), %o5 -	ld	[%o5 + %lo(sun4m_irq_global)], %l5 -	st	%l4, [%l5 + 0x0c]	! sun4m_irq_global->mask_set=0x80000000 -	WRITE_PAUSE -	ld	[%l5 + 0x00], %g0	! sun4m_irq_global->pending -	WRITE_PAUSE -	or	%l0, PSR_PIL, %l4 -	wr	%l4, 0x0, %psr -	WRITE_PAUSE -	wr	%l4, PSR_ET, %psr -	WRITE_PAUSE -	call	sun4m_nmi -	 nop -	st	%l4, [%l5 + 0x08]	! sun4m_irq_global->mask_clear=0x80000000 -	WRITE_PAUSE -	ld	[%l5 + 0x00], %g0	! sun4m_irq_global->pending -	WRITE_PAUSE -	RESTORE_ALL  	.globl	smp4d_ticker  	/* SMP per-cpu ticker interrupts are handled specially. */ @@ -400,19 +393,18 @@ linux_trap_ipi15_sun4d:  	/* FIXME */  1:	b,a	1b -#ifdef CONFIG_SPARC_LEON - -	.globl	smpleon_ticker -	/* SMP per-cpu ticker interrupts are handled specially. */ -smpleon_ticker: +	.globl	smpleon_ipi +	.extern leon_ipi_interrupt +	/* SMP per-cpu IPI interrupts are handled specially. */ +smpleon_ipi:          SAVE_ALL  	or	%l0, PSR_PIL, %g2  	wr	%g2, 0x0, %psr  	WRITE_PAUSE  	wr	%g2, PSR_ET, %psr  	WRITE_PAUSE -	call	leon_percpu_timer_interrupt -	 add	%sp, STACKFRAME_SZ, %o0 +	call	leonsmp_ipi_interrupt +	 add	%sp, STACKFRAME_SZ, %o1 ! pt_regs  	wr	%l0, PSR_ET, %psr  	WRITE_PAUSE  	RESTORE_ALL @@ -431,8 +423,6 @@ linux_trap_ipi15_leon:  	b	ret_trap_lockless_ipi  	 clr	%l6 -#endif /* CONFIG_SPARC_LEON */ -  #endif /* CONFIG_SMP */  	/* This routine handles illegal instructions and privileged @@ -739,326 +729,37 @@ setcc_trap_handler:  	jmp	%l2		! advance over trap instruction  	rett	%l2 + 0x4	! like this... -	.align	4 -	.globl	linux_trap_nmi_sun4c -linux_trap_nmi_sun4c: -	SAVE_ALL - -	/* Ugh, we need to clear the IRQ line.  This is now -	 * a very sun4c specific trap handler... -	 */ -	sethi	%hi(interrupt_enable), %l5 -	ld	[%l5 + %lo(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 +sun4m_nmi_error: +	/* NMI async memory error handling. */ +	sethi	%hi(0x80000000), %l4 +	sethi	%hi(sun4m_irq_global), %o5 +	ld	[%o5 + %lo(sun4m_irq_global)], %l5 +	st	%l4, [%l5 + 0x0c]	! sun4m_irq_global->mask_set=0x80000000  	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	sparc_lvl15_nmi -	 add	%sp, STACKFRAME_SZ, %o0 - -	RESTORE_ALL - -	.align	4 -	.globl	invalid_segment_patch1_ff -	.globl	invalid_segment_patch2_ff -invalid_segment_patch1_ff:	cmp	%l4, 0xff -invalid_segment_patch2_ff:	mov	0xff, %l3 - -	.align	4 -	.globl	invalid_segment_patch1_1ff -	.globl	invalid_segment_patch2_1ff -invalid_segment_patch1_1ff:	cmp	%l4, 0x1ff -invalid_segment_patch2_1ff:	mov	0x1ff, %l3 - -	.align	4 -	.globl	num_context_patch1_16, num_context_patch2_16 -num_context_patch1_16:		mov	0x10, %l7 -num_context_patch2_16:		mov	0x10, %l7 - -	.align	4 -	.globl	vac_linesize_patch_32 -vac_linesize_patch_32:		subcc	%l7, 32, %l7 - -	.align	4 -	.globl	vac_hwflush_patch1_on, vac_hwflush_patch2_on - -/* - * Ugly, but we cant use hardware flushing on the sun4 and we'd require - * two instructions (Anton) - */ -vac_hwflush_patch1_on:		addcc	%l7, -PAGE_SIZE, %l7 - -vac_hwflush_patch2_on:		sta	%g0, [%l3 + %l7] ASI_HWFLUSHSEG - -	.globl	invalid_segment_patch1, invalid_segment_patch2 -	.globl	num_context_patch1 -	.globl	vac_linesize_patch, vac_hwflush_patch1 -	.globl	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 %l6 -sun4c_fault: -	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 - -	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			! PC - -1: -	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   invalid_segment_patch1 -	 lduXa	[%l5] ASI_SEGMAP, %l4 - -	sethi   %hi(swapper_pg_dir), %l4 -	srl     %l5, SUN4C_PGDIR_SHIFT, %l6 -	or      %l4, %lo(swapper_pg_dir), %l4 -	sll     %l6, 2, %l6 -	ld      [%l4 + %l6], %l4 -	andcc   %l4, PAGE_MASK, %g0 -	be      sun4c_fault_fromuser -	 lduXa  [%l5] ASI_SEGMAP, %l4 - -invalid_segment_patch1: -	cmp	%l4, 0x7f -	bne	1f -	 sethi	%hi(sun4c_kfree_ring), %l4 -	or	%l4, %lo(sun4c_kfree_ring), %l4 -	ld	[%l4 + 0x18], %l3 -	deccc	%l3			! do we have a free entry? -	bcs,a	2f			! no, unmap one. -	 sethi	%hi(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(sun4c_kernel_ring), %l4 -	or	%l4, %lo(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++ -	st	%l3, [%l4 + 0x18] -	b	4f -	 ld	[%l6 + 0x08], %l5 - -2: -	or	%l4, %lo(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. -	sethi	%hi((64 * 1024)), %l7 -9: -vac_hwflush_patch1: -vac_linesize_patch: -	subcc	%l7, 16, %l7 -	bne	9b -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 = tmp - -4: -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_CONTROL -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, %l5 - -1: -	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), %l4 - -2: -	sta	%l3, [%l5] ASI_PTE -	deccc	%l7 -	inc	%l3 -	bne	2b -	 add	%l5, %l4, %l5 - -	b	7f -	 sethi	%hi(sun4c_kernel_faults), %l4 - -1: -	srl	%l5, SUN4C_PGDIR_SHIFT, %l3 -	sethi	%hi(swapper_pg_dir), %l4 -	or	%l4, %lo(swapper_pg_dir), %l4 -	sll	%l3, 2, %l3 -	ld	[%l4 + %l3], %l4 -	and	%l4, PAGE_MASK, %l4 - -	srl	%l5, (PAGE_SHIFT - 2), %l6 -	and	%l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6 -	add	%l6, %l4, %l6 - -	sethi	%hi(PAGE_SIZE), %l4 - -2: -	ld	[%l6], %l3 -	deccc	%l7 -	sta	%l3, [%l5] ASI_PTE -	add	%l6, 0x4, %l6 -	bne	2b -	 add	%l5, %l4, %l5 - -	sethi	%hi(sun4c_kernel_faults), %l4 -7: -	ld	[%l4 + %lo(sun4c_kernel_faults)], %l3 -	inc	%l3 -	st	%l3, [%l4 + %lo(sun4c_kernel_faults)] - -	/* Restore condition codes */ -	wr	%l0, 0x0, %psr +	ld	[%l5 + 0x00], %g0	! sun4m_irq_global->pending  	WRITE_PAUSE -	jmp	%l1 -	 rett	%l2 - -sun4c_fault_fromuser: -	SAVE_ALL +	or	%l0, PSR_PIL, %l4 +	wr	%l4, 0x0, %psr +	WRITE_PAUSE +	wr	%l4, PSR_ET, %psr +	WRITE_PAUSE +	call	sun4m_nmi  	 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 +	st	%l4, [%l5 + 0x08]	! sun4m_irq_global->mask_clear=0x80000000 +	WRITE_PAUSE +	ld	[%l5 + 0x00], %g0	! sun4m_irq_global->pending  	WRITE_PAUSE +	RESTORE_ALL -	call	do_sun4c_fault -	 add	%sp, STACKFRAME_SZ, %o0	! arg1 = pt_regs ptr +#ifndef CONFIG_SMP +	.align	4 +	.globl	linux_trap_ipi15_sun4m +linux_trap_ipi15_sun4m: +	SAVE_ALL -	RESTORE_ALL +	ba	sun4m_nmi_error +	 nop +#endif /* CONFIG_SMP */  	.align	4  	.globl	srmmu_fault @@ -1066,8 +767,11 @@ 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 +LEON_PI(lda	[%l5] ASI_LEON_MMUREGS, %l6)	! read sfar first +SUN_PI_(lda	[%l5] ASI_M_MMUREGS, %l6)	! read sfar first + +LEON_PI(lda	[%l4] ASI_LEON_MMUREGS, %l5)	! read sfsr last +SUN_PI_(lda	[%l4] ASI_M_MMUREGS, %l5)	! read sfsr last  	andn	%l6, 0xfff, %l6  	srl	%l5, 6, %l5			! and encode all info into l7 @@ -1102,23 +806,10 @@ sys_nis_syscall:  	call	c_sys_nis_syscall  	 mov	%l5, %o7 -	.align	4 -	.globl	sys_execve -sys_execve: -	mov	%o7, %l5 -	add	%sp, STACKFRAME_SZ, %o0		! pt_regs *regs arg -	call	sparc_execve -	 mov	%l5, %o7 - -	.globl	sunos_execv  sunos_execv: -	st	%g0, [%sp + STACKFRAME_SZ + PT_I2] - -	call	sparc_execve -	 add	%sp, STACKFRAME_SZ, %o0 - -	b	ret_sys_call -	 ld	[%sp + STACKFRAME_SZ + PT_I0], %o0 +	.globl	sunos_execv +	b	sys_execve +	 clr	%i2  	.align	4  	.globl	sys_sparc_pipe @@ -1129,14 +820,6 @@ sys_sparc_pipe:  	 mov	%l5, %o7  	.align	4 -	.globl	sys_sigaltstack -sys_sigaltstack: -	mov	%o7, %l5 -	mov	%fp, %o2 -	call	do_sigaltstack -	 mov	%l5, %o7 - -	.align	4  	.globl	sys_sigstack  sys_sigstack:  	mov	%o7, %l5 @@ -1156,7 +839,7 @@ sys_sigreturn:  	 nop  	call	syscall_trace -	 nop +	 mov	1, %o1  1:  	/* We don't want to muck with user registers like a @@ -1255,17 +938,9 @@ flush_patch_four:          .align  4  linux_sparc_ni_syscall:  	sethi   %hi(sys_ni_syscall), %l7 -	b       syscall_is_too_hard +	b       do_syscall  	 or     %l7, %lo(sys_ni_syscall), %l7 -linux_fast_syscall: -	andn	%l7, 3, %l7 -	mov	%i0, %o0 -	mov	%i1, %o1 -	mov 	%i2, %o2 -	jmpl	%l7 + %g0, %g0 -	 mov	%i3, %o3 -  linux_syscall_trace:  	add	%sp, STACKFRAME_SZ, %o0  	call	syscall_trace @@ -1283,10 +958,27 @@ linux_syscall_trace:  	.globl	ret_from_fork  ret_from_fork:  	call	schedule_tail -	 mov	%g3, %o0 +	 ld	[%g3 + TI_TASK], %o0  	b	ret_sys_call  	 ld	[%sp + STACKFRAME_SZ + PT_I0], %o0 +	.globl	ret_from_kernel_thread +ret_from_kernel_thread: +	call	schedule_tail +	 ld	[%g3 + TI_TASK], %o0 +	ld	[%sp + STACKFRAME_SZ + PT_G1], %l0 +	call	%l0 +	 ld	[%sp + STACKFRAME_SZ + PT_G2], %o0 +	rd	%psr, %l1 +	ld	[%sp + STACKFRAME_SZ + PT_PSR], %l0 +	andn	%l0, PSR_CWP, %l0 +	nop +	and	%l1, PSR_CWP, %l1 +	or	%l0, %l1, %l0 +	st	%l0, [%sp + STACKFRAME_SZ + PT_PSR] +	b	ret_sys_call +	 mov	0, %o0 +  	/* Linux native system calls enter here... */  	.align	4  	.globl	linux_sparc_syscall @@ -1298,11 +990,8 @@ linux_sparc_syscall:  	bgeu	linux_sparc_ni_syscall  	 sll	%g1, 2, %l4  	ld	[%l7 + %l4], %l7 -	andcc	%l7, 1, %g0 -	bne	linux_fast_syscall -	 /* Just do first insn from SAVE_ALL in the delay slot */ -syscall_is_too_hard: +do_syscall:  	SAVE_ALL_HEAD  	 rd	%wim, %l3 @@ -1462,11 +1151,13 @@ fpload:  	.globl	__ndelay  __ndelay:  	save	%sp, -STACKFRAME_SZ, %sp -	mov	%i0, %o0 -	call	.umul			! round multiplier up so large ns ok -	 mov	0x1ae, %o1		! 2**32 / (1 000 000 000 / HZ) -	call	.umul -	 mov	%i1, %o1		! udelay_val +	mov	%i0, %o0		! round multiplier up so large ns ok +	mov	0x1ae, %o1		! 2**32 / (1 000 000 000 / HZ) +	umul	%o0, %o1, %o0 +	rd	%y, %o1 +	mov	%i1, %o1		! udelay_val +	umul	%o0, %o1, %o0 +	rd	%y, %o1  	ba	delay_continue  	 mov	%o1, %o0		! >>32 later for better resolution @@ -1475,18 +1166,21 @@ __udelay:  	save	%sp, -STACKFRAME_SZ, %sp  	mov	%i0, %o0  	sethi	%hi(0x10c7), %o1	! round multiplier up so large us ok -	call	.umul -	 or	%o1, %lo(0x10c7), %o1	! 2**32 / 1 000 000 -	call	.umul -	 mov	%i1, %o1		! udelay_val +	or	%o1, %lo(0x10c7), %o1	! 2**32 / 1 000 000 +	umul	%o0, %o1, %o0 +	rd	%y, %o1 +	mov	%i1, %o1		! udelay_val +	umul	%o0, %o1, %o0 +	rd	%y, %o1  	sethi	%hi(0x028f4b62), %l0	! Add in rounding constant * 2**32,  	or	%g0, %lo(0x028f4b62), %l0  	addcc	%o0, %l0, %o0		! 2**32 * 0.009 999  	bcs,a	3f  	 add	%o1, 0x01, %o1  3: -	call	.umul -	 mov	HZ, %o0			! >>32 earlier for wider range +	mov	HZ, %o0			! >>32 earlier for wider range +	umul	%o0, %o1, %o0 +	rd	%y, %o1  delay_continue:  	cmp	%o0, 0x0 @@ -1583,7 +1277,7 @@ restore_current:  	retl  	 nop -#ifdef CONFIG_PCI +#ifdef CONFIG_PCIC_PCI  #include <asm/pcic.h>  	.align	4 @@ -1629,7 +1323,7 @@ pcic_nmi_trap_patch:  	 rd	%psr, %l0  	.word	0 -#endif /* CONFIG_PCI */ +#endif /* CONFIG_PCIC_PCI */  	.globl	flushw_all  flushw_all: @@ -1649,4 +1343,26 @@ flushw_all:  	ret  	 restore +#ifdef CONFIG_SMP +ENTRY(hard_smp_processor_id) +661:	rd		%tbr, %g1 +	srl		%g1, 12, %o0 +	and		%o0, 3, %o0 +	.section	.cpuid_patch, "ax" +	/* Instruction location. */ +	.word		661b +	/* SUN4D implementation. */ +	lda		[%g0] ASI_M_VIKING_TMP1, %o0 +	nop +	nop +	/* LEON implementation. */ +	rd		%asr17, %o0 +	srl		%o0, 0x1c, %o0 +	nop +	.previous +	retl +	 nop +ENDPROC(hard_smp_processor_id) +#endif +  /* End of entry.S */  | 
