patch-2.1.97 linux/arch/sparc/kernel/entry.S
Next file: linux/arch/sparc/kernel/etrap.S
Previous file: linux/arch/sparc/kernel/devices.c
Back to the patch index
Back to the overall index
- Lines: 379
- Date:
Tue Apr 14 17:44:18 1998
- Orig file:
v2.1.96/linux/arch/sparc/kernel/entry.S
- Orig date:
Mon Jan 12 15:15:43 1998
diff -u --recursive --new-file v2.1.96/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S
@@ -1,10 +1,11 @@
-/* $Id: entry.S,v 1.142 1998/01/07 06:33:47 baccala Exp $
+/* $Id: entry.S,v 1.149 1998/03/19 15:36:30 jj Exp $
* arch/sparc/kernel/entry.S: Sparc trap low-level entry points.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
* Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
- * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1996,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1997 Anton Blanchard (anton@progsoc.uts.edu.au)
*/
#include <linux/config.h>
@@ -21,9 +22,15 @@
#include <asm/vaddrs.h>
#include <asm/memreg.h>
#include <asm/page.h>
+#ifdef CONFIG_SUN4
+#include <asm/pgtsun4.h>
+#else
#include <asm/pgtsun4c.h>
+#endif
#include <asm/winmacro.h>
#include <asm/signal.h>
+#include <asm/obio.h>
+#include <asm/mxcc.h>
#include <asm/asmmacro.h>
@@ -288,10 +295,14 @@
SAVE_ALL
#ifdef __SMP__
+ .globl patchme_maybe_smp_msg
+
cmp %l7, 12
- bgu maybe_smp_msg
+patchme_maybe_smp_msg:
+ bgu maybe_smp4m_msg
nop
#endif
+
real_irq_continue:
or %l0, PSR_PIL, %g2
wr %g2, 0x0, %psr
@@ -309,14 +320,14 @@
#ifdef __SMP__
/* SMP per-cpu ticker interrupts are handled specially. */
-smp_ticker:
- bne real_irq_continue
+smp4m_ticker:
+ bne real_irq_continue+4
or %l0, PSR_PIL, %g2
wr %g2, 0x0, %psr
WRITE_PAUSE
wr %g2, PSR_ET, %psr
WRITE_PAUSE
- call C_LABEL(smp_percpu_timer_interrupt)
+ call C_LABEL(smp4m_percpu_timer_interrupt)
add %sp, REGWIN_SZ, %o0
wr %l0, PSR_ET, %psr
WRITE_PAUSE
@@ -326,7 +337,7 @@
* on some level other than 15 which is the NMI and only used
* for cross calls. That has a seperate entry point below.
*/
-maybe_smp_msg:
+maybe_smp4m_msg:
GET_PROCESSOR_MID(o3, o2)
set C_LABEL(sun4m_interrupts), %l5
ld [%l5], %o5
@@ -334,7 +345,7 @@
sll %o3, 12, %o3
ld [%o5 + %o3], %o1
andcc %o1, %o4, %g0
- be,a smp_ticker
+ be,a smp4m_ticker
cmp %l7, 14
cmp %l7, 13
add %o5, %o3, %o5
@@ -383,7 +394,7 @@
WRITE_PAUSE
wr %l4, PSR_ET, %psr
WRITE_PAUSE
- call C_LABEL(smp_cross_call_irq)
+ call C_LABEL(smp4m_cross_call_irq)
nop
b ret_trap_lockless_ipi
clr %l6
@@ -409,6 +420,64 @@
ld [%l5], %g0
WRITE_PAUSE
RESTORE_ALL
+
+ .globl smp4d_ticker
+ /* SMP per-cpu ticker interrupts are handled specially. */
+smp4d_ticker:
+ SAVE_ALL
+ or %l0, PSR_PIL, %g2
+ sethi %hi(CC_ICLR), %o0
+ sethi %hi(1 << 14), %o1
+ or %o0, %lo(CC_ICLR), %o0
+ stha %o1, [%o0] ASI_M_MXCC /* Clear PIL 14 in MXCC's ICLR */
+ wr %g2, 0x0, %psr
+ WRITE_PAUSE
+ wr %g2, PSR_ET, %psr
+ WRITE_PAUSE
+ call C_LABEL(smp4d_percpu_timer_interrupt)
+ add %sp, REGWIN_SZ, %o0
+ wr %l0, PSR_ET, %psr
+ WRITE_PAUSE
+ RESTORE_ALL
+
+ .align 4
+ .globl linux_trap_ipi15_sun4d
+linux_trap_ipi15_sun4d:
+ SAVE_ALL
+ sethi %hi(CC_BASE), %o4
+ sethi %hi(MXCC_ERR_ME|MXCC_ERR_PEW|MXCC_ERR_ASE|MXCC_ERR_PEE), %o2
+ or %o4, (CC_EREG - CC_BASE), %o0
+ ldda [%o0] ASI_M_MXCC, %o0
+ andcc %o0, %o2, %g0
+ bne 1f
+ sethi %hi(BB_STAT2), %o2
+ lduba [%o2] ASI_M_CTL, %o2
+ andcc %o2, BB_STAT2_MASK, %g0
+ bne 2f
+ or %o4, (CC_ICLR - CC_BASE), %o0
+ sethi %hi(1 << 15), %o1
+ stha %o1, [%o0] ASI_M_MXCC /* Clear PIL 15 in MXCC's ICLR */
+ or %l0, PSR_PIL, %l4
+ wr %l4, 0x0, %psr
+ WRITE_PAUSE
+ wr %l4, PSR_ET, %psr
+ WRITE_PAUSE
+ call C_LABEL(smp4d_cross_call_irq)
+ nop
+ b ret_trap_lockless_ipi
+ clr %l6
+
+1: /* MXCC error */
+2: /* BB error */
+ /* Disable PIL 15 */
+ set CC_IMSK, %l4
+ lduha [%l4] ASI_M_MXCC, %l5
+ sethi %hi(1 << 15), %l7
+ or %l5, %l7, %l5
+ stha %l5, [%l4] ASI_M_MXCC
+ /* FIXME */
+1: b,a 1b
+
#endif /* __SMP__ */
/* This routine handles illegal instructions and privileged
@@ -417,6 +486,12 @@
.align 4
.globl bad_instruction
bad_instruction:
+ sethi %hi(0xc1f80000), %l4
+ ld [%l1], %l5
+ sethi %hi(0x81d80000), %l7
+ and %l5, %l4, %l5
+ cmp %l5, %l7
+ be 1f
SAVE_ALL
wr %l0, PSR_ET, %psr ! re-enable traps
@@ -430,6 +505,10 @@
RESTORE_ALL
+1: /* unimplemented flush - just skip */
+ jmpl %l2, %g0
+ rett %l2 + 4
+
.align 4
.globl priv_instruction
priv_instruction:
@@ -601,23 +680,6 @@
RESTORE_ALL
- /* This routine handles Unimplemented FLUSH Exceptions. */
- .align 4
- .globl do_bad_flush
-do_bad_flush:
- SAVE_ALL
-
- wr %l0, PSR_ET, %psr ! re-enable traps
- WRITE_PAUSE
-
- add %sp, REGWIN_SZ, %o0
- mov %l1, %o1
- mov %l2, %o2
- call C_LABEL(handle_bad_flush)
- mov %l0, %o3
-
- RESTORE_ALL
-
/* This routine handles Co-Processor Exceptions. */
.align 4
.globl do_cp_exception
@@ -766,6 +828,12 @@
C_LABEL(invalid_segment_patch2_ff): mov 0xff, %l4
.align 4
+ .globl C_LABEL(invalid_segment_patch1_1ff)
+ .globl C_LABEL(invalid_segment_patch2_1ff)
+C_LABEL(invalid_segment_patch1_1ff): cmp %l4, 0x1ff
+C_LABEL(invalid_segment_patch2_1ff): mov 0x1ff, %l4
+
+ .align 4
.globl C_LABEL(num_context_patch1_16), C_LABEL(num_context_patch2_16)
C_LABEL(num_context_patch1_16): mov 0x10, %l7
C_LABEL(num_context_patch2_16): mov 0x10, %l7
@@ -776,7 +844,17 @@
.align 4
.globl C_LABEL(vac_hwflush_patch1_on), C_LABEL(vac_hwflush_patch2_on)
+
+/*
+ * Ugly, but we cant use hardware flushing on the sun4 and we'd require
+ * two instructions (Anton)
+ */
+#ifdef CONFIG_SUN4
+C_LABEL(vac_hwflush_patch1_on): nop
+#else
C_LABEL(vac_hwflush_patch1_on): subcc %l7, (PAGE_SIZE - 4), %l7
+#endif
+
C_LABEL(vac_hwflush_patch2_on): sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG
.globl C_LABEL(invalid_segment_patch1), C_LABEL(invalid_segment_patch2)
@@ -786,11 +864,50 @@
.align 4
.globl sun4c_fault
+
+! %l0 = %psr
+! %l1 = %pc
+! %l2 = %npc
+! %l3 = %wim
+! %l7 = 1 for textfault
+! We want error in %l5, vaddr in %l6
sun4c_fault:
+#ifdef CONFIG_SUN4
+ sethi C_LABEL(sun4c_memerr_reg), %l4
+ ld [%l4+%lo(C_LABEL(sun4c_memerr_reg))], %l4 ! memerr ctrl reg addr
+ ld [%l4], %l6 ! memerr ctrl reg
+ ld [%l4 + 4], %l5 ! memerr vaddr reg
+ andcc %l6, 0x80, %g0 ! check for error type
+ st %g0, [%l4 + 4] ! clear the error
+ be 0f ! normal error
+ sethi %hi(AC_BUS_ERROR), %l4 ! bus err reg addr
+
+ call C_LABEL(prom_halt) ! something weird happened
+ ! what exactly did happen?
+ ! what should we do here?
+
+0: or %l4, %lo(AC_BUS_ERROR), %l4 ! bus err reg addr
+ lduba [%l4] ASI_CONTROL, %l6 ! bus err reg
+
+ cmp %l7, 1 ! text fault?
+ be 1f ! yes
+ nop
+
+ ld [%l1], %l4 ! load instruction that caused fault
+ srl %l4, 21, %l4
+ andcc %l4, 1, %g0 ! store instruction?
+
+ be 1f ! no
+ sethi %hi(SUN4C_SYNC_BADWRITE), %l4 ! yep
+ ! %lo(SUN4C_SYNC_BADWRITE) = 0
+ or %l4, %l6, %l6 ! set write bit to emulate sun4c
+1:
+#else
sethi %hi(AC_SYNC_ERR), %l4
add %l4, 0x4, %l6 ! AC_SYNC_VA in %l6
lda [%l6] ASI_CONTROL, %l5 ! Address
lda [%l4] ASI_CONTROL, %l6 ! Error, retained for a bit
+#endif
andn %l5, 0xfff, %l5 ! Encode all info into l7
srl %l6, 14, %l4
@@ -830,17 +947,21 @@
sethi %hi(SUN4C_VMALLOC_START), %l4
cmp %l5, %l4
blu,a C_LABEL(invalid_segment_patch1)
- lduba [%l5] ASI_SEGMAP, %l4
+ lduXa [%l5] ASI_SEGMAP, %l4
- srl %l5, SUN4C_PGDIR_SHIFT, %l6
sethi %hi(C_LABEL(swapper_pg_dir)), %l4
+ srl %l5, SUN4C_PGDIR_SHIFT, %l6
or %l4, %lo(C_LABEL(swapper_pg_dir)), %l4
sll %l6, 2, %l6
ld [%l4 + %l6], %l4
+#ifdef CONFIG_SUN4
+ sethi PAGE_MASK, %l6
+ andcc %l4, %l6, %g0
+#else
andcc %l4, PAGE_MASK, %g0
-
+#endif
be sun4c_fault_fromuser
- lduba [%l5] ASI_SEGMAP, %l4
+ lduXa [%l5] ASI_SEGMAP, %l4
C_LABEL(invalid_segment_patch1):
cmp %l4, 0x7f
@@ -889,7 +1010,11 @@
ld [%l6 + 0x08], %l3 ! tmp = entry->vaddr
! Flush segment from the cache.
+#ifdef CONFIG_SUN4
+ sethi %hi((128 * 1024)), %l7
+#else
sethi %hi((64 * 1024)), %l7
+#endif
9:
C_LABEL(vac_hwflush_patch1):
C_LABEL(vac_linesize_patch):
@@ -928,7 +1053,7 @@
deccc %l7
stba %l7, [%l3] ASI_CONTROL
bne 3b
- stba %l4, [%l5] ASI_SEGMAP
+ stXa %l4, [%l5] ASI_SEGMAP
stba %l6, [%l3] ASI_CONTROL
@@ -952,7 +1077,7 @@
deccc %l7
stba %l7, [%l3] ASI_CONTROL
bne 3b
- stba %l4, [%l5] ASI_SEGMAP
+ stXa %l4, [%l5] ASI_SEGMAP
stba %l6, [%l3] ASI_CONTROL
@@ -988,7 +1113,12 @@
or %l4, %lo(C_LABEL(swapper_pg_dir)), %l4
sll %l3, 2, %l3
ld [%l4 + %l3], %l4
+#ifndef CONFIG_SUN4
and %l4, PAGE_MASK, %l4
+#else
+ sethi PAGE_MASK, %l6
+ and %l4, %l6, %l4
+#endif
srl %l5, (PAGE_SHIFT - 2), %l6
and %l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6
@@ -1640,9 +1770,8 @@
call .umul
ld [%o3 + %lo(C_LABEL(loops_per_sec))], %o1
#else
- GET_PROCESSOR_OFFSET(o4)
+ GET_PROCESSOR_OFFSET(o4, o2)
set C_LABEL(cpu_data), %o3
- sll %o4, 1, %o4
call .umul
ld [%o3 + %o4], %o1
#endif
@@ -1717,5 +1846,12 @@
3:
retl ! return
st %g0, [%g6 + AOFF_task_tss + AOFF_thread_w_saved] ! no windows saved
+
+ .align 4
+ .globl C_LABEL(restore_current)
+C_LABEL(restore_current):
+ LOAD_CURRENT(g6, o0)
+ retl
+ nop
/* End of entry.S */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov