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