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

Next file: linux/arch/mips/kernel/init_task.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.1.43/linux/arch/mips/kernel/head.S linux/arch/mips/kernel/head.S
@@ -1,258 +1,617 @@
 /*
  *  arch/mips/kernel/head.S
  *
- *  Copyright (C) 1994, 1995 Waldorf Electronics
+ *  Copyright (C) 1994, 1995 Waldorf Electronics, 1996 Paul M. Antoine
  *  Written by Ralf Baechle and Andreas Busse
+ *  Modified for DECStation and hence R3000 support by Paul M. Antoine
+ *  Further modifications by David S. Miller
  *
  *  Head.S contains the MIPS exception handler and startup code.
  */
+#include <linux/config.h>
 #include <linux/tasks.h>
 
 #include <asm/asm.h>
-#include <asm/segment.h>
+#include <asm/current.h>
+#include <asm/offset.h>
+#include <asm/processor.h>
+#include <asm/regdef.h>
 #include <asm/cachectl.h>
 #include <asm/mipsregs.h>
 #include <asm/mipsconfig.h>
 #include <asm/stackframe.h>
 #include <asm/bootinfo.h>
+#include <asm/cpu.h>
 
-#define PAGE_SIZE	0x1000
+	.text
+	/*
+	 * Reserved space for exception handlers.
+	 * Necessary for machines which link their kernels at KSEG0.
+	 */
+	.fill	512
+/*	
+ * This is space for the interrupt handlers.
+ * After trap_init() they are located at virtual address KSEG0.
+ *
+ * These handlers much be written in a relocatable manner
+ * because based upon the cpu type an arbitrary one of the
+ * following pieces of code will be copied to the KSEG0
+ * vector location.
+ */
+	/* TLB refill, EXL == 0, R4xx0, non-R4600 version */
+	.set	noreorder
+	.set	noat
+	LEAF(except_vec0_r4000)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR		# Get faulting address
+	_GET_CURRENT(k1)			# get current task ptr
+	srl	k0, k0, 22			# get pgd only bits
+	lw	k1, THREAD_PGDIR(k1)		# get task pg_dir
+	sll	k0, k0, 2
+	addu	k1, k1, k0			# add in pgd offset
+	mfc0	k0, CP0_CONTEXT			# get context reg
+	lw	k1, (k1)
+	srl	k0, k0, 1			# get pte offset
+	and	k0, k0, 0xff8
+	addu	k1, k1, k0			# add in offset
+	lw	k0, 0(k1)			# get even pte
+	lw	k1, 4(k1)			# get odd pte
+	srl	k0, k0, 6			# convert to entrylo0
+	mtc0	k0, CP0_ENTRYLO0		# load it
+	srl	k1, k1, 6			# convert to entrylo1
+	mtc0	k1, CP0_ENTRYLO1		# load it
+	b	1f
+	 tlbwr					# write random tlb entry
+1:	
+	nop
+	eret					# return from trap
+	END(except_vec0_r4000)
+
+	/* TLB refill, EXL == 0, R4600 version */
+	LEAF(except_vec0_r4600)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR
+	_GET_CURRENT(k1)			# get current task ptr
+	srl	k0, k0, 22
+	lw	k1, THREAD_PGDIR(k1)
+	sll	k0, k0, 2
+	addu	k1, k1, k0
+	mfc0	k0, CP0_CONTEXT
+	lw	k1, (k1)
+	srl	k0, k0, 1
+	and	k0, k0, 0xff8
+	addu	k1, k1, k0
+	lw	k0, 0(k1)
+	lw	k1, 4(k1)
+	srl	k0, k0, 6
+	mtc0	k0, CP0_ENTRYLO0
+	srl	k1, k1, 6
+	mtc0	k1, CP0_ENTRYLO1
+	nop
+	tlbwr
+	nop
+	eret
+	END(except_vec0_r4600)
+
+	/* TLB refill, EXL == 0, R4[40]00/R5000 badvaddr hwbug version */
+	LEAF(except_vec0_r45k_bvahwbug)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR
+	_GET_CURRENT(k1)			# get current task ptr
+	srl	k0, k0, 22
+	lw	k1, THREAD_PGDIR(k1)
+	sll	k0, k0, 2
+	addu	k1, k1, k0
+	mfc0	k0, CP0_CONTEXT
+	lw	k1, (k1)
+	srl	k0, k0, 1
+	and	k0, k0, 0xff8
+	addu	k1, k1, k0
+	lw	k0, 0(k1)
+	lw	k1, 4(k1)
+	tlbp
+	srl	k0, k0, 6
+	mtc0	k0, CP0_ENTRYLO0
+	srl	k1, k1, 6
+	mfc0	k0, CP0_INDEX
+	mtc0	k1, CP0_ENTRYLO1
+	bltzl	k0, 1f
+	tlbwr
+1:
+	nop
+	eret
+	END(except_vec0_r45k_bvahwbug)
+
+#ifdef __SMP__
+	/* TLB refill, EXL == 0, R4000 MP badvaddr hwbug version */
+	LEAF(except_vec0_r4k_mphwbug)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR
+	_GET_CURRENT(k1)			# get current task ptr
+	srl	k0, k0, 22
+	lw	k1, THREAD_PGDIR(k1)
+	sll	k0, k0, 2
+	addu	k1, k1, k0
+	mfc0	k0, CP0_CONTEXT
+	lw	k1, (k1)
+	srl	k0, k0, 1
+	and	k0, k0, 0xff8
+	addu	k1, k1, k0
+	lw	k0, 0(k1)
+	lw	k1, 4(k1)
+	tlbp
+	srl	k0, k0, 6
+	mtc0	k0, CP0_ENTRYLO0
+	srl	k1, k1, 6
+	mfc0	k0, CP0_INDEX
+	mtc0	k1, CP0_ENTRYLO1
+	bltzl	k0, 1f
+	tlbwr
+1:
+	nop
+	eret
+	END(except_vec0_r4k_mphwbug)
+#endif
 
-#define MODE_GLOBAL	0x0001	/* shared for all processes */
-#define MODE_ALIAS	0x0016	/* uncachable */
+	/* TLB refill, EXL == 0, R4000 UP 250MHZ entrylo[01] hwbug version */
+	LEAF(except_vec0_r4k_250MHZhwbug)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR
+	_GET_CURRENT(k1)			# get current task ptr
+	srl	k0, k0, 22
+	lw	k1, THREAD_PGDIR(k1)
+	sll	k0, k0, 2
+	addu	k1, k1, k0
+	mfc0	k0, CP0_CONTEXT
+	lw	k1, (k1)
+	srl	k0, k0, 1
+	and	k0, k0, 0xff8
+	addu	k1, k1, k0
+	lw	k0, 0(k1)
+	lw	k1, 4(k1)
+	srl	k0, k0, 6
+	mtc0	zero, CP0_ENTRYLO0
+	mtc0	k0, CP0_ENTRYLO0
+	srl	k1, k1, 6
+	mtc0	zero, CP0_ENTRYLO1
+	mtc0	k1, CP0_ENTRYLO1
+	b	1f
+	tlbwr
+1:
+	nop
+	eret
+	END(except_vec0_r4k_250MHZhwbug)
+
+#ifdef __SMP__
+	/* TLB refill, EXL == 0, R4000 MP 250MHZ entrylo[01]+badvaddr bug version */
+	LEAF(except_vec0_r4k_MP250MHZhwbug)
+	.set	mips3
+	mfc0	k0, CP0_BADVADDR
+	_GET_CURRENT(k1)			# get current task ptr
+	srl	k0, k0, 22
+	lw	k1, THREAD_PGDIR(k1)
+	sll	k0, k0, 2
+	addu	k1, k1, k0
+	mfc0	k0, CP0_CONTEXT
+	lw	k1, (k1)
+	srl	k0, k0, 1
+	and	k0, k0, 0xff8
+	addu	k1, k1, k0
+	lw	k0, 0(k1)
+	lw	k1, 4(k1)
+	tlbp
+	srl	k0, k0, 6
+	mtc0	zero, CP0_ENTRYLO0
+	mtc0	k0, CP0_ENTRYLO0
+	mfc0	k0, CP0_INDEX
+	srl	k1, k1, 6
+	mtc0	zero, CP0_ENTRYLO1
+	mtc0	k1, CP0_ENTRYLO1
+	bltzl	k0, 1f
+	tlbwr
+1:
+	nop
+	eret
+	END(except_vec0_r4k_MP250MHZhwbug)
+#endif
 
-		.text
-		.set	mips3
-/*
- * This is space for the interrupt handlers.
- * They are located at virtual address KSEG[01] (physical 0x0)
- */
-		/*
-		 * TLB refill, EXL == 0
-		 */
-		.set	noreorder
-		.set	noat
-		LEAF(except_vec0)
-		dmfc0	k1,CP0_CONTEXT
-		dsra	k1,1
-		lwu	k0,(k1)			# May cause another exception
-		lwu	k1,4(k1)
-		dsrl	k0,6			# Convert to EntryLo format
-		dsrl	k1,6			# Convert to EntryLo format
-		dmtc0	k0,CP0_ENTRYLO0
-		dmtc0	k1,CP0_ENTRYLO1
-		nop				# Needed for R4[04]00 pipeline
-		tlbwr
-		nop				# Needed for R4[04]00 pipeline
-		nop
-		nop
-		eret
-		/*
-		 * Workaround for R4000 bug.  For explanation see MIPS
-		 * docs.  Note that this is so obscure that it will almost
-		 * never happen.  Well, but Mips writes about its bugs.
-		 */
-		nop
-		eret
-		END(except_vec0)
-
-		/*
-		 * XTLB refill, EXL == 0
-		 * Should never be reached
-		 */
-		.org	except_vec0+0x80
-		LEAF(except_vec1)
-		PANIC("XTLB Refill exception.\n")
-1:		j	1b
-		nop
-		END(except_vec1)
-
-		/*
-		 * Cache Error
-		 */
-		.org	except_vec1+0x80
-		LEAF(except_vec2)
-		/*
-		 * Famous last words: unreached
-		 */
-		mfc0	a1,CP0_ERROREPC
-		PRINT("Cache error exception: c0_errorepc == %08x\n")
-1:		j	1b
-		nop
-		END(except_vec2)
-
-		/*
-		 * General exception vector.
-		 */
-		.org	except_vec2+0x80
-		NESTED(except_vec3, 0, sp)
-		.set	noat
-		/*
-		 * Register saving is delayed as long as we don't know
-		 * which registers really need to be saved.
-		 */
-		mfc0	k1,CP0_CAUSE
-		la	k0,exception_handlers
-		/*
-		 * Next lines assumes that the used CPU type has max.
-		 * 32 different types of exceptions. We might use this
-		 * to implement software exceptions in the future.
-		 */
-		andi	k1,0x7c
-		addu	k0,k1
-		lw	k0,(k0)
-		NOP
-		jr	k0
-		nop
-		END(except_vec3)
-		.set	at
-
-/******************************************************************************/
-
-/*
- * Kernel entry
- */
-		.set	noreorder
-		NESTED(kernel_entry, 16, sp)
-		/*
-		 * The following two symbols are used for kernel profiling.
-		 */
-		EXPORT(stext)
-		EXPORT(_stext)
-
-#ifdef CONF_DISABLE_KSEG0_CACHING
-		/*
-		 * Disable all caching for KSEG0.  This option is useful
-		 * when cache trouble with drivers is suspected
-		 */
-		mfc0	t0,CP0_CONFIG
-		ori	t0,7
-		xori	t0,5
-		mtc0	t0,CP0_CONFIG
+	/* TLB refill, EXL == 0, R[23]00 version */
+	LEAF(except_vec0_r2300)
+	.set	mips1
+	mfc0	k0, CP0_BADVADDR
+	_GET_CURRENT(k1)			# get current task ptr
+	srl	k0, k0, 22
+	lw	k1, THREAD_PGDIR(k1)
+	sll	k0, k0, 2
+	addu	k1, k1, k0
+	mfc0	k0, CP0_CONTEXT
+	lw	k1, (k1)
+	srl	k0, k0, 1
+	and	k0, k0, 0xffc
+	addu	k1, k1, k0
+	lw	k0, (k1)
+	srl	k0, k0, 12
+	mtc0	k0, CP0_ENTRYLO0
+	mfc0	k1, CP0_EPC
+	tlbwr
+	nop
+	nop
+	nop
+	nop
+	jr	k1
+	rfe
+	END(except_vec0_r2300)
+
+
+	/* XTLB refill, EXL == 0, R4xx0 cpus only use this... */
+	NESTED(except_vec1_generic, 0, sp)
+	.set	noat
+	.set	mips3
+	/* Register saving is delayed as long as we don't know
+	 * which registers really need to be saved.
+	 */
+	mfc0	k1, CP0_CONTEXT
+	dsra	k1, 1
+	lwu	k0,  (k1)		# May cause another exception
+	lwu	k1, 4(k1)
+	dsrl	k0, 6			# Convert to EntryLo format
+	dsrl	k1, 6			# Convert to EntryLo format
+	dmtc0	k0, CP0_ENTRYLO0
+	dmtc0	k1, CP0_ENTRYLO1
+	nop				# Needed for R4[04]00 pipeline
+	tlbwr
+	nop				# Needed for R4[04]00 pipeline
+	nop
+	nop
+	eret
+	nop				/* Workaround for R4000 bug. */
+	eret
+	END(except_vec1_generic)
+
+	/* 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
+	END(except_vec2_generic)
+
+	/* General exception vector R4000 version. */
+	NESTED(except_vec3_r4000, 0, sp)
+	.set	noat
+	mfc0	k1, CP0_CAUSE
+
+	/* XXX Have to check for VCE's _before_ we do a load or store. */
+
+	la	k0, exception_handlers
+	andi	k1, k1, 0x7c
+	addu	k0, k0, k1
+	lw	k0, (k0)
+	nop
+	jr	k0
+	 nop
+	END(except_vec3_r4000)
+	.set	at
+
+	/* General exception vector. */
+	NESTED(except_vec3_generic, 0, sp)
+	.set	noat
+	mfc0	k1, CP0_CAUSE
+	la	k0, exception_handlers
+	andi	k1, k1, 0x7c
+	addu	k0, k0, k1
+	lw	k0, (k0)
+	nop
+	jr	k0
+	 nop
+	END(except_vec3_generic)
+	.set	at
+
+/*
+ * Kernel entry point
+ */
+NESTED(kernel_entry, 16, sp)
+	.set	noreorder
+	/* The following two symbols are used for kernel profiling. */
+	EXPORT(stext)
+	EXPORT(_stext)
+
+	/* Determine which MIPS variant we are running on. */
+	b	cpu_probe
+	 nop
+
+probe_done:
+
+#ifndef CONFIG_SGI
+	/* Get the memory upper limit the bootloader passed to us
+	 * in a0
+	 */
+	la	t0, mips_memory_upper
+	nop
+	sw	a0, (t0)		
+#else
+	/* On SGI's 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
+	 * by prom_init().
+	 */
+	la	t0, _edata
+	sw	zero, (t0)
+	la	t1, (_end - 4)
+1:
+	addiu	t0, 4
+	bne	t0, t1, 1b
+	 sw	zero, (t0)
+
+	jal	prom_init /* prom_init(argc, argv, envp); */
+	 nop
+	jal	sgi_sysinit
+	 nop
 #endif
-		/*
-		 * Clear BSS first so that there are no surprises...
-		 */
-		la	t0,_edata
-		la	t1,_end
-		sw	zero,(t0)
-1:		addiu	t0,4
-		bnel	t0,t1,1b
-		sw	zero,(t0)
-
-		/*
-		 * Initialize low level part of memory management
-		 * First flush the TLB to make sure that we don't get a
-		 * TLB shutdown during wire_mappings.
-		 */
-		jal	tlbflush
-		mtc0	zero,CP0_WIRED			# delay slot
-		jal	wire_mappings
-		nop
-
-		/*
-		 * Stack for kernel and init
-		 */
-		la	sp,init_user_stack+PAGE_SIZE-24
-		la	t0,init_kernel_stack+PAGE_SIZE
-		sw	t0,kernelsp
-
-		/*
-		 * Disable coprocessors; set ST0_CU0 to indicate that
-		 * we're running on the kernel stack
-		 */
-		mfc0	t0,CP0_STATUS
-		li	t1,~(ST0_CU1|ST0_CU2|ST0_CU3)
-		and	t0,t1
-		li	t1,ST0_CU0
-		or	t0,ST0_CU0
-		mtc0	t0,CP0_STATUS
-
-1:		jal	start_kernel
-		nop					# delay slot
-		/*
-		 * Main should never return here, but
-		 * just in case, we know what happens.
-		 */
-		b	1b
-		nop					# delay slot
-		END(kernel_entry)
-
-/*
- * wire_mappings - used to map hardware registers
- */
-		LEAF(wire_mappings)
-		/*
- 		 * Get base address of map0 table for the
-		 * the board we're running on
-		 */
-		la	t0,boot_info
-		lw	t1,OFFSET_BOOTINFO_MACHTYPE(t0)
-		la	t0,map0table
-		sll	t1,PTRLOG		# machtype used as index
-		addu	t0,t1
-		lw	t0,(t0)			# get base address
-
-		/*
-		 * Get number of wired TLB entries and
-		 * loop over selected map0 table.
-		 */
-		lw	t1,(t0)			# number of wired TLB entries
-		move	t2,zero			# TLB entry counter
-		addiu	t3,t1,1			# wire one additional entry
-		beqz	t1,2f			# null, exit
-		mtc0	t3,CP0_WIRED		# delay slot
-		addiu	t0,8
-1:		lw	t4,24(t0)		# PageMask
-		ld	t5,0(t0)		# entryHi
-		ld	t6,8(t0)		# entryLo0
-		ld	t7,16(t0)		# entryLo1
-		addiu	t2,1			# increment ctr
-		mtc0	t2,CP0_INDEX		# set TLB entry
-		mtc0	t4,CP0_PAGEMASK
-		dmtc0	t5,CP0_ENTRYHI
-		dmtc0	t6,CP0_ENTRYLO0
-		dmtc0	t7,CP0_ENTRYLO1
-		addiu	t0,32
-		bne	t1,t2,1b		# next TLB entry
- 		tlbwi 				# delay slot
-
-		/*
-		 * We use only 4k pages. Therefore the PageMask register
-		 * is expected to be setup for 4k pages.
-		 */
-2:		li	t0,PM_4K
-		mtc0	t0,CP0_PAGEMASK
-
-		/*
-		 * Now map the pagetables
-		 */
-		mtc0	zero,CP0_INDEX
-		la	t0,TLB_ROOT
-		dmtc0	t0,CP0_ENTRYHI
-		la	t0,swapper_pg_dir-KSEG1
-		srl	t0,6
-		ori	t0,(MODE_ALIAS|MODE_GLOBAL) # uncachable, dirty, valid
-		dmtc0	t0,CP0_ENTRYLO0
-		li	t0,MODE_GLOBAL
-		dmtc0	t0,CP0_ENTRYLO1
-		nop
-		tlbwi				# delayed
-
-		/*
-		 * Load the context register with a value that allows
-		 * it to be used as fast as possible in tlb exceptions.
-		 * It is expected that this register's content will
-		 * NEVER be changed.
-		 */
-		li	t0,TLBMAP
-		dsll	t0,1
-		dmtc0	t0,CP0_CONTEXT
-		jr	ra			# delay slot
-		nop
-		END(wire_mappings)
+	/* Get the very one tags we need early in the boot process */
+	nop
+	jal	bi_EarlySnarf
+	 nop
+#ifndef CONFIG_SGI
+	/* Clear BSS first so that there are no surprises... */
+	la	t0, _edata
+	la	t1, (_end - 4)
+	sw	zero, (t0)
+1:
+	addiu	t0, 4
+	bne	t0, t1, 1b
+	 sw	zero, (t0)
+	nop
+#endif
+	/*
+	 * Determine the mmu/cache attached to this machine,
+	 * then flush the tlb and caches.  On the r4xx0
+	 * variants this also sets CP0_WIRED to zero.
+	 */
+	jal	loadmmu
+	 nop
+
+	la	t2, mips_cputype
+	lw	t4, (t2)
+	li	t1, CPU_R2000
+	li	t2, CPU_R3000
+	li	t3, CPU_R3000A
+	beq	t4,t1,2f
+	 nop		
+
+	beq	t4,t2,2f
+	 nop		
+
+	beq	t4,t3,2f
+	 nop		
+
+	jal	wire_mappings_r4xx0
+	 nop	
+
+	b	9f
+	 nop
+
+2:
+	jal	wire_mappings_r3000
+	 nop	
+
+	/*
+	 * Stack for kernel and init
+	 */
+9:	la	sp, init_task_union+(KERNEL_STACK_SIZE-4*SZREG)
+	sw	sp, kernelsp
+
+	/* Disable coprocessors */
+	mfc0	t0, CP0_STATUS
+	li	t1, ~(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX)
+	and	t0, t1
+	or	t0, ST0_CU0
+	mtc0	t0, CP0_STATUS
+
+1:	jal	start_kernel
+	 nop
+	/*
+	 * Main should never return here, but
+	 * just in case, we know what happens.
+	 */
+	b	1b
+	 nop					# delay slot
+	END(kernel_entry)
+
+/*
+ * wire_mappings - used to map hardware registers, r4xx0 version.
+ */
+LEAF(wire_mappings_r4xx0)
+	mtc0	zero, CP0_WIRED
+	nop
+	nop
+	nop
+	j	ra
+	 nop
+	END(wire_mappings_r4xx0)
+
+/*
+ * R3000 version of wire_mappings.
+ */
+LEAF(wire_mappings_r3000)
+	/*
+	 * Get base address of map0 table for the
+	 * the board we're running on
+	 */
+	lw	t1, mips_machtype
+	la	t0, map0table
+	sll	t1, PTRLOG		# machtype used as index
+	addu	t0, t1
+	lw	t0, (t0)		# get base address
+	nop
+	/* Get number of wired TLB entries and
+	 * loop over selected map0 table.
+	 */
+	lw	t1, (t0)		# number of wired TLB entries
+	move	t2, zero		# TLB entry counter
+	addiu	t3, t1, 1		# wire one additional entry
+	beqz	t1, 2f			# null, exit
+	 nop
+
+	addiu	t0, 8
+1:
+	lw	t4, 24(t0)		# PageMask
+	ld	t5,  0(t0)		# entryHi
+	ld	t6,  8(t0)		# entryLo0
+	addiu	t2, 1			# increment ctr
+	mtc0	t2, CP0_INDEX		# set TLB entry
+	nop
+	mtc0	t5, CP0_ENTRYHI
+	nop
+	mtc0	t6, CP0_ENTRYLO0
+	addiu	t0, 32
+	bne	t1, t2, 1b		# next TLB entry
+	 tlbwi
+
+	/* We use only 4k pages. Therefore the PageMask register
+	 * is expected to be setup for 4k pages.
+	 */
+2:
+	/* Now map the pagetables */
+	mtc0	zero, CP0_INDEX
+	la	t0, TLB_ROOT
+	mtc0	t0, CP0_ENTRYHI
+	nop
+	la	t0, swapper_pg_dir
+	srl	t0, 12
+	ori	t0, (0x00e0|0x0100)	# uncachable, dirty, valid
+	mtc0	t0, CP0_ENTRYLO0
+	nop
+	tlbwi				# delayed
+
+	/* Load the context register with zero.  To see why, look
+	 * at how the tlb refill code above works.
+	 */
+	mtc0	zero, CP0_CONTEXT
+
+	jr	ra
+	 nop
+	END(wire_mappings_r3000)
+
+	/* CPU type probing code, called at Kernel entry. */
+	LEAF(cpu_probe)
+	mfc0	t0, CP0_PRID
+	la	t3, mips_cputype
+	andi	t1, t0, 0xff00
+	li	t2, PRID_IMP_R2000
+	bne	t1, t2, 1f
+	 andi	t0, 0x00ff
+
+	li	t2, CPU_R2000
+	b	probe_done
+	 sw	t2, (t3)
+1:
+	li	t2, PRID_IMP_R3000
+	bne	t1, t2, 1f
+	 nop
+
+	li	t2, PRID_REV_R3000A
+	bne	t0, t2, 9f
+	 nop
+
+	li	t2, CPU_R3000A
+	b	probe_done
+	sw	t2, (t3)
+9:
+	li	t2, CPU_R3000
+	b	probe_done
+	 sw	t2, (t3)
+1:
+	li	t2, PRID_IMP_R6000
+	bne	t1, t2, 1f
+	 nop
+
+	li	t2, CPU_R6000
+	b	probe_done
+	 sw	t2, (t3)
+1:
+	li	t2, PRID_IMP_R4000
+	bne	t1, t2, 1f
+	 nop
+
+	li	t2, PRID_REV_R4400
+	bne	t0, t2, 9f
+	 nop
+
+	li	t2, CPU_R4400SC
+	b	probe_done
+	 sw	t2, (t3)
+9:
+	li	t2, CPU_R4000SC
+	b	probe_done
+	 sw	t2, (t3)
+1:
+	li	t2, PRID_IMP_R6000A
+	bne	t1, t2, 1f
+	 nop
+
+	li	t2, CPU_R6000A
+	b	probe_done
+	 sw	t2, (t3)
+1:
+	li	t2, PRID_IMP_R10000
+	bne	t1, t2, 1f
+	 nop
+
+	li	t2, CPU_R10000
+	b	probe_done
+	 sw	t2, (t3)
+1:
+	li	t2, PRID_IMP_R8000
+	bne	t1, t2, 1f
+	 nop
+
+	li	t2, CPU_R8000
+	b	probe_done
+	 sw	t2, (t3)
+1:
+	li	t2, PRID_IMP_R4600
+	bne	t1, t2, 1f
+	 nop
+
+	li	t2, CPU_R4600
+	b	probe_done
+	 sw	t2, (t3)
+1:
+	li	t2, PRID_IMP_R4700
+	bne	t1, t2, 1f
+	 nop
+
+	li	t2, CPU_R4700
+	b	probe_done
+	 sw	t2, (t3)
+1:
+	li	t2, PRID_IMP_R4650
+	bne	t1, t2, 1f
+	 nop
+
+	li	t2, CPU_R4650
+	b	probe_done
+	 sw	t2, (t3)
+1:
+	li	t2, PRID_IMP_R5000
+	bne	t1, t2, 1f
+	 nop
+
+	li	t2, CPU_R5000
+	b	probe_done
+	 sw	t2, (t3)
+1:
+	li	t2, CPU_UNKNOWN
+	sw	t2, (t3)
+
+	b	probe_done
+	 nop
+	END(cpu_probe)
 
-		.data
+	.data
 /*
  * Build an entry for table of wired entries
  */
@@ -269,6 +628,11 @@
  * following by EntryHi/EntryLo pairs and page mask.
  * Since everything must be quad-aligned (8) we insert
  * some dummy zeros.
+ *
+ * Keep in mind that the PFN does not depend on the page size in the
+ * TLB page mask register.  See milo's lib/dumptlb.c for how to decode
+ * and encode these entries.  Don't see the same routine in the linux
+ * kernel distribution, since it is older and unreliable.
  */
 
 /*
@@ -282,19 +646,25 @@
 		PTR	map0_tyne		# Deskstation Tyne
 		PTR	map0_pica61		# Acer Pica-61
 		PTR	map0_magnum4000		# MIPS Magnum 4000PC (RC4030)
+		PTR	map0_dummy
+		PTR	map0_dummy		# DEC Personal DECStation 5000/2x (for now)
+		PTR	map0_sni_rm200_pci	# SNI RM200 PCI
+		PTR	map0_dummy		# SGI INDY
 
 map0_dummy:	.word	0			# 0 entries
 
 		.align  3
 /*
- * Initial mappings for Deskstation rPC boards.
- * RB: Untested goodie - I don't have such a board.
+ * Deskstation rpc44 mappings.  This machine has its EISA bus at physical
+ * address 0xa0000000 which we map for 32M, but that doesn't match EISA
+ * spec.  Not sure what to do about this.  Its I/O ports are memory mapped
+ * at physical memory location 0xb0000000.
  */
 map0_rpc: 	.word   2			# no. of wired TLB entries
 		.word	0			# pad for alignment
 
-MAPDATA(0xffffffffe0000000, 0x04020017, 0x00000001, PM_1M)	# VESA DMA cache
-MAPDATA(0xffffffffe2000000, 0x24000017, 0x04000017, PM_16M)	# VESA I/O and memory space
+MAPDATA(0xffffffffe0000000, 0x02800017, 0x00000001, PM_16M)	# ISA Memory space
+MAPDATA(0xffffffffe2000000, 0x02c00017, 0x00000001, PM_64K)	# ISA I/O Space
 
 /*
  * Initial mappings for Deskstation Tyne boards.
@@ -330,51 +700,52 @@
  * Do you believe me now that the Acer and Mips boxes are nearly the same ? :-)
  * FIXME: Remove or merge some of the mappings.
  */
-
 map0_magnum4000:
 		.word  	8			# no. wired TLB entries
 		.word	0			# dummy
 
-MAPDATA(0xffffffffe1000000, 0x03ffc013, 0x00000001, 0x7e000)	# 0
-MAPDATA(0xffffffffe0000000, 0x02000017, 0x00000001, 0x1e000)	# 1 local I/O
-MAPDATA(0xffffffffe0100000, 0x03c00017, 0x00000001, 0)		# 2 IRQ source
-MAPDATA(0xffffffffe0200000, 0x01800017, 0x01804017, 0x1fe000)	# 3 local video ctrl
-MAPDATA(0xffffffffe0400000, 0x01808017, 0x0180c017, 0x1fe000)	# 4 ext. video ctrl
-MAPDATA(0xffffffffe0800000, 0x01000017, 0x01010017, 0x7fe000)	# 5 local video mem.
-MAPDATA(0xffffffffe2000000, 0x02400017, 0x02440017, 0x1ffe000)	# 6 ISA I/O and mem.
-MAPDATA(0xffffffffffffe000, 0x00000001, 0x0001ffd7, 0)		# 7 PCR
+MAPDATA(0xffffffffe1000000, 0x03ffc013, 0x00000001, PM_256K)	# 0
+MAPDATA(0xffffffffe0000000, 0x02000017, 0x00000001, PM_64K)	# 1 local I/O
+MAPDATA(0xffffffffe0100000, 0x03c00017, 0x00000001, PM_4K)	# 2 IRQ source
+MAPDATA(0xffffffffe0200000, 0x01800017, 0x01804017, PM_1M)	# 3 local video ctrl
+MAPDATA(0xffffffffe0400000, 0x01808017, 0x0180c017, PM_1M)	# 4 ext. video ctrl
+MAPDATA(0xffffffffe0800000, 0x01000017, 0x01010017, PM_4M)	# 5 local video mem.
+MAPDATA(0xffffffffe2000000, 0x02400017, 0x02440017, PM_16M)	# 6 ISA I/O and mem.
+MAPDATA(0xffffffffffffe000, 0x00000001, 0x0001ffd7, PM_4K)	# 7 PCR
 
+/*
+ * The RM200 doesn't need any wired entries.
+ */
+map0_sni_rm200_pci:
+		.word  	0			# no. wired TLB entries
+		.word	0			# dummy
 
 			.text
 
 			.org	0x1000
-			.globl	swapper_pg_dir
-swapper_pg_dir		=	. + (KSEG1-KSEG0)
+			EXPORT(swapper_pg_dir)
 
-/*
- * The page tables are initialized to only 4MB here - the final page
- * tables are set up later depending on memory size.
- */
 			.org	0x2000
-			EXPORT(pg0)
-
-			.org	0x3000
 			EXPORT(empty_bad_page)
 
-			.org	0x4000
+			.org	0x3000
 			EXPORT(empty_bad_page_table)
 
-			.org	0x5000
+			.org	0x4000
 			EXPORT(empty_zero_page)
 
-			.org	0x6000
+			.org	0x5000
 			EXPORT(invalid_pte_table)
 
-			.org	0x7000
+			.org	0x6000
 
+			/*
+			 * init_task_union follows here in the .text segment.
+			 * Keep this aligned to a 8kb boundary!
+			 */
+			.data
 			EXPORT(cache_error_buffer)
 			.fill	32*4,1,0
 
-			.data
 			EXPORT(kernelsp)
 			PTR	0

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov