xref: /openbmc/linux/arch/sparc/kernel/entry.S (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
1b2441318SGreg Kroah-Hartman/* SPDX-License-Identifier: GPL-2.0 */
20a808a31SDavid S. Miller/* arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
31da177e4SLinus Torvalds *
40a808a31SDavid S. Miller * Copyright (C) 1995, 2007 David S. Miller (davem@davemloft.net)
51da177e4SLinus Torvalds * Copyright (C) 1996 Eddie C. Dost   (ecd@skynet.be)
61da177e4SLinus Torvalds * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
71da177e4SLinus Torvalds * Copyright (C) 1996-1999 Jakub Jelinek   (jj@sunsite.mff.cuni.cz)
81da177e4SLinus Torvalds * Copyright (C) 1997 Anton Blanchard (anton@progsoc.uts.edu.au)
91da177e4SLinus Torvalds */
101da177e4SLinus Torvalds
11*4cdb71b6SMasahiro Yamada#include <linux/export.h>
12c68e5d39SDavid S. Miller#include <linux/linkage.h>
131da177e4SLinus Torvalds#include <linux/errno.h>
1465fddcfcSMike Rapoport#include <linux/pgtable.h>
151da177e4SLinus Torvalds
161da177e4SLinus Torvalds#include <asm/head.h>
171da177e4SLinus Torvalds#include <asm/asi.h>
181da177e4SLinus Torvalds#include <asm/smp.h>
191da177e4SLinus Torvalds#include <asm/contregs.h>
201da177e4SLinus Torvalds#include <asm/ptrace.h>
2147003497SSam Ravnborg#include <asm/asm-offsets.h>
221da177e4SLinus Torvalds#include <asm/psr.h>
231da177e4SLinus Torvalds#include <asm/vaddrs.h>
241da177e4SLinus Torvalds#include <asm/page.h>
251da177e4SLinus Torvalds#include <asm/winmacro.h>
261da177e4SLinus Torvalds#include <asm/signal.h>
271da177e4SLinus Torvalds#include <asm/obio.h>
281da177e4SLinus Torvalds#include <asm/mxcc.h>
291da177e4SLinus Torvalds#include <asm/thread_info.h>
301da177e4SLinus Torvalds#include <asm/param.h>
3159359ff8SDavid S. Miller#include <asm/unistd.h>
321da177e4SLinus Torvalds
331da177e4SLinus Torvalds#include <asm/asmmacro.h>
341da177e4SLinus Torvalds
351da177e4SLinus Torvalds#define curptr      g6
361da177e4SLinus Torvalds
371da177e4SLinus Torvalds/* These are just handy. */
381da177e4SLinus Torvalds#define _SV	save	%sp, -STACKFRAME_SZ, %sp
391da177e4SLinus Torvalds#define _RS     restore
401da177e4SLinus Torvalds
411da177e4SLinus Torvalds#define FLUSH_ALL_KERNEL_WINDOWS \
421da177e4SLinus Torvalds	_SV; _SV; _SV; _SV; _SV; _SV; _SV; \
431da177e4SLinus Torvalds	_RS; _RS; _RS; _RS; _RS; _RS; _RS;
441da177e4SLinus Torvalds
451da177e4SLinus Torvalds	.text
46e2fdd7fdSDavid S. Miller
47e2fdd7fdSDavid S. Miller#ifdef CONFIG_KGDB
481da177e4SLinus Torvalds	.align	4
49e2fdd7fdSDavid S. Miller	.globl		arch_kgdb_breakpoint
50e2fdd7fdSDavid S. Miller	.type		arch_kgdb_breakpoint,#function
51e2fdd7fdSDavid S. Millerarch_kgdb_breakpoint:
52e2fdd7fdSDavid S. Miller	ta		0x7d
53e2fdd7fdSDavid S. Miller	retl
54e2fdd7fdSDavid S. Miller	 nop
55e2fdd7fdSDavid S. Miller	.size		arch_kgdb_breakpoint,.-arch_kgdb_breakpoint
561da177e4SLinus Torvalds#endif
571da177e4SLinus Torvalds
580a808a31SDavid S. Miller#if defined(CONFIG_BLK_DEV_FD) || defined(CONFIG_BLK_DEV_FD_MODULE)
591da177e4SLinus Torvalds	.align	4
601da177e4SLinus Torvalds	.globl	floppy_hardint
611da177e4SLinus Torvaldsfloppy_hardint:
621da177e4SLinus Torvalds	/*
631da177e4SLinus Torvalds	 * This code cannot touch registers %l0 %l1 and %l2
641da177e4SLinus Torvalds	 * because SAVE_ALL depends on their values. It depends
651da177e4SLinus Torvalds	 * on %l3 also, but we regenerate it before a call.
661da177e4SLinus Torvalds	 * Other registers are:
671da177e4SLinus Torvalds	 * %l3 -- base address of fdc registers
681da177e4SLinus Torvalds	 * %l4 -- pdma_vaddr
691da177e4SLinus Torvalds	 * %l5 -- scratch for ld/st address
701da177e4SLinus Torvalds	 * %l6 -- pdma_size
711da177e4SLinus Torvalds	 * %l7 -- scratch [floppy byte, ld/st address, aux. data]
721da177e4SLinus Torvalds	 */
731da177e4SLinus Torvalds
741da177e4SLinus Torvalds	/* Do we have work to do? */
751da177e4SLinus Torvalds	sethi	%hi(doing_pdma), %l7
761da177e4SLinus Torvalds	ld	[%l7 + %lo(doing_pdma)], %l7
771da177e4SLinus Torvalds	cmp	%l7, 0
781da177e4SLinus Torvalds	be	floppy_dosoftint
791da177e4SLinus Torvalds	 nop
801da177e4SLinus Torvalds
811da177e4SLinus Torvalds	/* Load fdc register base */
821da177e4SLinus Torvalds	sethi	%hi(fdc_status), %l3
831da177e4SLinus Torvalds	ld	[%l3 + %lo(fdc_status)], %l3
841da177e4SLinus Torvalds
851da177e4SLinus Torvalds	/* Setup register addresses */
861da177e4SLinus Torvalds	sethi	%hi(pdma_vaddr), %l5	! transfer buffer
871da177e4SLinus Torvalds	ld	[%l5 + %lo(pdma_vaddr)], %l4
881da177e4SLinus Torvalds	sethi	%hi(pdma_size), %l5	! bytes to go
891da177e4SLinus Torvalds	ld	[%l5 + %lo(pdma_size)], %l6
901da177e4SLinus Torvaldsnext_byte:
911da177e4SLinus Torvalds  	ldub	[%l3], %l7
921da177e4SLinus Torvalds
931da177e4SLinus Torvalds	andcc	%l7, 0x80, %g0		! Does fifo still have data
941da177e4SLinus Torvalds	bz	floppy_fifo_emptied	! fifo has been emptied...
951da177e4SLinus Torvalds	 andcc	%l7, 0x20, %g0		! in non-dma mode still?
961da177e4SLinus Torvalds	bz	floppy_overrun		! nope, overrun
971da177e4SLinus Torvalds	 andcc	%l7, 0x40, %g0		! 0=write 1=read
981da177e4SLinus Torvalds	bz	floppy_write
991da177e4SLinus Torvalds	 sub	%l6, 0x1, %l6
1001da177e4SLinus Torvalds
1011da177e4SLinus Torvalds	/* Ok, actually read this byte */
1021da177e4SLinus Torvalds	ldub	[%l3 + 1], %l7
1031da177e4SLinus Torvalds	orcc	%g0, %l6, %g0
1041da177e4SLinus Torvalds	stb	%l7, [%l4]
1051da177e4SLinus Torvalds	bne	next_byte
1061da177e4SLinus Torvalds	 add	%l4, 0x1, %l4
1071da177e4SLinus Torvalds
1081da177e4SLinus Torvalds	b	floppy_tdone
1091da177e4SLinus Torvalds	 nop
1101da177e4SLinus Torvalds
1111da177e4SLinus Torvaldsfloppy_write:
1121da177e4SLinus Torvalds	/* Ok, actually write this byte */
1131da177e4SLinus Torvalds	ldub	[%l4], %l7
1141da177e4SLinus Torvalds	orcc	%g0, %l6, %g0
1151da177e4SLinus Torvalds	stb	%l7, [%l3 + 1]
1161da177e4SLinus Torvalds	bne	next_byte
1171da177e4SLinus Torvalds	 add	%l4, 0x1, %l4
1181da177e4SLinus Torvalds
1191da177e4SLinus Torvalds	/* fall through... */
1201da177e4SLinus Torvaldsfloppy_tdone:
1211da177e4SLinus Torvalds	sethi	%hi(pdma_vaddr), %l5
1221da177e4SLinus Torvalds	st	%l4, [%l5 + %lo(pdma_vaddr)]
1231da177e4SLinus Torvalds	sethi	%hi(pdma_size), %l5
1241da177e4SLinus Torvalds	st	%l6, [%l5 + %lo(pdma_size)]
1251da177e4SLinus Torvalds	/* Flip terminal count pin */
1261da177e4SLinus Torvalds	set	auxio_register, %l7
1271da177e4SLinus Torvalds	ld	[%l7], %l7
1281da177e4SLinus Torvalds
1291da177e4SLinus Torvalds	ldub	[%l7], %l5
1301da177e4SLinus Torvalds
1311da177e4SLinus Torvalds	or	%l5, 0xc2, %l5
1321da177e4SLinus Torvalds	stb	%l5, [%l7]
1331da177e4SLinus Torvalds	andn    %l5, 0x02, %l5
1341da177e4SLinus Torvalds
1351da177e4SLinus Torvalds2:
1361da177e4SLinus Torvalds	/* Kill some time so the bits set */
1371da177e4SLinus Torvalds	WRITE_PAUSE
1381da177e4SLinus Torvalds	WRITE_PAUSE
1391da177e4SLinus Torvalds
1401da177e4SLinus Torvalds	stb     %l5, [%l7]
1411da177e4SLinus Torvalds
1421da177e4SLinus Torvalds	/* Prevent recursion */
1431da177e4SLinus Torvalds	sethi	%hi(doing_pdma), %l7
1441da177e4SLinus Torvalds	b	floppy_dosoftint
1451da177e4SLinus Torvalds	 st	%g0, [%l7 + %lo(doing_pdma)]
1461da177e4SLinus Torvalds
1471da177e4SLinus Torvalds	/* We emptied the FIFO, but we haven't read everything
1481da177e4SLinus Torvalds	 * as of yet.  Store the current transfer address and
1491da177e4SLinus Torvalds	 * bytes left to read so we can continue when the next
1501da177e4SLinus Torvalds	 * fast IRQ comes in.
1511da177e4SLinus Torvalds	 */
1521da177e4SLinus Torvaldsfloppy_fifo_emptied:
1531da177e4SLinus Torvalds	sethi	%hi(pdma_vaddr), %l5
1541da177e4SLinus Torvalds	st	%l4, [%l5 + %lo(pdma_vaddr)]
1551da177e4SLinus Torvalds	sethi	%hi(pdma_size), %l7
1561da177e4SLinus Torvalds	st	%l6, [%l7 + %lo(pdma_size)]
1571da177e4SLinus Torvalds
1581da177e4SLinus Torvalds	/* Restore condition codes */
1591da177e4SLinus Torvalds	wr	%l0, 0x0, %psr
1601da177e4SLinus Torvalds	WRITE_PAUSE
1611da177e4SLinus Torvalds
1621da177e4SLinus Torvalds	jmp	%l1
1631da177e4SLinus Torvalds	rett	%l2
1641da177e4SLinus Torvalds
1651da177e4SLinus Torvaldsfloppy_overrun:
1661da177e4SLinus Torvalds	sethi	%hi(pdma_vaddr), %l5
1671da177e4SLinus Torvalds	st	%l4, [%l5 + %lo(pdma_vaddr)]
1681da177e4SLinus Torvalds	sethi	%hi(pdma_size), %l5
1691da177e4SLinus Torvalds	st	%l6, [%l5 + %lo(pdma_size)]
1701da177e4SLinus Torvalds	/* Prevent recursion */
1711da177e4SLinus Torvalds	sethi	%hi(doing_pdma), %l7
1721da177e4SLinus Torvalds	st	%g0, [%l7 + %lo(doing_pdma)]
1731da177e4SLinus Torvalds
1741da177e4SLinus Torvalds	/* fall through... */
1751da177e4SLinus Torvaldsfloppy_dosoftint:
1761da177e4SLinus Torvalds	rd	%wim, %l3
1771da177e4SLinus Torvalds	SAVE_ALL
1781da177e4SLinus Torvalds
1791da177e4SLinus Torvalds	/* Set all IRQs off. */
1801da177e4SLinus Torvalds	or	%l0, PSR_PIL, %l4
1811da177e4SLinus Torvalds	wr	%l4, 0x0, %psr
1821da177e4SLinus Torvalds	WRITE_PAUSE
1831da177e4SLinus Torvalds	wr	%l4, PSR_ET, %psr
1841da177e4SLinus Torvalds	WRITE_PAUSE
1851da177e4SLinus Torvalds
1861da177e4SLinus Torvalds	mov	11, %o0			! floppy irq level (unused anyway)
1871da177e4SLinus Torvalds	mov	%g0, %o1		! devid is not used in fast interrupts
1881da177e4SLinus Torvalds	call	sparc_floppy_irq
1891da177e4SLinus Torvalds	 add	%sp, STACKFRAME_SZ, %o2	! struct pt_regs *regs
1901da177e4SLinus Torvalds
1911da177e4SLinus Torvalds	RESTORE_ALL
1921da177e4SLinus Torvalds
1931da177e4SLinus Torvalds#endif /* (CONFIG_BLK_DEV_FD) */
1941da177e4SLinus Torvalds
1951da177e4SLinus Torvalds	/* Bad trap handler */
1961da177e4SLinus Torvalds	.globl	bad_trap_handler
1971da177e4SLinus Torvaldsbad_trap_handler:
1981da177e4SLinus Torvalds	SAVE_ALL
1991da177e4SLinus Torvalds
2001da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr
2011da177e4SLinus Torvalds	WRITE_PAUSE
2021da177e4SLinus Torvalds
2031da177e4SLinus Torvalds	add	%sp, STACKFRAME_SZ, %o0	! pt_regs
2041da177e4SLinus Torvalds	call	do_hw_interrupt
2051da177e4SLinus Torvalds	 mov	%l7, %o1		! trap number
2061da177e4SLinus Torvalds
2071da177e4SLinus Torvalds	RESTORE_ALL
2081da177e4SLinus Torvalds
2091da177e4SLinus Torvalds/* For now all IRQ's not registered get sent here. handler_irq() will
2101da177e4SLinus Torvalds * see if a routine is registered to handle this interrupt and if not
2111da177e4SLinus Torvalds * it will say so on the console.
2121da177e4SLinus Torvalds */
2131da177e4SLinus Torvalds
2141da177e4SLinus Torvalds	.align	4
2151da177e4SLinus Torvalds	.globl	real_irq_entry, patch_handler_irq
2161da177e4SLinus Torvaldsreal_irq_entry:
2171da177e4SLinus Torvalds	SAVE_ALL
2181da177e4SLinus Torvalds
2191da177e4SLinus Torvalds#ifdef CONFIG_SMP
2201da177e4SLinus Torvalds	.globl	patchme_maybe_smp_msg
2211da177e4SLinus Torvalds
222a7d82a0aSDaniel Hellstrom	cmp	%l7, 11
2231da177e4SLinus Torvaldspatchme_maybe_smp_msg:
2241da177e4SLinus Torvalds	bgu	maybe_smp4m_msg
2251da177e4SLinus Torvalds	 nop
2261da177e4SLinus Torvalds#endif
2271da177e4SLinus Torvalds
2281da177e4SLinus Torvaldsreal_irq_continue:
2291da177e4SLinus Torvalds	or	%l0, PSR_PIL, %g2
2301da177e4SLinus Torvalds	wr	%g2, 0x0, %psr
2311da177e4SLinus Torvalds	WRITE_PAUSE
2321da177e4SLinus Torvalds	wr	%g2, PSR_ET, %psr
2331da177e4SLinus Torvalds	WRITE_PAUSE
2341da177e4SLinus Torvalds	mov	%l7, %o0		! irq level
2351da177e4SLinus Torvaldspatch_handler_irq:
2361da177e4SLinus Torvalds	call	handler_irq
2371da177e4SLinus Torvalds	 add	%sp, STACKFRAME_SZ, %o1	! pt_regs ptr
2381da177e4SLinus Torvalds	or	%l0, PSR_PIL, %g2	! restore PIL after handler_irq
2391da177e4SLinus Torvalds	wr	%g2, PSR_ET, %psr	! keep ET up
2401da177e4SLinus Torvalds	WRITE_PAUSE
2411da177e4SLinus Torvalds
2421da177e4SLinus Torvalds	RESTORE_ALL
2431da177e4SLinus Torvalds
2441da177e4SLinus Torvalds#ifdef CONFIG_SMP
2451da177e4SLinus Torvalds	/* SMP per-cpu ticker interrupts are handled specially. */
2461da177e4SLinus Torvaldssmp4m_ticker:
2471da177e4SLinus Torvalds	bne	real_irq_continue+4
2481da177e4SLinus Torvalds	 or	%l0, PSR_PIL, %g2
2491da177e4SLinus Torvalds	wr	%g2, 0x0, %psr
2501da177e4SLinus Torvalds	WRITE_PAUSE
2511da177e4SLinus Torvalds	wr	%g2, PSR_ET, %psr
2521da177e4SLinus Torvalds	WRITE_PAUSE
2531da177e4SLinus Torvalds	call	smp4m_percpu_timer_interrupt
2541da177e4SLinus Torvalds	 add	%sp, STACKFRAME_SZ, %o0
2551da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr
2561da177e4SLinus Torvalds	WRITE_PAUSE
2571da177e4SLinus Torvalds	RESTORE_ALL
2581da177e4SLinus Torvalds
2590bfcee9aSDavid S. Miller#define GET_PROCESSOR4M_ID(reg)	\
2600bfcee9aSDavid S. Miller	rd	%tbr, %reg;	\
2610bfcee9aSDavid S. Miller	srl	%reg, 12, %reg;	\
2620bfcee9aSDavid S. Miller	and	%reg, 3, %reg;
2630bfcee9aSDavid S. Miller
2641da177e4SLinus Torvalds	/* Here is where we check for possible SMP IPI passed to us
2651da177e4SLinus Torvalds	 * on some level other than 15 which is the NMI and only used
2661da177e4SLinus Torvalds	 * for cross calls.  That has a separate entry point below.
267ecbc42b7SDaniel Hellstrom	 *
268ecbc42b7SDaniel Hellstrom	 * IPIs are sent on Level 12, 13 and 14. See IRQ_IPI_*.
2691da177e4SLinus Torvalds	 */
2701da177e4SLinus Torvaldsmaybe_smp4m_msg:
2711da177e4SLinus Torvalds	GET_PROCESSOR4M_ID(o3)
27269c010b2SDavid S. Miller	sethi	%hi(sun4m_irq_percpu), %l5
27369c010b2SDavid S. Miller	sll	%o3, 2, %o3
27469c010b2SDavid S. Miller	or	%l5, %lo(sun4m_irq_percpu), %o5
275ecbc42b7SDaniel Hellstrom	sethi	%hi(0x70000000), %o2	! Check all soft-IRQs
2761da177e4SLinus Torvalds	ld	[%o5 + %o3], %o1
27769c010b2SDavid S. Miller	ld	[%o1 + 0x00], %o3	! sun4m_irq_percpu[cpu]->pending
27869c010b2SDavid S. Miller	andcc	%o3, %o2, %g0
2791da177e4SLinus Torvalds	be,a	smp4m_ticker
2801da177e4SLinus Torvalds	 cmp	%l7, 14
281ecbc42b7SDaniel Hellstrom	/* Soft-IRQ IPI */
282ecbc42b7SDaniel Hellstrom	st	%o2, [%o1 + 0x04]	! sun4m_irq_percpu[cpu]->clear=0x70000000
2831da177e4SLinus Torvalds	WRITE_PAUSE
28469c010b2SDavid S. Miller	ld	[%o1 + 0x00], %g0	! sun4m_irq_percpu[cpu]->pending
2851da177e4SLinus Torvalds	WRITE_PAUSE
2861da177e4SLinus Torvalds	or	%l0, PSR_PIL, %l4
2871da177e4SLinus Torvalds	wr	%l4, 0x0, %psr
2881da177e4SLinus Torvalds	WRITE_PAUSE
2891da177e4SLinus Torvalds	wr	%l4, PSR_ET, %psr
2901da177e4SLinus Torvalds	WRITE_PAUSE
2911ef48593SWill Simoneau	srl	%o3, 28, %o2		! shift for simpler checks below
292ecbc42b7SDaniel Hellstrommaybe_smp4m_msg_check_single:
293ecbc42b7SDaniel Hellstrom	andcc	%o2, 0x1, %g0
294ecbc42b7SDaniel Hellstrom	beq,a	maybe_smp4m_msg_check_mask
295ecbc42b7SDaniel Hellstrom	 andcc	%o2, 0x2, %g0
296ecbc42b7SDaniel Hellstrom	call	smp_call_function_single_interrupt
2971da177e4SLinus Torvalds	 nop
298ecbc42b7SDaniel Hellstrom	andcc	%o2, 0x2, %g0
299ecbc42b7SDaniel Hellstrommaybe_smp4m_msg_check_mask:
300ecbc42b7SDaniel Hellstrom	beq,a	maybe_smp4m_msg_check_resched
301ecbc42b7SDaniel Hellstrom	 andcc	%o2, 0x4, %g0
302ecbc42b7SDaniel Hellstrom	call	smp_call_function_interrupt
303ecbc42b7SDaniel Hellstrom	 nop
304ecbc42b7SDaniel Hellstrom	andcc	%o2, 0x4, %g0
305ecbc42b7SDaniel Hellstrommaybe_smp4m_msg_check_resched:
306ecbc42b7SDaniel Hellstrom	/* rescheduling is done in RESTORE_ALL regardless, but incr stats */
307ecbc42b7SDaniel Hellstrom	beq,a	maybe_smp4m_msg_out
308ecbc42b7SDaniel Hellstrom	 nop
309ecbc42b7SDaniel Hellstrom	call	smp_resched_interrupt
310ecbc42b7SDaniel Hellstrom	 nop
311ecbc42b7SDaniel Hellstrommaybe_smp4m_msg_out:
3121da177e4SLinus Torvalds	RESTORE_ALL
3131da177e4SLinus Torvalds
3141da177e4SLinus Torvalds	.align	4
31596061a91SDavid S. Miller	.globl	linux_trap_ipi15_sun4m
31696061a91SDavid S. Millerlinux_trap_ipi15_sun4m:
3171da177e4SLinus Torvalds	SAVE_ALL
3181da177e4SLinus Torvalds	sethi	%hi(0x80000000), %o2
3191da177e4SLinus Torvalds	GET_PROCESSOR4M_ID(o0)
32069c010b2SDavid S. Miller	sethi	%hi(sun4m_irq_percpu), %l5
32169c010b2SDavid S. Miller	or	%l5, %lo(sun4m_irq_percpu), %o5
32269c010b2SDavid S. Miller	sll	%o0, 2, %o0
32369c010b2SDavid S. Miller	ld	[%o5 + %o0], %o5
32469c010b2SDavid S. Miller	ld	[%o5 + 0x00], %o3	! sun4m_irq_percpu[cpu]->pending
3251da177e4SLinus Torvalds	andcc	%o3, %o2, %g0
32696061a91SDavid S. Miller	be	sun4m_nmi_error		! Must be an NMI async memory error
32769c010b2SDavid S. Miller	 st	%o2, [%o5 + 0x04]	! sun4m_irq_percpu[cpu]->clear=0x80000000
3281da177e4SLinus Torvalds	WRITE_PAUSE
32969c010b2SDavid S. Miller	ld	[%o5 + 0x00], %g0	! sun4m_irq_percpu[cpu]->pending
3301da177e4SLinus Torvalds	WRITE_PAUSE
3311da177e4SLinus Torvalds	or	%l0, PSR_PIL, %l4
3321da177e4SLinus Torvalds	wr	%l4, 0x0, %psr
3331da177e4SLinus Torvalds	WRITE_PAUSE
3341da177e4SLinus Torvalds	wr	%l4, PSR_ET, %psr
3351da177e4SLinus Torvalds	WRITE_PAUSE
3361da177e4SLinus Torvalds	call	smp4m_cross_call_irq
3371da177e4SLinus Torvalds	 nop
3381da177e4SLinus Torvalds	b	ret_trap_lockless_ipi
3391da177e4SLinus Torvalds	 clr	%l6
3401da177e4SLinus Torvalds
3411da177e4SLinus Torvalds	.globl	smp4d_ticker
3421da177e4SLinus Torvalds	/* SMP per-cpu ticker interrupts are handled specially. */
3431da177e4SLinus Torvaldssmp4d_ticker:
3441da177e4SLinus Torvalds	SAVE_ALL
3451da177e4SLinus Torvalds	or	%l0, PSR_PIL, %g2
3461da177e4SLinus Torvalds	sethi	%hi(CC_ICLR), %o0
3471da177e4SLinus Torvalds	sethi	%hi(1 << 14), %o1
3481da177e4SLinus Torvalds	or	%o0, %lo(CC_ICLR), %o0
3491da177e4SLinus Torvalds	stha	%o1, [%o0] ASI_M_MXCC	/* Clear PIL 14 in MXCC's ICLR */
3501da177e4SLinus Torvalds	wr	%g2, 0x0, %psr
3511da177e4SLinus Torvalds	WRITE_PAUSE
3521da177e4SLinus Torvalds	wr	%g2, PSR_ET, %psr
3531da177e4SLinus Torvalds	WRITE_PAUSE
3541da177e4SLinus Torvalds	call	smp4d_percpu_timer_interrupt
3551da177e4SLinus Torvalds	 add	%sp, STACKFRAME_SZ, %o0
3561da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr
3571da177e4SLinus Torvalds	WRITE_PAUSE
3581da177e4SLinus Torvalds	RESTORE_ALL
3591da177e4SLinus Torvalds
3601da177e4SLinus Torvalds	.align	4
3611da177e4SLinus Torvalds	.globl	linux_trap_ipi15_sun4d
3621da177e4SLinus Torvaldslinux_trap_ipi15_sun4d:
3631da177e4SLinus Torvalds	SAVE_ALL
3641da177e4SLinus Torvalds	sethi	%hi(CC_BASE), %o4
3651da177e4SLinus Torvalds	sethi	%hi(MXCC_ERR_ME|MXCC_ERR_PEW|MXCC_ERR_ASE|MXCC_ERR_PEE), %o2
3661da177e4SLinus Torvalds	or	%o4, (CC_EREG - CC_BASE), %o0
3671da177e4SLinus Torvalds	ldda	[%o0] ASI_M_MXCC, %o0
3681da177e4SLinus Torvalds	andcc	%o0, %o2, %g0
3691da177e4SLinus Torvalds	bne	1f
3701da177e4SLinus Torvalds	 sethi	%hi(BB_STAT2), %o2
3711da177e4SLinus Torvalds	lduba	[%o2] ASI_M_CTL, %o2
3721da177e4SLinus Torvalds	andcc	%o2, BB_STAT2_MASK, %g0
3731da177e4SLinus Torvalds	bne	2f
3741da177e4SLinus Torvalds	 or	%o4, (CC_ICLR - CC_BASE), %o0
3751da177e4SLinus Torvalds	sethi	%hi(1 << 15), %o1
3761da177e4SLinus Torvalds	stha	%o1, [%o0] ASI_M_MXCC	/* Clear PIL 15 in MXCC's ICLR */
3771da177e4SLinus Torvalds	or	%l0, PSR_PIL, %l4
3781da177e4SLinus Torvalds	wr	%l4, 0x0, %psr
3791da177e4SLinus Torvalds	WRITE_PAUSE
3801da177e4SLinus Torvalds	wr	%l4, PSR_ET, %psr
3811da177e4SLinus Torvalds	WRITE_PAUSE
3821da177e4SLinus Torvalds	call	smp4d_cross_call_irq
3831da177e4SLinus Torvalds	 nop
3841da177e4SLinus Torvalds	b	ret_trap_lockless_ipi
3851da177e4SLinus Torvalds	 clr	%l6
3861da177e4SLinus Torvalds
3871da177e4SLinus Torvalds1:	/* MXCC error */
3881da177e4SLinus Torvalds2:	/* BB error */
3891da177e4SLinus Torvalds	/* Disable PIL 15 */
3901da177e4SLinus Torvalds	set	CC_IMSK, %l4
3911da177e4SLinus Torvalds	lduha	[%l4] ASI_M_MXCC, %l5
3921da177e4SLinus Torvalds	sethi	%hi(1 << 15), %l7
3931da177e4SLinus Torvalds	or	%l5, %l7, %l5
3941da177e4SLinus Torvalds	stha	%l5, [%l4] ASI_M_MXCC
3951da177e4SLinus Torvalds	/* FIXME */
3961da177e4SLinus Torvalds1:	b,a	1b
3971da177e4SLinus Torvalds
3981ca0c808SDaniel Hellstrom	.globl	smpleon_ipi
3991ca0c808SDaniel Hellstrom	.extern leon_ipi_interrupt
4001ca0c808SDaniel Hellstrom	/* SMP per-cpu IPI interrupts are handled specially. */
4011ca0c808SDaniel Hellstromsmpleon_ipi:
4021ca0c808SDaniel Hellstrom        SAVE_ALL
4031ca0c808SDaniel Hellstrom	or	%l0, PSR_PIL, %g2
4041ca0c808SDaniel Hellstrom	wr	%g2, 0x0, %psr
4051ca0c808SDaniel Hellstrom	WRITE_PAUSE
4061ca0c808SDaniel Hellstrom	wr	%g2, PSR_ET, %psr
4071ca0c808SDaniel Hellstrom	WRITE_PAUSE
4081ca0c808SDaniel Hellstrom	call	leonsmp_ipi_interrupt
4091ca0c808SDaniel Hellstrom	 add	%sp, STACKFRAME_SZ, %o1 ! pt_regs
4101ca0c808SDaniel Hellstrom	wr	%l0, PSR_ET, %psr
4111ca0c808SDaniel Hellstrom	WRITE_PAUSE
4121ca0c808SDaniel Hellstrom	RESTORE_ALL
4131ca0c808SDaniel Hellstrom
4148401707fSKonrad Eisele	.align	4
4158401707fSKonrad Eisele	.globl	linux_trap_ipi15_leon
4168401707fSKonrad Eiselelinux_trap_ipi15_leon:
4178401707fSKonrad Eisele	SAVE_ALL
4188401707fSKonrad Eisele	or	%l0, PSR_PIL, %l4
4198401707fSKonrad Eisele	wr	%l4, 0x0, %psr
4208401707fSKonrad Eisele	WRITE_PAUSE
4218401707fSKonrad Eisele	wr	%l4, PSR_ET, %psr
4228401707fSKonrad Eisele	WRITE_PAUSE
4238401707fSKonrad Eisele	call	leon_cross_call_irq
4248401707fSKonrad Eisele	 nop
4258401707fSKonrad Eisele	b	ret_trap_lockless_ipi
4268401707fSKonrad Eisele	 clr	%l6
4278401707fSKonrad Eisele
4281da177e4SLinus Torvalds#endif /* CONFIG_SMP */
4291da177e4SLinus Torvalds
4301da177e4SLinus Torvalds	/* This routine handles illegal instructions and privileged
4311da177e4SLinus Torvalds	 * instruction attempts from user code.
4321da177e4SLinus Torvalds	 */
4331da177e4SLinus Torvalds	.align	4
4341da177e4SLinus Torvalds	.globl	bad_instruction
4351da177e4SLinus Torvaldsbad_instruction:
4361da177e4SLinus Torvalds	sethi	%hi(0xc1f80000), %l4
4371da177e4SLinus Torvalds	ld	[%l1], %l5
4381da177e4SLinus Torvalds	sethi	%hi(0x81d80000), %l7
4391da177e4SLinus Torvalds	and	%l5, %l4, %l5
4401da177e4SLinus Torvalds	cmp	%l5, %l7
4411da177e4SLinus Torvalds	be	1f
4421da177e4SLinus Torvalds	SAVE_ALL
4431da177e4SLinus Torvalds
4441da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr		! re-enable traps
4451da177e4SLinus Torvalds	WRITE_PAUSE
4461da177e4SLinus Torvalds
4471da177e4SLinus Torvalds	add	%sp, STACKFRAME_SZ, %o0
4481da177e4SLinus Torvalds	mov	%l1, %o1
4491da177e4SLinus Torvalds	mov	%l2, %o2
4501da177e4SLinus Torvalds	call	do_illegal_instruction
4511da177e4SLinus Torvalds	 mov	%l0, %o3
4521da177e4SLinus Torvalds
4531da177e4SLinus Torvalds	RESTORE_ALL
4541da177e4SLinus Torvalds
4551da177e4SLinus Torvalds1:	/* unimplemented flush - just skip */
4561da177e4SLinus Torvalds	jmpl	%l2, %g0
4571da177e4SLinus Torvalds	 rett	%l2 + 4
4581da177e4SLinus Torvalds
4591da177e4SLinus Torvalds	.align	4
4601da177e4SLinus Torvalds	.globl	priv_instruction
4611da177e4SLinus Torvaldspriv_instruction:
4621da177e4SLinus Torvalds	SAVE_ALL
4631da177e4SLinus Torvalds
4641da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr
4651da177e4SLinus Torvalds	WRITE_PAUSE
4661da177e4SLinus Torvalds
4671da177e4SLinus Torvalds	add	%sp, STACKFRAME_SZ, %o0
4681da177e4SLinus Torvalds	mov	%l1, %o1
4691da177e4SLinus Torvalds	mov	%l2, %o2
4701da177e4SLinus Torvalds	call	do_priv_instruction
4711da177e4SLinus Torvalds	 mov	%l0, %o3
4721da177e4SLinus Torvalds
4731da177e4SLinus Torvalds	RESTORE_ALL
4741da177e4SLinus Torvalds
4751da177e4SLinus Torvalds	/* This routine handles unaligned data accesses. */
4761da177e4SLinus Torvalds	.align	4
4771da177e4SLinus Torvalds	.globl	mna_handler
4781da177e4SLinus Torvaldsmna_handler:
4791da177e4SLinus Torvalds	andcc	%l0, PSR_PS, %g0
4801da177e4SLinus Torvalds	be	mna_fromuser
4811da177e4SLinus Torvalds	 nop
4821da177e4SLinus Torvalds
4831da177e4SLinus Torvalds	SAVE_ALL
4841da177e4SLinus Torvalds
4851da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr
4861da177e4SLinus Torvalds	WRITE_PAUSE
4871da177e4SLinus Torvalds
4881da177e4SLinus Torvalds	ld	[%l1], %o1
4891da177e4SLinus Torvalds	call	kernel_unaligned_trap
4901da177e4SLinus Torvalds	 add	%sp, STACKFRAME_SZ, %o0
4911da177e4SLinus Torvalds
4921da177e4SLinus Torvalds	RESTORE_ALL
4931da177e4SLinus Torvalds
4941da177e4SLinus Torvaldsmna_fromuser:
4951da177e4SLinus Torvalds	SAVE_ALL
4961da177e4SLinus Torvalds
4971da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr		! re-enable traps
4981da177e4SLinus Torvalds	WRITE_PAUSE
4991da177e4SLinus Torvalds
5001da177e4SLinus Torvalds	ld	[%l1], %o1
5011da177e4SLinus Torvalds	call	user_unaligned_trap
5021da177e4SLinus Torvalds	 add	%sp, STACKFRAME_SZ, %o0
5031da177e4SLinus Torvalds
5041da177e4SLinus Torvalds	RESTORE_ALL
5051da177e4SLinus Torvalds
5061da177e4SLinus Torvalds	/* This routine handles floating point disabled traps. */
5071da177e4SLinus Torvalds	.align	4
5081da177e4SLinus Torvalds	.globl	fpd_trap_handler
5091da177e4SLinus Torvaldsfpd_trap_handler:
5101da177e4SLinus Torvalds	SAVE_ALL
5111da177e4SLinus Torvalds
5121da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr		! re-enable traps
5131da177e4SLinus Torvalds	WRITE_PAUSE
5141da177e4SLinus Torvalds
5151da177e4SLinus Torvalds	add	%sp, STACKFRAME_SZ, %o0
5161da177e4SLinus Torvalds	mov	%l1, %o1
5171da177e4SLinus Torvalds	mov	%l2, %o2
5181da177e4SLinus Torvalds	call	do_fpd_trap
5191da177e4SLinus Torvalds	 mov	%l0, %o3
5201da177e4SLinus Torvalds
5211da177e4SLinus Torvalds	RESTORE_ALL
5221da177e4SLinus Torvalds
5231da177e4SLinus Torvalds	/* This routine handles Floating Point Exceptions. */
5241da177e4SLinus Torvalds	.align	4
5251da177e4SLinus Torvalds	.globl	fpe_trap_handler
5261da177e4SLinus Torvaldsfpe_trap_handler:
5271da177e4SLinus Torvalds	set	fpsave_magic, %l5
5281da177e4SLinus Torvalds	cmp	%l1, %l5
5291da177e4SLinus Torvalds	be	1f
5301da177e4SLinus Torvalds	 sethi	%hi(fpsave), %l5
5311da177e4SLinus Torvalds	or	%l5, %lo(fpsave), %l5
5321da177e4SLinus Torvalds	cmp	%l1, %l5
5331da177e4SLinus Torvalds	bne	2f
5341da177e4SLinus Torvalds	 sethi	%hi(fpsave_catch2), %l5
5351da177e4SLinus Torvalds	or	%l5, %lo(fpsave_catch2), %l5
5361da177e4SLinus Torvalds	wr	%l0, 0x0, %psr
5371da177e4SLinus Torvalds	WRITE_PAUSE
5381da177e4SLinus Torvalds	jmp	%l5
5391da177e4SLinus Torvalds	 rett	%l5 + 4
5401da177e4SLinus Torvalds1:
5411da177e4SLinus Torvalds	sethi	%hi(fpsave_catch), %l5
5421da177e4SLinus Torvalds	or	%l5, %lo(fpsave_catch), %l5
5431da177e4SLinus Torvalds	wr	%l0, 0x0, %psr
5441da177e4SLinus Torvalds	WRITE_PAUSE
5451da177e4SLinus Torvalds	jmp	%l5
5461da177e4SLinus Torvalds	 rett	%l5 + 4
5471da177e4SLinus Torvalds
5481da177e4SLinus Torvalds2:
5491da177e4SLinus Torvalds	SAVE_ALL
5501da177e4SLinus Torvalds
5511da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr		! re-enable traps
5521da177e4SLinus Torvalds	WRITE_PAUSE
5531da177e4SLinus Torvalds
5541da177e4SLinus Torvalds	add	%sp, STACKFRAME_SZ, %o0
5551da177e4SLinus Torvalds	mov	%l1, %o1
5561da177e4SLinus Torvalds	mov	%l2, %o2
5571da177e4SLinus Torvalds	call	do_fpe_trap
5581da177e4SLinus Torvalds	 mov	%l0, %o3
5591da177e4SLinus Torvalds
5601da177e4SLinus Torvalds	RESTORE_ALL
5611da177e4SLinus Torvalds
5621da177e4SLinus Torvalds	/* This routine handles Tag Overflow Exceptions. */
5631da177e4SLinus Torvalds	.align	4
5641da177e4SLinus Torvalds	.globl	do_tag_overflow
5651da177e4SLinus Torvaldsdo_tag_overflow:
5661da177e4SLinus Torvalds	SAVE_ALL
5671da177e4SLinus Torvalds
5681da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr		! re-enable traps
5691da177e4SLinus Torvalds	WRITE_PAUSE
5701da177e4SLinus Torvalds
5711da177e4SLinus Torvalds	add	%sp, STACKFRAME_SZ, %o0
5721da177e4SLinus Torvalds	mov	%l1, %o1
5731da177e4SLinus Torvalds	mov	%l2, %o2
5741da177e4SLinus Torvalds	call	handle_tag_overflow
5751da177e4SLinus Torvalds	 mov	%l0, %o3
5761da177e4SLinus Torvalds
5771da177e4SLinus Torvalds	RESTORE_ALL
5781da177e4SLinus Torvalds
5791da177e4SLinus Torvalds	/* This routine handles Watchpoint Exceptions. */
5801da177e4SLinus Torvalds	.align	4
5811da177e4SLinus Torvalds	.globl	do_watchpoint
5821da177e4SLinus Torvaldsdo_watchpoint:
5831da177e4SLinus Torvalds	SAVE_ALL
5841da177e4SLinus Torvalds
5851da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr		! re-enable traps
5861da177e4SLinus Torvalds	WRITE_PAUSE
5871da177e4SLinus Torvalds
5881da177e4SLinus Torvalds	add	%sp, STACKFRAME_SZ, %o0
5891da177e4SLinus Torvalds	mov	%l1, %o1
5901da177e4SLinus Torvalds	mov	%l2, %o2
5911da177e4SLinus Torvalds	call	handle_watchpoint
5921da177e4SLinus Torvalds	 mov	%l0, %o3
5931da177e4SLinus Torvalds
5941da177e4SLinus Torvalds	RESTORE_ALL
5951da177e4SLinus Torvalds
5961da177e4SLinus Torvalds	/* This routine handles Register Access Exceptions. */
5971da177e4SLinus Torvalds	.align	4
5981da177e4SLinus Torvalds	.globl	do_reg_access
5991da177e4SLinus Torvaldsdo_reg_access:
6001da177e4SLinus Torvalds	SAVE_ALL
6011da177e4SLinus Torvalds
6021da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr		! re-enable traps
6031da177e4SLinus Torvalds	WRITE_PAUSE
6041da177e4SLinus Torvalds
6051da177e4SLinus Torvalds	add	%sp, STACKFRAME_SZ, %o0
6061da177e4SLinus Torvalds	mov	%l1, %o1
6071da177e4SLinus Torvalds	mov	%l2, %o2
6081da177e4SLinus Torvalds	call	handle_reg_access
6091da177e4SLinus Torvalds	 mov	%l0, %o3
6101da177e4SLinus Torvalds
6111da177e4SLinus Torvalds	RESTORE_ALL
6121da177e4SLinus Torvalds
6131da177e4SLinus Torvalds	/* This routine handles Co-Processor Disabled Exceptions. */
6141da177e4SLinus Torvalds	.align	4
6151da177e4SLinus Torvalds	.globl	do_cp_disabled
6161da177e4SLinus Torvaldsdo_cp_disabled:
6171da177e4SLinus Torvalds	SAVE_ALL
6181da177e4SLinus Torvalds
6191da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr		! re-enable traps
6201da177e4SLinus Torvalds	WRITE_PAUSE
6211da177e4SLinus Torvalds
6221da177e4SLinus Torvalds	add	%sp, STACKFRAME_SZ, %o0
6231da177e4SLinus Torvalds	mov	%l1, %o1
6241da177e4SLinus Torvalds	mov	%l2, %o2
6251da177e4SLinus Torvalds	call	handle_cp_disabled
6261da177e4SLinus Torvalds	 mov	%l0, %o3
6271da177e4SLinus Torvalds
6281da177e4SLinus Torvalds	RESTORE_ALL
6291da177e4SLinus Torvalds
6301da177e4SLinus Torvalds	/* This routine handles Co-Processor Exceptions. */
6311da177e4SLinus Torvalds	.align	4
6321da177e4SLinus Torvalds	.globl	do_cp_exception
6331da177e4SLinus Torvaldsdo_cp_exception:
6341da177e4SLinus Torvalds	SAVE_ALL
6351da177e4SLinus Torvalds
6361da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr		! re-enable traps
6371da177e4SLinus Torvalds	WRITE_PAUSE
6381da177e4SLinus Torvalds
6391da177e4SLinus Torvalds	add	%sp, STACKFRAME_SZ, %o0
6401da177e4SLinus Torvalds	mov	%l1, %o1
6411da177e4SLinus Torvalds	mov	%l2, %o2
6421da177e4SLinus Torvalds	call	handle_cp_exception
6431da177e4SLinus Torvalds	 mov	%l0, %o3
6441da177e4SLinus Torvalds
6451da177e4SLinus Torvalds	RESTORE_ALL
6461da177e4SLinus Torvalds
6471da177e4SLinus Torvalds	/* This routine handles Hardware Divide By Zero Exceptions. */
6481da177e4SLinus Torvalds	.align	4
6491da177e4SLinus Torvalds	.globl	do_hw_divzero
6501da177e4SLinus Torvaldsdo_hw_divzero:
6511da177e4SLinus Torvalds	SAVE_ALL
6521da177e4SLinus Torvalds
6531da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr		! re-enable traps
6541da177e4SLinus Torvalds	WRITE_PAUSE
6551da177e4SLinus Torvalds
6561da177e4SLinus Torvalds	add	%sp, STACKFRAME_SZ, %o0
6571da177e4SLinus Torvalds	mov	%l1, %o1
6581da177e4SLinus Torvalds	mov	%l2, %o2
6591da177e4SLinus Torvalds	call	handle_hw_divzero
6601da177e4SLinus Torvalds	 mov	%l0, %o3
6611da177e4SLinus Torvalds
6621da177e4SLinus Torvalds	RESTORE_ALL
6631da177e4SLinus Torvalds
6641da177e4SLinus Torvalds	.align	4
6651da177e4SLinus Torvalds	.globl	do_flush_windows
6661da177e4SLinus Torvaldsdo_flush_windows:
6671da177e4SLinus Torvalds	SAVE_ALL
6681da177e4SLinus Torvalds
6691da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr
6701da177e4SLinus Torvalds	WRITE_PAUSE
6711da177e4SLinus Torvalds
6721da177e4SLinus Torvalds	andcc	%l0, PSR_PS, %g0
6731da177e4SLinus Torvalds	bne	dfw_kernel
6741da177e4SLinus Torvalds	 nop
6751da177e4SLinus Torvalds
6761da177e4SLinus Torvalds	call	flush_user_windows
6771da177e4SLinus Torvalds	 nop
6781da177e4SLinus Torvalds
6791da177e4SLinus Torvalds	/* Advance over the trap instruction. */
6801da177e4SLinus Torvalds	ld	[%sp + STACKFRAME_SZ + PT_NPC], %l1
6811da177e4SLinus Torvalds	add	%l1, 0x4, %l2
6821da177e4SLinus Torvalds	st	%l1, [%sp + STACKFRAME_SZ + PT_PC]
6831da177e4SLinus Torvalds	st	%l2, [%sp + STACKFRAME_SZ + PT_NPC]
6841da177e4SLinus Torvalds
6851da177e4SLinus Torvalds	RESTORE_ALL
6861da177e4SLinus Torvalds
6871da177e4SLinus Torvalds	.globl	flush_patch_one
6881da177e4SLinus Torvalds
6891da177e4SLinus Torvalds	/* We get these for debugging routines using __builtin_return_address() */
6901da177e4SLinus Torvaldsdfw_kernel:
6911da177e4SLinus Torvaldsflush_patch_one:
6921da177e4SLinus Torvalds	FLUSH_ALL_KERNEL_WINDOWS
6931da177e4SLinus Torvalds
6941da177e4SLinus Torvalds	/* Advance over the trap instruction. */
6951da177e4SLinus Torvalds	ld	[%sp + STACKFRAME_SZ + PT_NPC], %l1
6961da177e4SLinus Torvalds	add	%l1, 0x4, %l2
6971da177e4SLinus Torvalds	st	%l1, [%sp + STACKFRAME_SZ + PT_PC]
6981da177e4SLinus Torvalds	st	%l2, [%sp + STACKFRAME_SZ + PT_NPC]
6991da177e4SLinus Torvalds
7001da177e4SLinus Torvalds	RESTORE_ALL
7011da177e4SLinus Torvalds
7021da177e4SLinus Torvalds	/* The getcc software trap.  The user wants the condition codes from
7031da177e4SLinus Torvalds	 * the %psr in register %g1.
7041da177e4SLinus Torvalds	 */
7051da177e4SLinus Torvalds
7061da177e4SLinus Torvalds	.align	4
7071da177e4SLinus Torvalds	.globl	getcc_trap_handler
7081da177e4SLinus Torvaldsgetcc_trap_handler:
7091da177e4SLinus Torvalds	srl	%l0, 20, %g1	! give user
7101da177e4SLinus Torvalds	and	%g1, 0xf, %g1	! only ICC bits in %psr
7111da177e4SLinus Torvalds	jmp	%l2		! advance over trap instruction
7121da177e4SLinus Torvalds	rett	%l2 + 0x4	! like this...
7131da177e4SLinus Torvalds
7141da177e4SLinus Torvalds	/* The setcc software trap.  The user has condition codes in %g1
7151da177e4SLinus Torvalds	 * that it would like placed in the %psr.  Be careful not to flip
7161da177e4SLinus Torvalds	 * any unintentional bits!
7171da177e4SLinus Torvalds	 */
7181da177e4SLinus Torvalds
7191da177e4SLinus Torvalds	.align	4
7201da177e4SLinus Torvalds	.globl	setcc_trap_handler
7211da177e4SLinus Torvaldssetcc_trap_handler:
7221da177e4SLinus Torvalds	sll	%g1, 0x14, %l4
7231da177e4SLinus Torvalds	set	PSR_ICC, %l5
7241da177e4SLinus Torvalds	andn	%l0, %l5, %l0	! clear ICC bits in %psr
7251da177e4SLinus Torvalds	and	%l4, %l5, %l4	! clear non-ICC bits in user value
7261da177e4SLinus Torvalds	or	%l4, %l0, %l4	! or them in... mix mix mix
7271da177e4SLinus Torvalds
7281da177e4SLinus Torvalds	wr	%l4, 0x0, %psr	! set new %psr
7291da177e4SLinus Torvalds	WRITE_PAUSE		! TI scumbags...
7301da177e4SLinus Torvalds
7311da177e4SLinus Torvalds	jmp	%l2		! advance over trap instruction
7321da177e4SLinus Torvalds	rett	%l2 + 0x4	! like this...
7331da177e4SLinus Torvalds
73496061a91SDavid S. Millersun4m_nmi_error:
73596061a91SDavid S. Miller	/* NMI async memory error handling. */
73696061a91SDavid S. Miller	sethi	%hi(0x80000000), %l4
73796061a91SDavid S. Miller	sethi	%hi(sun4m_irq_global), %o5
73896061a91SDavid S. Miller	ld	[%o5 + %lo(sun4m_irq_global)], %l5
73996061a91SDavid S. Miller	st	%l4, [%l5 + 0x0c]	! sun4m_irq_global->mask_set=0x80000000
7401da177e4SLinus Torvalds	WRITE_PAUSE
74196061a91SDavid S. Miller	ld	[%l5 + 0x00], %g0	! sun4m_irq_global->pending
74296061a91SDavid S. Miller	WRITE_PAUSE
74396061a91SDavid S. Miller	or	%l0, PSR_PIL, %l4
74496061a91SDavid S. Miller	wr	%l4, 0x0, %psr
74596061a91SDavid S. Miller	WRITE_PAUSE
74696061a91SDavid S. Miller	wr	%l4, PSR_ET, %psr
74796061a91SDavid S. Miller	WRITE_PAUSE
74896061a91SDavid S. Miller	call	sun4m_nmi
74996061a91SDavid S. Miller	 nop
75096061a91SDavid S. Miller	st	%l4, [%l5 + 0x08]	! sun4m_irq_global->mask_clear=0x80000000
75196061a91SDavid S. Miller	WRITE_PAUSE
75296061a91SDavid S. Miller	ld	[%l5 + 0x00], %g0	! sun4m_irq_global->pending
75396061a91SDavid S. Miller	WRITE_PAUSE
7541da177e4SLinus Torvalds	RESTORE_ALL
7551da177e4SLinus Torvalds
75696061a91SDavid S. Miller#ifndef CONFIG_SMP
75796061a91SDavid S. Miller	.align	4
75896061a91SDavid S. Miller	.globl	linux_trap_ipi15_sun4m
75996061a91SDavid S. Millerlinux_trap_ipi15_sun4m:
76096061a91SDavid S. Miller	SAVE_ALL
76196061a91SDavid S. Miller
76296061a91SDavid S. Miller	ba	sun4m_nmi_error
76396061a91SDavid S. Miller	 nop
7642c1cfb2dSSam Ravnborg#endif /* CONFIG_SMP */
7652c1cfb2dSSam Ravnborg
7661da177e4SLinus Torvalds	.align	4
7671da177e4SLinus Torvalds	.globl	srmmu_fault
7681da177e4SLinus Torvaldssrmmu_fault:
7691da177e4SLinus Torvalds	mov	0x400, %l5
7701da177e4SLinus Torvalds	mov	0x300, %l4
7711da177e4SLinus Torvalds
7721ec8cf62SSam RavnborgLEON_PI(lda	[%l5] ASI_LEON_MMUREGS, %l6)	! read sfar first
7731ec8cf62SSam RavnborgSUN_PI_(lda	[%l5] ASI_M_MMUREGS, %l6)	! read sfar first
7741ec8cf62SSam Ravnborg
7751ec8cf62SSam RavnborgLEON_PI(lda	[%l4] ASI_LEON_MMUREGS, %l5)	! read sfsr last
7761ec8cf62SSam RavnborgSUN_PI_(lda	[%l4] ASI_M_MMUREGS, %l5)	! read sfsr last
7771da177e4SLinus Torvalds
7781da177e4SLinus Torvalds	andn	%l6, 0xfff, %l6
7791da177e4SLinus Torvalds	srl	%l5, 6, %l5			! and encode all info into l7
7801da177e4SLinus Torvalds
7811da177e4SLinus Torvalds	and	%l5, 2, %l5
7821da177e4SLinus Torvalds	or	%l5, %l6, %l6
7831da177e4SLinus Torvalds
7841da177e4SLinus Torvalds	or	%l6, %l7, %l7			! l7 = [addr,write,txtfault]
7851da177e4SLinus Torvalds
7861da177e4SLinus Torvalds	SAVE_ALL
7871da177e4SLinus Torvalds
7881da177e4SLinus Torvalds	mov	%l7, %o1
7891da177e4SLinus Torvalds	mov	%l7, %o2
7901da177e4SLinus Torvalds	and	%o1, 1, %o1		! arg2 = text_faultp
7911da177e4SLinus Torvalds	mov	%l7, %o3
7921da177e4SLinus Torvalds	and	%o2, 2, %o2		! arg3 = writep
7931da177e4SLinus Torvalds	andn	%o3, 0xfff, %o3		! arg4 = faulting address
7941da177e4SLinus Torvalds
7951da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr
7961da177e4SLinus Torvalds	WRITE_PAUSE
7971da177e4SLinus Torvalds
7981da177e4SLinus Torvalds	call	do_sparc_fault
7991da177e4SLinus Torvalds	 add	%sp, STACKFRAME_SZ, %o0	! arg1 = pt_regs ptr
8001da177e4SLinus Torvalds
8011da177e4SLinus Torvalds	RESTORE_ALL
8021da177e4SLinus Torvalds
8031da177e4SLinus Torvalds	.align	4
804ec98c6b9SDavid S. Millersunos_execv:
805f7200d4cSAl Viro	.globl	sunos_execv
806f7200d4cSAl Viro	b	sys_execve
807f7200d4cSAl Viro	 clr	%i2
808ec98c6b9SDavid S. Miller
8091da177e4SLinus Torvalds	.align	4
8101da177e4SLinus Torvalds	.globl	sys_sigstack
8111da177e4SLinus Torvaldssys_sigstack:
8121da177e4SLinus Torvalds	mov	%o7, %l5
8131da177e4SLinus Torvalds	mov	%fp, %o2
8141da177e4SLinus Torvalds	call	do_sys_sigstack
8151da177e4SLinus Torvalds	 mov	%l5, %o7
8161da177e4SLinus Torvalds
8171da177e4SLinus Torvalds	.align	4
8181da177e4SLinus Torvalds	.globl	sys_sigreturn
8191da177e4SLinus Torvaldssys_sigreturn:
8201da177e4SLinus Torvalds	call	do_sigreturn
8211da177e4SLinus Torvalds	 add	%sp, STACKFRAME_SZ, %o0
8221da177e4SLinus Torvalds
8231da177e4SLinus Torvalds	ld	[%curptr + TI_FLAGS], %l5
8241da177e4SLinus Torvalds	andcc	%l5, _TIF_SYSCALL_TRACE, %g0
8251da177e4SLinus Torvalds	be	1f
8261da177e4SLinus Torvalds	 nop
8271da177e4SLinus Torvalds
8281da177e4SLinus Torvalds	call	syscall_trace
8297a3b0f89SKirill Tkhai	 mov	1, %o1
8301da177e4SLinus Torvalds
8311da177e4SLinus Torvalds1:
8321da177e4SLinus Torvalds	/* We don't want to muck with user registers like a
8331da177e4SLinus Torvalds	 * normal syscall, just return.
8341da177e4SLinus Torvalds	 */
8351da177e4SLinus Torvalds	RESTORE_ALL
8361da177e4SLinus Torvalds
8371da177e4SLinus Torvalds	.align	4
8381da177e4SLinus Torvalds	.globl	sys_rt_sigreturn
8391da177e4SLinus Torvaldssys_rt_sigreturn:
8401da177e4SLinus Torvalds	call	do_rt_sigreturn
8411da177e4SLinus Torvalds	 add	%sp, STACKFRAME_SZ, %o0
8421da177e4SLinus Torvalds
8431da177e4SLinus Torvalds	ld	[%curptr + TI_FLAGS], %l5
8441da177e4SLinus Torvalds	andcc	%l5, _TIF_SYSCALL_TRACE, %g0
8451da177e4SLinus Torvalds	be	1f
8461da177e4SLinus Torvalds	 nop
8471da177e4SLinus Torvalds
8481c133b4bSDavid S. Miller	add	%sp, STACKFRAME_SZ, %o0
8491da177e4SLinus Torvalds	call	syscall_trace
8501c133b4bSDavid S. Miller	 mov	1, %o1
8511da177e4SLinus Torvalds
8521da177e4SLinus Torvalds1:
8531da177e4SLinus Torvalds	/* We are returning to a signal handler. */
8541da177e4SLinus Torvalds	RESTORE_ALL
8551da177e4SLinus Torvalds
8561da177e4SLinus Torvalds	/* Now that we have a real sys_clone, sys_fork() is
8571da177e4SLinus Torvalds	 * implemented in terms of it.  Our _real_ implementation
8581da177e4SLinus Torvalds	 * of SunOS vfork() will use sys_vfork().
8591da177e4SLinus Torvalds	 *
8601da177e4SLinus Torvalds	 * XXX These three should be consolidated into mostly shared
8611da177e4SLinus Torvalds	 * XXX code just like on sparc64... -DaveM
8621da177e4SLinus Torvalds	 */
8631da177e4SLinus Torvalds	.align	4
8641da177e4SLinus Torvalds	.globl	sys_fork, flush_patch_two
8651da177e4SLinus Torvaldssys_fork:
8661da177e4SLinus Torvalds	mov	%o7, %l5
8671da177e4SLinus Torvaldsflush_patch_two:
8681da177e4SLinus Torvalds	FLUSH_ALL_KERNEL_WINDOWS;
8691da177e4SLinus Torvalds	ld	[%curptr + TI_TASK], %o4
8701da177e4SLinus Torvalds	rd	%psr, %g4
8711da177e4SLinus Torvalds	WRITE_PAUSE
8721da177e4SLinus Torvalds	rd	%wim, %g5
8731da177e4SLinus Torvalds	WRITE_PAUSE
8741da177e4SLinus Torvalds	std	%g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
875a4261d4bSChristian Brauner	add	%sp, STACKFRAME_SZ, %o0
876a4261d4bSChristian Brauner	call	sparc_fork
8771da177e4SLinus Torvalds	 mov	%l5, %o7
8781da177e4SLinus Torvalds
8791da177e4SLinus Torvalds	/* Whee, kernel threads! */
8801da177e4SLinus Torvalds	.globl	sys_clone, flush_patch_three
8811da177e4SLinus Torvaldssys_clone:
8821da177e4SLinus Torvalds	mov	%o7, %l5
8831da177e4SLinus Torvaldsflush_patch_three:
8841da177e4SLinus Torvalds	FLUSH_ALL_KERNEL_WINDOWS;
8851da177e4SLinus Torvalds	ld	[%curptr + TI_TASK], %o4
8861da177e4SLinus Torvalds	rd	%psr, %g4
8871da177e4SLinus Torvalds	WRITE_PAUSE
8881da177e4SLinus Torvalds	rd	%wim, %g5
8891da177e4SLinus Torvalds	WRITE_PAUSE
8901da177e4SLinus Torvalds	std	%g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
891a4261d4bSChristian Brauner	add	%sp, STACKFRAME_SZ, %o0
892a4261d4bSChristian Brauner	call	sparc_clone
8931da177e4SLinus Torvalds	 mov	%l5, %o7
8941da177e4SLinus Torvalds
8951da177e4SLinus Torvalds	/* Whee, real vfork! */
8961da177e4SLinus Torvalds	.globl	sys_vfork, flush_patch_four
8971da177e4SLinus Torvaldssys_vfork:
8981da177e4SLinus Torvaldsflush_patch_four:
8991da177e4SLinus Torvalds	FLUSH_ALL_KERNEL_WINDOWS;
9001da177e4SLinus Torvalds	ld	[%curptr + TI_TASK], %o4
9011da177e4SLinus Torvalds	rd	%psr, %g4
9021da177e4SLinus Torvalds	WRITE_PAUSE
9031da177e4SLinus Torvalds	rd	%wim, %g5
9041da177e4SLinus Torvalds	WRITE_PAUSE
9051da177e4SLinus Torvalds	std	%g4, [%o4 + AOFF_task_thread + AOFF_thread_fork_kpsr]
906a4261d4bSChristian Brauner	sethi	%hi(sparc_vfork), %l1
907a4261d4bSChristian Brauner	jmpl	%l1 + %lo(sparc_vfork), %g0
908a4261d4bSChristian Brauner	 add	%sp, STACKFRAME_SZ, %o0
9091da177e4SLinus Torvalds
9101da177e4SLinus Torvalds        .align  4
9111da177e4SLinus Torvaldslinux_sparc_ni_syscall:
9121da177e4SLinus Torvalds	sethi   %hi(sys_ni_syscall), %l7
91332942bc7SAl Viro	b       do_syscall
9141da177e4SLinus Torvalds	 or     %l7, %lo(sys_ni_syscall), %l7
9151da177e4SLinus Torvalds
9161da177e4SLinus Torvaldslinux_syscall_trace:
9171c133b4bSDavid S. Miller	add	%sp, STACKFRAME_SZ, %o0
9181da177e4SLinus Torvalds	call	syscall_trace
9191c133b4bSDavid S. Miller	 mov	0, %o1
9201c133b4bSDavid S. Miller	cmp	%o0, 0
9211c133b4bSDavid S. Miller	bne	3f
9221c133b4bSDavid S. Miller	 mov	-ENOSYS, %o0
9231a40b953SMike Frysinger
9241a40b953SMike Frysinger	/* Syscall tracing can modify the registers.  */
9251a40b953SMike Frysinger	ld	[%sp + STACKFRAME_SZ + PT_G1], %g1
9261a40b953SMike Frysinger	sethi	%hi(sys_call_table), %l7
9271a40b953SMike Frysinger	ld	[%sp + STACKFRAME_SZ + PT_I0], %i0
9281a40b953SMike Frysinger	or	%l7, %lo(sys_call_table), %l7
9291a40b953SMike Frysinger	ld	[%sp + STACKFRAME_SZ + PT_I1], %i1
9301a40b953SMike Frysinger	ld	[%sp + STACKFRAME_SZ + PT_I2], %i2
9311a40b953SMike Frysinger	ld	[%sp + STACKFRAME_SZ + PT_I3], %i3
9321a40b953SMike Frysinger	ld	[%sp + STACKFRAME_SZ + PT_I4], %i4
9331a40b953SMike Frysinger	ld	[%sp + STACKFRAME_SZ + PT_I5], %i5
9341a40b953SMike Frysinger	cmp	%g1, NR_syscalls
9351a40b953SMike Frysinger	bgeu	3f
9361a40b953SMike Frysinger	 mov	-ENOSYS, %o0
9371a40b953SMike Frysinger
9381a40b953SMike Frysinger	sll	%g1, 2, %l4
9391da177e4SLinus Torvalds	mov	%i0, %o0
9401a40b953SMike Frysinger	ld	[%l7 + %l4], %l7
9411da177e4SLinus Torvalds	mov	%i1, %o1
9421da177e4SLinus Torvalds	mov	%i2, %o2
9431da177e4SLinus Torvalds	mov	%i3, %o3
9441da177e4SLinus Torvalds	b	2f
9451da177e4SLinus Torvalds	 mov	%i4, %o4
9461da177e4SLinus Torvalds
9471da177e4SLinus Torvalds	.globl	ret_from_fork
9481da177e4SLinus Torvaldsret_from_fork:
9491da177e4SLinus Torvalds	call	schedule_tail
95047c7c97aSTkhai Kirill	 ld	[%g3 + TI_TASK], %o0
9511da177e4SLinus Torvalds	b	ret_sys_call
9521da177e4SLinus Torvalds	 ld	[%sp + STACKFRAME_SZ + PT_I0], %o0
9531da177e4SLinus Torvalds
954c78e0643SAl Viro	.globl	ret_from_kernel_thread
955c78e0643SAl Viroret_from_kernel_thread:
956c78e0643SAl Viro	call	schedule_tail
957c78e0643SAl Viro	 ld	[%g3 + TI_TASK], %o0
958c78e0643SAl Viro	ld	[%sp + STACKFRAME_SZ + PT_G1], %l0
959c78e0643SAl Viro	call	%l0
960c78e0643SAl Viro	 ld	[%sp + STACKFRAME_SZ + PT_G2], %o0
961ab348681SAl Viro	rd	%psr, %l1
962ab348681SAl Viro	ld	[%sp + STACKFRAME_SZ + PT_PSR], %l0
963ab348681SAl Viro	andn	%l0, PSR_CWP, %l0
964ab348681SAl Viro	nop
965ab348681SAl Viro	and	%l1, PSR_CWP, %l1
966ab348681SAl Viro	or	%l0, %l1, %l0
967ab348681SAl Viro	st	%l0, [%sp + STACKFRAME_SZ + PT_PSR]
968ab348681SAl Viro	b	ret_sys_call
969ab348681SAl Viro	 mov	0, %o0
970c78e0643SAl Viro
971ec98c6b9SDavid S. Miller	/* Linux native system calls enter here... */
9721da177e4SLinus Torvalds	.align	4
9731da177e4SLinus Torvalds	.globl	linux_sparc_syscall
9741da177e4SLinus Torvaldslinux_sparc_syscall:
97528e61036SDavid S. Miller	sethi	%hi(PSR_SYSCALL), %l4
97628e61036SDavid S. Miller	or	%l0, %l4, %l0
9771da177e4SLinus Torvalds	/* Direct access to user regs, must faster. */
978c658ad1bSDavid S. Miller	cmp	%g1, NR_syscalls
9791da177e4SLinus Torvalds	bgeu	linux_sparc_ni_syscall
9801da177e4SLinus Torvalds	 sll	%g1, 2, %l4
9811da177e4SLinus Torvalds	ld	[%l7 + %l4], %l7
9821da177e4SLinus Torvalds
98332942bc7SAl Virodo_syscall:
9841da177e4SLinus Torvalds	SAVE_ALL_HEAD
9851da177e4SLinus Torvalds	 rd	%wim, %l3
9861da177e4SLinus Torvalds
9871da177e4SLinus Torvalds	wr	%l0, PSR_ET, %psr
9881da177e4SLinus Torvalds	mov	%i0, %o0
9891da177e4SLinus Torvalds	mov	%i1, %o1
9901da177e4SLinus Torvalds	mov	%i2, %o2
9911da177e4SLinus Torvalds
9921da177e4SLinus Torvalds	ld	[%curptr + TI_FLAGS], %l5
9931da177e4SLinus Torvalds	mov	%i3, %o3
9941da177e4SLinus Torvalds	andcc	%l5, _TIF_SYSCALL_TRACE, %g0
9951da177e4SLinus Torvalds	mov	%i4, %o4
9961da177e4SLinus Torvalds	bne	linux_syscall_trace
997c599a782SAndreas Larsson	 mov	%i0, %l6
9981da177e4SLinus Torvalds2:
9991da177e4SLinus Torvalds	call	%l7
10001da177e4SLinus Torvalds	 mov	%i5, %o5
10011da177e4SLinus Torvalds
10021c133b4bSDavid S. Miller3:
10031da177e4SLinus Torvalds	st	%o0, [%sp + STACKFRAME_SZ + PT_I0]
10041da177e4SLinus Torvalds
10051da177e4SLinus Torvaldsret_sys_call:
1006c599a782SAndreas Larsson	ld	[%curptr + TI_FLAGS], %l5
10071da177e4SLinus Torvalds	cmp	%o0, -ERESTART_RESTARTBLOCK
10081da177e4SLinus Torvalds	ld	[%sp + STACKFRAME_SZ + PT_PSR], %g3
10091da177e4SLinus Torvalds	set	PSR_C, %g2
10101da177e4SLinus Torvalds	bgeu	1f
1011c599a782SAndreas Larsson	 andcc	%l5, _TIF_SYSCALL_TRACE, %g0
10121da177e4SLinus Torvalds
10131da177e4SLinus Torvalds	/* System call success, clear Carry condition code. */
10141da177e4SLinus Torvalds	andn	%g3, %g2, %g3
10151da177e4SLinus Torvalds	st	%g3, [%sp + STACKFRAME_SZ + PT_PSR]
10161da177e4SLinus Torvalds	bne	linux_syscall_trace2
10171da177e4SLinus Torvalds	 ld	[%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */
10181da177e4SLinus Torvalds	add	%l1, 0x4, %l2			/* npc = npc+4 */
10191da177e4SLinus Torvalds	st	%l1, [%sp + STACKFRAME_SZ + PT_PC]
10201da177e4SLinus Torvalds	b	ret_trap_entry
10211da177e4SLinus Torvalds	 st	%l2, [%sp + STACKFRAME_SZ + PT_NPC]
10221da177e4SLinus Torvalds1:
10231da177e4SLinus Torvalds	/* System call failure, set Carry condition code.
10241da177e4SLinus Torvalds	 * Also, get abs(errno) to return to the process.
10251da177e4SLinus Torvalds	 */
10261da177e4SLinus Torvalds	sub	%g0, %o0, %o0
10271da177e4SLinus Torvalds	or	%g3, %g2, %g3
10281da177e4SLinus Torvalds	st	%o0, [%sp + STACKFRAME_SZ + PT_I0]
10291da177e4SLinus Torvalds	st	%g3, [%sp + STACKFRAME_SZ + PT_PSR]
10301da177e4SLinus Torvalds	bne	linux_syscall_trace2
10311da177e4SLinus Torvalds	 ld	[%sp + STACKFRAME_SZ + PT_NPC], %l1 /* pc = npc */
10321da177e4SLinus Torvalds	add	%l1, 0x4, %l2			/* npc = npc+4 */
10331da177e4SLinus Torvalds	st	%l1, [%sp + STACKFRAME_SZ + PT_PC]
10341da177e4SLinus Torvalds	b	ret_trap_entry
10351da177e4SLinus Torvalds	 st	%l2, [%sp + STACKFRAME_SZ + PT_NPC]
10361da177e4SLinus Torvalds
10371da177e4SLinus Torvaldslinux_syscall_trace2:
10381c133b4bSDavid S. Miller	add	%sp, STACKFRAME_SZ, %o0
10391c133b4bSDavid S. Miller	mov	1, %o1
10401da177e4SLinus Torvalds	call	syscall_trace
10411da177e4SLinus Torvalds	 add	%l1, 0x4, %l2			/* npc = npc+4 */
10421da177e4SLinus Torvalds	st	%l1, [%sp + STACKFRAME_SZ + PT_PC]
10431da177e4SLinus Torvalds	b	ret_trap_entry
10441da177e4SLinus Torvalds	 st	%l2, [%sp + STACKFRAME_SZ + PT_NPC]
10451da177e4SLinus Torvalds
10461da177e4SLinus Torvalds
10471da177e4SLinus Torvalds/* Saving and restoring the FPU state is best done from lowlevel code.
10481da177e4SLinus Torvalds *
10491da177e4SLinus Torvalds * void fpsave(unsigned long *fpregs, unsigned long *fsr,
10501da177e4SLinus Torvalds *             void *fpqueue, unsigned long *fpqdepth)
10511da177e4SLinus Torvalds */
10521da177e4SLinus Torvalds
10531da177e4SLinus Torvalds	.globl	fpsave
10541da177e4SLinus Torvaldsfpsave:
10551da177e4SLinus Torvalds	st	%fsr, [%o1]	! this can trap on us if fpu is in bogon state
10561da177e4SLinus Torvalds	ld	[%o1], %g1
10571da177e4SLinus Torvalds	set	0x2000, %g4
10581da177e4SLinus Torvalds	andcc	%g1, %g4, %g0
10591da177e4SLinus Torvalds	be	2f
10601da177e4SLinus Torvalds	 mov	0, %g2
10611da177e4SLinus Torvalds
10621da177e4SLinus Torvalds	/* We have an fpqueue to save. */
10631da177e4SLinus Torvalds1:
10641da177e4SLinus Torvalds	std	%fq, [%o2]
10651da177e4SLinus Torvaldsfpsave_magic:
10661da177e4SLinus Torvalds	st	%fsr, [%o1]
10671da177e4SLinus Torvalds	ld	[%o1], %g3
10681da177e4SLinus Torvalds	andcc	%g3, %g4, %g0
10691da177e4SLinus Torvalds	add	%g2, 1, %g2
10701da177e4SLinus Torvalds	bne	1b
10711da177e4SLinus Torvalds	 add	%o2, 8, %o2
10721da177e4SLinus Torvalds
10731da177e4SLinus Torvalds2:
10741da177e4SLinus Torvalds	st	%g2, [%o3]
10751da177e4SLinus Torvalds
10761da177e4SLinus Torvalds	std	%f0, [%o0 + 0x00]
10771da177e4SLinus Torvalds	std	%f2, [%o0 + 0x08]
10781da177e4SLinus Torvalds	std	%f4, [%o0 + 0x10]
10791da177e4SLinus Torvalds	std	%f6, [%o0 + 0x18]
10801da177e4SLinus Torvalds	std	%f8, [%o0 + 0x20]
10811da177e4SLinus Torvalds	std	%f10, [%o0 + 0x28]
10821da177e4SLinus Torvalds	std	%f12, [%o0 + 0x30]
10831da177e4SLinus Torvalds	std	%f14, [%o0 + 0x38]
10841da177e4SLinus Torvalds	std	%f16, [%o0 + 0x40]
10851da177e4SLinus Torvalds	std	%f18, [%o0 + 0x48]
10861da177e4SLinus Torvalds	std	%f20, [%o0 + 0x50]
10871da177e4SLinus Torvalds	std	%f22, [%o0 + 0x58]
10881da177e4SLinus Torvalds	std	%f24, [%o0 + 0x60]
10891da177e4SLinus Torvalds	std	%f26, [%o0 + 0x68]
10901da177e4SLinus Torvalds	std	%f28, [%o0 + 0x70]
10911da177e4SLinus Torvalds	retl
10921da177e4SLinus Torvalds	 std	%f30, [%o0 + 0x78]
10931da177e4SLinus Torvalds
10941da177e4SLinus Torvalds	/* Thanks for Theo Deraadt and the authors of the Sprite/netbsd/openbsd
10951da177e4SLinus Torvalds	 * code for pointing out this possible deadlock, while we save state
10961da177e4SLinus Torvalds	 * above we could trap on the fsr store so our low level fpu trap
10971da177e4SLinus Torvalds	 * code has to know how to deal with this.
10981da177e4SLinus Torvalds	 */
10991da177e4SLinus Torvaldsfpsave_catch:
11001da177e4SLinus Torvalds	b	fpsave_magic + 4
11011da177e4SLinus Torvalds	 st	%fsr, [%o1]
11021da177e4SLinus Torvalds
11031da177e4SLinus Torvaldsfpsave_catch2:
11041da177e4SLinus Torvalds	b	fpsave + 4
11051da177e4SLinus Torvalds	 st	%fsr, [%o1]
11061da177e4SLinus Torvalds
11071da177e4SLinus Torvalds	/* void fpload(unsigned long *fpregs, unsigned long *fsr); */
11081da177e4SLinus Torvalds
11091da177e4SLinus Torvalds	.globl	fpload
11101da177e4SLinus Torvaldsfpload:
11111da177e4SLinus Torvalds	ldd	[%o0 + 0x00], %f0
11121da177e4SLinus Torvalds	ldd	[%o0 + 0x08], %f2
11131da177e4SLinus Torvalds	ldd	[%o0 + 0x10], %f4
11141da177e4SLinus Torvalds	ldd	[%o0 + 0x18], %f6
11151da177e4SLinus Torvalds	ldd	[%o0 + 0x20], %f8
11161da177e4SLinus Torvalds	ldd	[%o0 + 0x28], %f10
11171da177e4SLinus Torvalds	ldd	[%o0 + 0x30], %f12
11181da177e4SLinus Torvalds	ldd	[%o0 + 0x38], %f14
11191da177e4SLinus Torvalds	ldd	[%o0 + 0x40], %f16
11201da177e4SLinus Torvalds	ldd	[%o0 + 0x48], %f18
11211da177e4SLinus Torvalds	ldd	[%o0 + 0x50], %f20
11221da177e4SLinus Torvalds	ldd	[%o0 + 0x58], %f22
11231da177e4SLinus Torvalds	ldd	[%o0 + 0x60], %f24
11241da177e4SLinus Torvalds	ldd	[%o0 + 0x68], %f26
11251da177e4SLinus Torvalds	ldd	[%o0 + 0x70], %f28
11261da177e4SLinus Torvalds	ldd	[%o0 + 0x78], %f30
11271da177e4SLinus Torvalds	ld	[%o1], %fsr
11281da177e4SLinus Torvalds	retl
11291da177e4SLinus Torvalds	 nop
11301da177e4SLinus Torvalds
11311da177e4SLinus Torvalds	/* __ndelay and __udelay take two arguments:
11321da177e4SLinus Torvalds	 * 0 - nsecs or usecs to delay
11331da177e4SLinus Torvalds	 * 1 - per_cpu udelay_val (loops per jiffy)
11341da177e4SLinus Torvalds	 *
11351da177e4SLinus Torvalds	 * Note that ndelay gives HZ times higher resolution but has a 10ms
11361da177e4SLinus Torvalds	 * limit.  udelay can handle up to 1s.
11371da177e4SLinus Torvalds	 */
11381da177e4SLinus Torvalds	.globl	__ndelay
11391da177e4SLinus Torvalds__ndelay:
11401da177e4SLinus Torvalds	save	%sp, -STACKFRAME_SZ, %sp
11411b35a57bSDavid S. Miller	mov	%i0, %o0		! round multiplier up so large ns ok
1142196bffa5SMark Fortescue	mov	0x1ae, %o1		! 2**32 / (1 000 000 000 / HZ)
11431b35a57bSDavid S. Miller	umul	%o0, %o1, %o0
11441b35a57bSDavid S. Miller	rd	%y, %o1
11451da177e4SLinus Torvalds	mov	%i1, %o1		! udelay_val
11461b35a57bSDavid S. Miller	umul	%o0, %o1, %o0
11471b35a57bSDavid S. Miller	rd	%y, %o1
11481da177e4SLinus Torvalds	ba	delay_continue
11491da177e4SLinus Torvalds	 mov	%o1, %o0		! >>32 later for better resolution
11501da177e4SLinus Torvalds
11511da177e4SLinus Torvalds	.globl	__udelay
11521da177e4SLinus Torvalds__udelay:
11531da177e4SLinus Torvalds	save	%sp, -STACKFRAME_SZ, %sp
11541da177e4SLinus Torvalds	mov	%i0, %o0
1155196bffa5SMark Fortescue	sethi	%hi(0x10c7), %o1	! round multiplier up so large us ok
1156196bffa5SMark Fortescue	or	%o1, %lo(0x10c7), %o1	! 2**32 / 1 000 000
11571b35a57bSDavid S. Miller	umul	%o0, %o1, %o0
11581b35a57bSDavid S. Miller	rd	%y, %o1
11591da177e4SLinus Torvalds	mov	%i1, %o1		! udelay_val
11601b35a57bSDavid S. Miller	umul	%o0, %o1, %o0
11611b35a57bSDavid S. Miller	rd	%y, %o1
1162196bffa5SMark Fortescue	sethi	%hi(0x028f4b62), %l0	! Add in rounding constant * 2**32,
1163196bffa5SMark Fortescue	or	%g0, %lo(0x028f4b62), %l0
1164196bffa5SMark Fortescue	addcc	%o0, %l0, %o0		! 2**32 * 0.009 999
1165196bffa5SMark Fortescue	bcs,a	3f
1166196bffa5SMark Fortescue	 add	%o1, 0x01, %o1
1167196bffa5SMark Fortescue3:
11681da177e4SLinus Torvalds	mov	HZ, %o0			! >>32 earlier for wider range
11691b35a57bSDavid S. Miller	umul	%o0, %o1, %o0
11701b35a57bSDavid S. Miller	rd	%y, %o1
11711da177e4SLinus Torvalds
11721da177e4SLinus Torvaldsdelay_continue:
11731da177e4SLinus Torvalds	cmp	%o0, 0x0
11741da177e4SLinus Torvalds1:
11751da177e4SLinus Torvalds	bne	1b
11761da177e4SLinus Torvalds	 subcc	%o0, 1, %o0
11771da177e4SLinus Torvalds
11781da177e4SLinus Torvalds	ret
11791da177e4SLinus Torvalds	restore
1180d3867f04SAl ViroEXPORT_SYMBOL(__udelay)
1181d3867f04SAl ViroEXPORT_SYMBOL(__ndelay)
11821da177e4SLinus Torvalds
11831da177e4SLinus Torvalds	/* Handle a software breakpoint */
11841da177e4SLinus Torvalds	/* We have to inform parent that child has stopped */
11851da177e4SLinus Torvalds	.align 4
11861da177e4SLinus Torvalds	.globl breakpoint_trap
11871da177e4SLinus Torvaldsbreakpoint_trap:
11881da177e4SLinus Torvalds	rd	%wim,%l3
11891da177e4SLinus Torvalds	SAVE_ALL
11901da177e4SLinus Torvalds	wr 	%l0, PSR_ET, %psr
11911da177e4SLinus Torvalds	WRITE_PAUSE
11921da177e4SLinus Torvalds
11931da177e4SLinus Torvalds	st	%i0, [%sp + STACKFRAME_SZ + PT_G0] ! for restarting syscalls
11941da177e4SLinus Torvalds	call	sparc_breakpoint
11951da177e4SLinus Torvalds	 add	%sp, STACKFRAME_SZ, %o0
11961da177e4SLinus Torvalds
11971da177e4SLinus Torvalds	RESTORE_ALL
11981da177e4SLinus Torvalds
1199e2fdd7fdSDavid S. Miller#ifdef CONFIG_KGDB
1200d097efa9SSam Ravnborg	ENTRY(kgdb_trap_low)
1201e2fdd7fdSDavid S. Miller	rd	%wim,%l3
1202e2fdd7fdSDavid S. Miller	SAVE_ALL
1203e2fdd7fdSDavid S. Miller	wr 	%l0, PSR_ET, %psr
1204e2fdd7fdSDavid S. Miller	WRITE_PAUSE
1205e2fdd7fdSDavid S. Miller
1206d097efa9SSam Ravnborg	mov	%l7, %o0		! trap_level
1207e2fdd7fdSDavid S. Miller	call	kgdb_trap
1208d097efa9SSam Ravnborg	 add	%sp, STACKFRAME_SZ, %o1	! struct pt_regs *regs
1209e2fdd7fdSDavid S. Miller
1210e2fdd7fdSDavid S. Miller	RESTORE_ALL
1211d097efa9SSam Ravnborg	ENDPROC(kgdb_trap_low)
1212e2fdd7fdSDavid S. Miller#endif
1213e2fdd7fdSDavid S. Miller
12141da177e4SLinus Torvalds	.align	4
1215c61c65cdSAdrian Bunk	.globl	flush_patch_exception
12161da177e4SLinus Torvaldsflush_patch_exception:
12171da177e4SLinus Torvalds	FLUSH_ALL_KERNEL_WINDOWS;
12181da177e4SLinus Torvalds	ldd	[%o0], %o6
12191da177e4SLinus Torvalds	jmpl	%o7 + 0xc, %g0			! see asm-sparc/processor.h
12201da177e4SLinus Torvalds	 mov	1, %g1				! signal EFAULT condition
12211da177e4SLinus Torvalds
12221da177e4SLinus Torvalds	.align	4
12231da177e4SLinus Torvalds	.globl	kill_user_windows, kuw_patch1_7win
12241da177e4SLinus Torvalds	.globl	kuw_patch1
12251da177e4SLinus Torvaldskuw_patch1_7win:	sll	%o3, 6, %o3
12261da177e4SLinus Torvalds
12271da177e4SLinus Torvalds	/* No matter how much overhead this routine has in the worst
122808f80073SAdam Buchbinder	 * case scenario, it is several times better than taking the
12291da177e4SLinus Torvalds	 * traps with the old method of just doing flush_user_windows().
12301da177e4SLinus Torvalds	 */
12311da177e4SLinus Torvaldskill_user_windows:
12321da177e4SLinus Torvalds	ld	[%g6 + TI_UWINMASK], %o0	! get current umask
12331da177e4SLinus Torvalds	orcc	%g0, %o0, %g0			! if no bits set, we are done
12341da177e4SLinus Torvalds	be	3f				! nothing to do
12351da177e4SLinus Torvalds	 rd	%psr, %o5			! must clear interrupts
12361da177e4SLinus Torvalds	or	%o5, PSR_PIL, %o4		! or else that could change
12371da177e4SLinus Torvalds	wr	%o4, 0x0, %psr			! the uwinmask state
12381da177e4SLinus Torvalds	WRITE_PAUSE				! burn them cycles
12391da177e4SLinus Torvalds1:
12401da177e4SLinus Torvalds	ld	[%g6 + TI_UWINMASK], %o0	! get consistent state
12411da177e4SLinus Torvalds	orcc	%g0, %o0, %g0			! did an interrupt come in?
12421da177e4SLinus Torvalds	be	4f				! yep, we are done
12431da177e4SLinus Torvalds	 rd	%wim, %o3			! get current wim
12441da177e4SLinus Torvalds	srl	%o3, 1, %o4			! simulate a save
12451da177e4SLinus Torvaldskuw_patch1:
12461da177e4SLinus Torvalds	sll	%o3, 7, %o3			! compute next wim
12471da177e4SLinus Torvalds	or	%o4, %o3, %o3			! result
12481da177e4SLinus Torvalds	andncc	%o0, %o3, %o0			! clean this bit in umask
12491da177e4SLinus Torvalds	bne	kuw_patch1			! not done yet
12501da177e4SLinus Torvalds	 srl	%o3, 1, %o4			! begin another save simulation
12511da177e4SLinus Torvalds	wr	%o3, 0x0, %wim			! set the new wim
12521da177e4SLinus Torvalds	st	%g0, [%g6 + TI_UWINMASK]	! clear uwinmask
12531da177e4SLinus Torvalds4:
12541da177e4SLinus Torvalds	wr	%o5, 0x0, %psr			! re-enable interrupts
12551da177e4SLinus Torvalds	WRITE_PAUSE				! burn baby burn
12561da177e4SLinus Torvalds3:
12571da177e4SLinus Torvalds	retl					! return
12581da177e4SLinus Torvalds	 st	%g0, [%g6 + TI_W_SAVED]		! no windows saved
12591da177e4SLinus Torvalds
12601da177e4SLinus Torvalds	.align	4
12611da177e4SLinus Torvalds	.globl	restore_current
12621da177e4SLinus Torvaldsrestore_current:
12631da177e4SLinus Torvalds	LOAD_CURRENT(g6, o0)
12641da177e4SLinus Torvalds	retl
12651da177e4SLinus Torvalds	 nop
12661da177e4SLinus Torvalds
1267cfe3af5dSDaniel Hellstrom#ifdef CONFIG_PCIC_PCI
12681da177e4SLinus Torvalds#include <asm/pcic.h>
12691da177e4SLinus Torvalds
12701da177e4SLinus Torvalds	.align	4
12711da177e4SLinus Torvalds	.globl	linux_trap_ipi15_pcic
12721da177e4SLinus Torvaldslinux_trap_ipi15_pcic:
12731da177e4SLinus Torvalds	rd	%wim, %l3
12741da177e4SLinus Torvalds	SAVE_ALL
12751da177e4SLinus Torvalds
12761da177e4SLinus Torvalds	/*
12771da177e4SLinus Torvalds	 * First deactivate NMI
12781da177e4SLinus Torvalds	 * or we cannot drop ET, cannot get window spill traps.
12791da177e4SLinus Torvalds	 * The busy loop is necessary because the PIO error
12801da177e4SLinus Torvalds	 * sometimes does not go away quickly and we trap again.
12811da177e4SLinus Torvalds	 */
12821da177e4SLinus Torvalds	sethi	%hi(pcic_regs), %o1
12831da177e4SLinus Torvalds	ld	[%o1 + %lo(pcic_regs)], %o2
12841da177e4SLinus Torvalds
12851da177e4SLinus Torvalds	! Get pending status for printouts later.
12861da177e4SLinus Torvalds	ld	[%o2 + PCI_SYS_INT_PENDING], %o0
12871da177e4SLinus Torvalds
12881da177e4SLinus Torvalds	mov	PCI_SYS_INT_PENDING_CLEAR_ALL, %o1
12891da177e4SLinus Torvalds	stb	%o1, [%o2 + PCI_SYS_INT_PENDING_CLEAR]
12901da177e4SLinus Torvalds1:
12911da177e4SLinus Torvalds	ld	[%o2 + PCI_SYS_INT_PENDING], %o1
12921da177e4SLinus Torvalds	andcc	%o1, ((PCI_SYS_INT_PENDING_PIO|PCI_SYS_INT_PENDING_PCI)>>24), %g0
12931da177e4SLinus Torvalds	bne	1b
12941da177e4SLinus Torvalds	 nop
12951da177e4SLinus Torvalds
12961da177e4SLinus Torvalds	or	%l0, PSR_PIL, %l4
12971da177e4SLinus Torvalds	wr	%l4, 0x0, %psr
12981da177e4SLinus Torvalds	WRITE_PAUSE
12991da177e4SLinus Torvalds	wr	%l4, PSR_ET, %psr
13001da177e4SLinus Torvalds	WRITE_PAUSE
13011da177e4SLinus Torvalds
13021da177e4SLinus Torvalds	call	pcic_nmi
13031da177e4SLinus Torvalds	 add	%sp, STACKFRAME_SZ, %o1	! struct pt_regs *regs
13041da177e4SLinus Torvalds	RESTORE_ALL
13051da177e4SLinus Torvalds
13061da177e4SLinus Torvalds	.globl	pcic_nmi_trap_patch
13071da177e4SLinus Torvaldspcic_nmi_trap_patch:
13081da177e4SLinus Torvalds	sethi	%hi(linux_trap_ipi15_pcic), %l3
13091da177e4SLinus Torvalds	jmpl	%l3 + %lo(linux_trap_ipi15_pcic), %g0
13101da177e4SLinus Torvalds	 rd	%psr, %l0
13111da177e4SLinus Torvalds	.word	0
13121da177e4SLinus Torvalds
1313cfe3af5dSDaniel Hellstrom#endif /* CONFIG_PCIC_PCI */
13141da177e4SLinus Torvalds
1315e2fdd7fdSDavid S. Miller	.globl	flushw_all
1316e2fdd7fdSDavid S. Millerflushw_all:
1317e2fdd7fdSDavid S. Miller	save	%sp, -0x40, %sp
1318e2fdd7fdSDavid S. Miller	save	%sp, -0x40, %sp
1319e2fdd7fdSDavid S. Miller	save	%sp, -0x40, %sp
1320e2fdd7fdSDavid S. Miller	save	%sp, -0x40, %sp
1321e2fdd7fdSDavid S. Miller	save	%sp, -0x40, %sp
1322e2fdd7fdSDavid S. Miller	save	%sp, -0x40, %sp
1323e2fdd7fdSDavid S. Miller	save	%sp, -0x40, %sp
1324e2fdd7fdSDavid S. Miller	restore
1325e2fdd7fdSDavid S. Miller	restore
1326e2fdd7fdSDavid S. Miller	restore
1327e2fdd7fdSDavid S. Miller	restore
1328e2fdd7fdSDavid S. Miller	restore
1329e2fdd7fdSDavid S. Miller	restore
1330e2fdd7fdSDavid S. Miller	ret
1331e2fdd7fdSDavid S. Miller	 restore
1332e2fdd7fdSDavid S. Miller
1333c68e5d39SDavid S. Miller#ifdef CONFIG_SMP
1334c68e5d39SDavid S. MillerENTRY(hard_smp_processor_id)
1335c68e5d39SDavid S. Miller661:	rd		%tbr, %g1
1336c68e5d39SDavid S. Miller	srl		%g1, 12, %o0
1337c68e5d39SDavid S. Miller	and		%o0, 3, %o0
1338c68e5d39SDavid S. Miller	.section	.cpuid_patch, "ax"
1339c68e5d39SDavid S. Miller	/* Instruction location. */
1340c68e5d39SDavid S. Miller	.word		661b
1341c68e5d39SDavid S. Miller	/* SUN4D implementation. */
1342c68e5d39SDavid S. Miller	lda		[%g0] ASI_M_VIKING_TMP1, %o0
1343c68e5d39SDavid S. Miller	nop
1344c68e5d39SDavid S. Miller	nop
1345c68e5d39SDavid S. Miller	/* LEON implementation. */
1346c68e5d39SDavid S. Miller	rd		%asr17, %o0
1347c68e5d39SDavid S. Miller	srl		%o0, 0x1c, %o0
1348c68e5d39SDavid S. Miller	nop
1349c68e5d39SDavid S. Miller	.previous
1350c68e5d39SDavid S. Miller	retl
1351c68e5d39SDavid S. Miller	 nop
1352c68e5d39SDavid S. MillerENDPROC(hard_smp_processor_id)
1353c68e5d39SDavid S. Miller#endif
1354c68e5d39SDavid S. Miller
13551da177e4SLinus Torvalds/* End of entry.S */
1356