patch-2.4.6 linux/arch/mips/kernel/head.S

Next file: linux/arch/mips/kernel/i8259.c
Previous file: linux/arch/mips/kernel/gdb-stub.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.5/linux/arch/mips/kernel/head.S linux/arch/mips/kernel/head.S
@@ -1,5 +1,4 @@
-/* $Id: head.S,v 1.18 2000/03/03 22:17:07 kevink Exp $
- *
+/*
  * arch/mips/kernel/head.S
  *
  * This file is subject to the terms and conditions of the GNU General Public
@@ -15,6 +14,14 @@
  * Copyright (C) 1999 Silicon Graphics, Inc.
  *
  * Head.S contains the MIPS exception handler and startup code.
+ *
+ **************************************************************************
+ *  9 Nov, 2000.
+ *  Added Cache Error exception handler and SBDDP EJTAG debug exception.
+ *
+ *  Kevin Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
+ *  Copyright (C) 2000 MIPS Technologies, Inc.  All rights reserved.
+ **************************************************************************
  */
 #include <linux/config.h>
 #include <linux/threads.h>
@@ -52,9 +59,19 @@
 	.set	noat
 	LEAF(except_vec0_r4000)
 	.set	mips3
+#ifdef CONFIG_SMP
+	mfc0	k1, CP0_CONTEXT
+	la	k0, current_pgd
+	srl	k1, 23
+	sll	k1, 2
+	addu	k1, k0, k1
+	lw	k1, (k1)
+#else 
+	lw	k1, current_pgd			# get pgd pointer
+#endif	
 	mfc0	k0, CP0_BADVADDR		# Get faulting address
 	srl	k0, k0, 22			# get pgd only bits
-	lw	k1, current_pgd			# get pgd pointer
+
 	sll	k0, k0, 2
 	addu	k1, k1, k0			# add in pgd offset
 	mfc0	k0, CP0_CONTEXT			# get context reg
@@ -69,8 +86,8 @@
 	srl	k1, k1, 6			# convert to entrylo1
 	mtc0	k1, CP0_ENTRYLO1		# load it
 	b	1f
-	 tlbwr					# write random tlb entry
-1:	
+	tlbwr					# write random tlb entry
+1:
 	nop
 	eret					# return from trap
 	END(except_vec0_r4000)
@@ -308,12 +325,26 @@
 
 	/* Cache Error */
 	LEAF(except_vec2_generic)
-	/* Famous last words: unreached */
-	mfc0	a1,CP0_ERROREPC
-	PRINT("Cache error exception: c0_errorepc == %08x\n")
-1:
-	j	1b
-	 nop
+	.set	noat
+	.set    mips0
+	/*
+	 * This is a very bad place to be.  Our cache error
+	 * detection has triggered.  If we have write-back data
+	 * in the cache, we may not be able to recover.  As a
+	 * first-order desperate measure, turn off KSEG0 cacheing.
+	 */
+	mfc0	k0,CP0_CONFIG
+	li	k1,~CONF_CM_CMASK
+	and	k0,k0,k1
+	ori	k0,k0,CONF_CM_UNCACHED
+	mtc0	k0,CP0_CONFIG
+	/* Give it a few cycles to sink in... */
+	nop
+	nop
+	nop
+
+	j	cache_parity_error
+	nop
 	END(except_vec2_generic)
 
 	/* General exception vector R4000 version. */
@@ -338,6 +369,7 @@
  * c0_badvaddr because after return from this exception handler the load /
  * store will be re-executed.
  */
+	.set    mips3
 handle_vced:
 	mfc0	k0, CP0_BADVADDR
  li k1, -4
@@ -393,6 +425,38 @@
 	 nop
 	END(except_vec4)
 
+	/*
+	 * SBDDP EJTAG debug exception handler.
+	 * The EJTAG debug exception entry point is 0xbfc00480, which
+	 * normally is in the boot PROM, so the boot PROM must do a
+	 * unconditional jump to this vector.
+	 */	
+	NESTED(except_vec_ejtag_debug, 0, sp)
+	j	ejtag_debug_handler
+	 nop
+	END(except_vec_ejtag_debug)
+
+	/*
+	 * EJTAG debug exception handler.
+	 */
+	NESTED(ejtag_debug_handler, PT_SIZE, sp)
+	.set	noat
+	.set	noreorder
+	SAVE_ALL
+	PRINT("SDBBP EJTAG debug exception - not handled yet, just ignored!\n");
+	mfc0	k0, $23         # Get EJTAG Debug register.
+	mfc0    k1, $24         # Get DEPC register.
+	bgez	k0, 1f
+	 addiu	k1, k1, 4	# SBDDP inst. in delay slot.
+	addiu	k1, k1, 4
+1:	mtc0	k1, $24
+	RESTORE_ALL
+	.word	0x4200001f      # deret, return EJTAG debug exception.
+	 nop
+	.set	at
+	END(ejtag_debug_handler)
+
+		
 /*
  * Kernel entry point
  */
@@ -407,9 +471,9 @@
 	 */
 	la	$28, init_task_union
 	addiu	t0, $28, KERNEL_STACK_SIZE-32
-	sw	t0, kernelsp
 	subu	sp, t0, 4*SZREG
 
+	sw	t0, kernelsp
 	/* The firmware/bootloader passes argc/argp/envp
 	 * to us as arguments.  But clear bss first because
 	 * the romvec and other important info is stored there
@@ -427,6 +491,30 @@
 	 nop
 	END(kernel_entry)
 
+
+#ifdef CONFIG_SMP
+
+/*
+ * SMP slave cpus entry point.  Board specific code
+ * for bootstrap calls this function after setting up
+ * the stack and gp registers. 
+ */
+	LEAF(smp_bootstrap)
+	.set push
+	.set noreorder
+	mtc0	zero, CP0_WIRED
+	CLI
+	mfc0	t0, CP0_STATUS
+	li	t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_BEV); 
+	and	t0, t1
+	or	t0, (ST0_CU0|ST0_KX|ST0_SX|ST0_FR);
+	addiu	a0, zero, 0
+	jal	start_secondary
+         mtc0	t0, CP0_STATUS
+	.set pop
+	END(smp_bootstrap)
+#endif
+	
 /*
  * This buffer is reserved for the use of the cache error handler.
  */
@@ -434,12 +522,19 @@
 		EXPORT(cache_error_buffer)
 		.fill	32*4,1,0
 
+#ifndef CONFIG_SMP
 EXPORT(kernelsp)
 		PTR	0
 EXPORT(current_pgd)
-		PTR	0
+		PTR     0
+#else
+		/* There's almost certainly a better way to do this with the macros...*/
+		.globl kernelsp
+		.comm  kernelsp,     NR_CPUS * 8, 8
+		.globl current_pgd
+		.comm	current_pgd, NR_CPUS * 8, 8
+#endif
 		.text
-
 		.org	0x1000
 EXPORT(swapper_pg_dir)
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)