Subject: Re: port-mips/31915: provide centralized wired_map logic
To: None <tsutsui@netbsd.org, gnats-admin@netbsd.org,>
From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
List: netbsd-bugs
Date: 11/03/2005 16:31:04
The following reply was made to PR port-mips/31915; it has been noted by GNATS.

From: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
To: garrett_damore@tadpole.com
Cc: soda@sra.co.jp, gnats-bugs@NetBSD.org, port-mips@NetBSD.org,
	tsutsui@ceres.dti.ne.jp
Subject: Re: port-mips/31915: provide centralized wired_map logic
Date: Fri, 4 Nov 2005 01:30:53 +0900

 In article <436A3650.5070402@tadpole.com>
 garrett_damore@tadpole.com wrote:
 
 > >>+	/* TLB entries come in pairs: this is the first address of the pair */
 > >>+	va0 = va & ~pgsz;
 > >This va0 should be double entry size aligned, i.e.
 > >>	va0 = va & ~(pgsz * 2 - 1);
 > >is right?
 
 > Yes.  But we have already asserted that none of the low bits are set.  
 > So my original is also correct.  Your version may be clearer, but it 
 > uses two additional instructions.
 
 This function would not be called so often, so clearer is better
 than a bit less instructions, IMHO.
 I also add some macro MIPS3_WIRED_ENTRY_OFFMASK(pgsize) for this.
 
 
 Now my arc (NEC-JC94, which has tga, ex, and acardide at pci)
 works fine. I'll integrate the attached patch in this weekend
 if there is no objection.
 ---
 Izumi Tsutsui
 
 
 Index: arc/arc/bus_space_large.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/arc/bus_space_large.c,v
 retrieving revision 1.4
 diff -u -r1.4 bus_space_large.c
 --- arc/arc/bus_space_large.c	22 Jan 2005 07:35:33 -0000	1.4
 +++ arc/arc/bus_space_large.c	3 Nov 2005 15:57:09 -0000
 @@ -51,7 +51,7 @@
   * - If requested region size >= ARC_THRESHOLD_TO_USE_WIRED_TLB,
   *   and enough wired TLBs are still free.
   *	In this case, the size of wired TLBs becomes always
 - *	ARC_WIRED_PAGE_SIZE (i.e. 16MB). (See wired_map.c for detail.)
 + *	MIPS3_WIRED_SIZE (i.e. 16MB). (See wired_map_machdep.c for detail.)
   */
  
  #include <sys/cdefs.h>
 @@ -65,7 +65,7 @@
  #include <uvm/uvm_extern.h>
  
  #include <machine/bus.h>
 -#include <arc/arc/wired_map.h>
 +#include <machine/wired_map.h>
  
  static int arc_large_bus_space_compose_handle(bus_space_tag_t, bus_addr_t,
      bus_size_t, int, bus_space_handle_t *);
 Index: arc/arc/c_magnum.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/arc/c_magnum.c,v
 retrieving revision 1.11
 diff -u -r1.11 c_magnum.c
 --- arc/arc/c_magnum.c	30 Oct 2005 05:27:14 -0000	1.11
 +++ arc/arc/c_magnum.c	3 Nov 2005 15:57:10 -0000
 @@ -91,13 +91,13 @@
  #include <machine/bus.h>
  #include <machine/pio.h>
  #include <machine/platform.h>
 +#include <machine/wired_map.h>
  #include <mips/locore.h>
  #include <mips/pte.h>
  
  #include <dev/isa/isavar.h>
  
  #include <arc/arc/timervar.h>
 -#include <arc/arc/wired_map.h>
  #include <arc/jazz/pica.h>
  #include <arc/jazz/jazziovar.h>
  #include <arc/jazz/timer_jazziovar.h>
 @@ -266,10 +266,13 @@
  	/*
  	 * Initialize wired TLB for I/O space which is used on early stage
  	 */
 -	arc_enter_wired(R4030_V_LOCAL_IO_BASE, R4030_P_LOCAL_IO_BASE,
 -	    PICA_P_INT_SOURCE, MIPS3_PG_SIZE_256K);
 -	arc_enter_wired(PICA_V_ISA_IO, PICA_P_ISA_IO, PICA_P_ISA_MEM,
 -	    MIPS3_PG_SIZE_16M);
 +	arc_wired_enter_page(R4030_V_LOCAL_IO_BASE, R4030_P_LOCAL_IO_BASE,
 +	    R4030_S_LOCAL_IO_BASE);
 +	arc_wired_enter_page(PICA_V_INT_SOURCE, PICA_P_INT_SOURCE,
 +	    R4030_S_LOCAL_IO_BASE);
 +
 +	arc_wired_enter_page(PICA_V_ISA_IO, PICA_P_ISA_IO, PICA_S_ISA_IO);
 +	arc_wired_enter_page(PICA_V_ISA_MEM, PICA_P_ISA_MEM, PICA_S_ISA_MEM);
  
  	/*
  	 * Initialize interrupt priority
 Index: arc/arc/c_nec_eisa.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/arc/c_nec_eisa.c,v
 retrieving revision 1.8
 diff -u -r1.8 c_nec_eisa.c
 --- arc/arc/c_nec_eisa.c	22 Jan 2005 07:35:33 -0000	1.8
 +++ arc/arc/c_nec_eisa.c	3 Nov 2005 15:57:10 -0000
 @@ -43,12 +43,12 @@
  #include <machine/autoconf.h>
  #include <machine/pio.h>
  #include <machine/platform.h>
 +#include <machine/wired_map.h>
  #include <mips/pte.h>
  
  #include <dev/isa/isavar.h>
  
  #include <arc/arc/arcbios.h>
 -#include <arc/arc/wired_map.h>
  #include <arc/jazz/pica.h>
  #include <arc/jazz/rd94.h>
  #include <arc/jazz/jazziovar.h>
 @@ -170,10 +170,11 @@
  	/*
  	 * Initialize wired TLB for I/O space which is used on early stage
  	 */
 -	arc_enter_wired(RD94_V_LOCAL_IO_BASE, RD94_P_LOCAL_IO_BASE, 0,
 -	    MIPS3_PG_SIZE_256K);
 -	arc_enter_wired(RD94_V_EISA_IO, RD94_P_EISA_IO, RD94_P_EISA_MEM,
 -	    MIPS3_PG_SIZE_16M);
 +	arc_wired_enter_page(RD94_V_LOCAL_IO_BASE, RD94_P_LOCAL_IO_BASE,
 +	    RD94_S_LOCAL_IO_BASE);
 +
 +	arc_wired_enter_page(RD94_V_EISA_IO, RD94_P_EISA_IO, RD94_S_EISA_IO);
 +	arc_wired_enter_page(RD94_V_EISA_MEM, RD94_P_EISA_MEM, RD94_S_EISA_MEM);
  
  	/*
  	 * Initialize interrupt priority
 Index: arc/arc/c_nec_pci.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/arc/c_nec_pci.c,v
 retrieving revision 1.11
 diff -u -r1.11 c_nec_pci.c
 --- arc/arc/c_nec_pci.c	3 Jun 2005 12:30:53 -0000	1.11
 +++ arc/arc/c_nec_pci.c	3 Nov 2005 15:57:10 -0000
 @@ -43,6 +43,7 @@
  #include <machine/bus.h>
  #include <machine/pio.h>
  #include <machine/platform.h>
 +#include <machine/wired_map.h>
  #include <mips/pte.h>
  
  #include <dev/clock_subr.h>
 @@ -51,7 +52,6 @@
  #include <dev/pci/pcivar.h>
  
  #include <arc/arc/arcbios.h>
 -#include <arc/arc/wired_map.h>
  #include <arc/jazz/pica.h>
  #include <arc/jazz/rd94.h>
  #include <arc/jazz/jazziovar.h>
 @@ -218,10 +218,14 @@
  	/*
  	 * Initialize wired TLB for I/O space which is used on early stage
  	 */
 -	arc_enter_wired(RD94_V_LOCAL_IO_BASE, RD94_P_LOCAL_IO_BASE, 0,
 -	    MIPS3_PG_SIZE_256K);
 -	arc_enter_wired(RD94_V_PCI_IO, RD94_P_PCI_IO, RD94_P_PCI_MEM,
 -	    MIPS3_PG_SIZE_16M);
 +	arc_wired_enter_page(RD94_V_LOCAL_IO_BASE, RD94_P_LOCAL_IO_BASE,
 +	    RD94_S_LOCAL_IO_BASE);
 +	/*
 +	 * allocate only 16M for PCM MEM space for now to save wired TLB entry;
 +	 * Other regions will be allocalted by bus_space_large.c later.
 +	 */
 +	arc_wired_enter_page(RD94_V_PCI_IO, RD94_P_PCI_IO, RD94_S_PCI_IO);
 +	arc_wired_enter_page(RD94_V_PCI_MEM, RD94_P_PCI_MEM, RD94_S_PCI_IO);
  
  	/*
  	 * By default, reserve 32MB in KSEG2 for PCI memory space.
 Index: arc/arc/locore_machdep.S
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/arc/locore_machdep.S,v
 retrieving revision 1.13
 diff -u -r1.13 locore_machdep.S
 --- arc/arc/locore_machdep.S	1 Oct 2005 02:05:19 -0000	1.13
 +++ arc/arc/locore_machdep.S	3 Nov 2005 15:57:10 -0000
 @@ -332,54 +332,3 @@
  	nop
  END(mdbpanic)
  #endif /* DEBUG */
 -
 -	.set	mips3
 -
 -/*--------------------------------------------------------------------------
 - *
 - * mips3_TLBWriteIndexedVPS --
 - *
 - *	Write the given entry into the TLB at the given index.
 - *	Pass full r4000 tlb info including variable page size mask.
 - *
 - *	mips3_TLBWriteIndexed(unsigned int index, struct tlb *tlb)
 - *
 - * Results:
 - *	None.
 - *
 - * Side effects:
 - *	TLB entry set.
 - *
 - *--------------------------------------------------------------------------
 - */
 -LEAF(mips3_TLBWriteIndexedVPS)
 -	mfc0	v1, MIPS_COP_0_STATUS		# Save the status register.
 -	mtc0	zero, MIPS_COP_0_STATUS		# Disable interrupts
 -	nop
 -	lw	a2, 8(a1)
 -	lw	a3, 12(a1)
 -	mfc0	v0, MIPS_COP_0_TLB_PG_MASK	# Save current PageMask.
 -	dmfc0	t0, MIPS_COP_0_TLB_HI		# Save the current PID.
 -
 -	dmtc0	a2, MIPS_COP_0_TLB_LO0		# Set up EntryLo0.
 -	dmtc0	a3, MIPS_COP_0_TLB_LO1		# Set up EntryLo1.
 -	nop
 -	lw	a2, 0(a1)
 -	lw	a3, 4(a1)
 -	nop
 -	mtc0	a0, MIPS_COP_0_TLB_INDEX	# Set the Index.
 -	mtc0	a2, MIPS_COP_0_TLB_PG_MASK	# Set up PageMask.
 -	dmtc0	a3, MIPS_COP_0_TLB_HI		# Set up EntryHi.
 -	nop
 -	tlbwi					# Write the TLB
 -	nop
 -	nop
 -	nop					# Delay for effect
 -	nop
 -
 -	dmtc0	t0, MIPS_COP_0_TLB_HI		# Restore the PID.
 -	nop
 -	mtc0	v0, MIPS_COP_0_TLB_PG_MASK	# Restore PageMask.
 -	j	ra
 -	mtc0	v1, MIPS_COP_0_STATUS		# Restore the status register
 -END(mips3_TLBWriteIndexedVPS)
 Index: arc/arc/machdep.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/arc/machdep.c,v
 retrieving revision 1.91
 diff -u -r1.91 machdep.c
 --- arc/arc/machdep.c	30 Oct 2005 05:27:14 -0000	1.91
 +++ arc/arc/machdep.c	3 Nov 2005 15:57:10 -0000
 @@ -121,6 +121,7 @@
  #include <machine/trap.h>
  #include <machine/autoconf.h>
  #include <machine/platform.h>
 +#include <machine/wired_map.h>
  #include <mips/pte.h>
  #include <mips/locore.h>
  #include <mips/cpuregs.h>
 @@ -138,7 +139,6 @@
  
  #include <arc/arc/arcbios.h>
  #include <arc/arc/timervar.h>
 -#include <arc/arc/wired_map.h>
  
  #include "ksyms.h"
  
 Index: arc/arc/p_dti_tyne.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/arc/p_dti_tyne.c,v
 retrieving revision 1.9
 diff -u -r1.9 p_dti_tyne.c
 --- arc/arc/p_dti_tyne.c	3 Jun 2005 12:30:53 -0000	1.9
 +++ arc/arc/p_dti_tyne.c	3 Nov 2005 15:57:11 -0000
 @@ -87,13 +87,13 @@
  #include <machine/bus.h>
  #include <machine/pio.h>
  #include <machine/platform.h>
 +#include <machine/wired_map.h>
  #include <mips/pte.h>
  
  #include <dev/isa/isareg.h>
  #include <dev/isa/isavar.h>
  #include <dev/ic/i8042reg.h>
  
 -#include <arc/arc/wired_map.h>
  #include <arc/dti/desktech.h>
  
  void arc_sysreset(bus_addr_t, bus_size_t);
 @@ -276,10 +276,13 @@
  	/*
  	 * Initialize wired TLB for I/O space which is used on early stage
  	 */
 -	arc_enter_wired(TYNE_V_BOUNCE, TYNE_P_BOUNCE, 0, MIPS3_PG_SIZE_256K);
 -	arc_enter_wired(TYNE_V_ISA_IO, TYNE_P_ISA_IO, 0, MIPS3_PG_SIZE_1M);
 -	arc_enter_wired(TYNE_V_ISA_MEM, TYNE_P_ISA_MEM, 0, MIPS3_PG_SIZE_1M);
 -	arc_enter_wired(0xe3000000, 0xfff00000, 0, MIPS3_PG_SIZE_4K);
 +	arc_wired_enter_page(TYNE_V_BOUNCE, TYNE_P_BOUNCE, TYNE_S_BOUNCE);
 +
 +	arc_wired_enter_page(TYNE_V_ISA_IO, TYNE_P_ISA_IO, TYNE_S_ISA_IO);
 +	arc_wired_enter_page(TYNE_V_ISA_MEM, TYNE_P_ISA_MEM, TYNE_S_ISA_MEM);
 +
 +	arc_wired_enter_page(0xe3000000, 0xfff00000,
 +	    MIPS3_PG_SIZE_MASK_TO_SIZE(MIPS3_PG_SIZE_4K));
  
  	/*
  	 * Initialize interrupt priority
 Index: arc/conf/files.arc
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/conf/files.arc,v
 retrieving revision 1.51
 diff -u -r1.51 files.arc
 --- arc/conf/files.arc	8 Jul 2004 22:07:47 -0000	1.51
 +++ arc/conf/files.arc	3 Nov 2005 15:57:11 -0000
 @@ -75,7 +75,7 @@
  file	arch/arc/arc/bus_space_sparse.c
  file	arch/arc/arc/bus_space_large.c
  file	arch/arc/arc/bus_dma.c
 -file	arch/arc/arc/wired_map.c
 +file	arch/arc/arc/wired_map_machdep.c
  
  file	arch/arc/arc/arcbios.c
  
 Index: arc/conf/std.arc
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/conf/std.arc,v
 retrieving revision 1.18
 diff -u -r1.18 std.arc
 --- arc/conf/std.arc	17 Sep 2005 09:44:06 -0000	1.18
 +++ arc/conf/std.arc	3 Nov 2005 15:57:11 -0000
 @@ -12,6 +12,9 @@
  #options 	MIPS1			# R2000/R3000 support
  options 	MIPS3			# R4000/R4400 support
  
 +# arc port use wired map for device space
 +options 	ENABLE_MIPS3_WIRED_MAP
 +
  # Standard (non-optional) system "options"
  
  # Standard exec-package options
 Index: arc/include/cpu.h
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/include/cpu.h,v
 retrieving revision 1.18
 diff -u -r1.18 cpu.h
 --- arc/include/cpu.h	22 Jan 2005 07:35:34 -0000	1.18
 +++ arc/include/cpu.h	3 Nov 2005 15:57:11 -0000
 @@ -20,9 +20,4 @@
  
  #define	INT_MASK_REAL_DEV	MIPS3_HARD_INT_MASK	/* XXX */
  
 -#ifndef _LOCORE
 -struct tlb;
 -extern void mips3_TLBWriteIndexedVPS(u_int index, struct tlb *tlb);
 -#endif /* ! _LOCORE */
 -
  #endif /* _ARC_CPU_H_ */
 Index: arc/include/vmparam.h
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/include/vmparam.h,v
 retrieving revision 1.7
 diff -u -r1.7 vmparam.h
 --- arc/include/vmparam.h	10 Dec 2002 05:14:26 -0000	1.7
 +++ arc/include/vmparam.h	3 Nov 2005 15:57:11 -0000
 @@ -4,6 +4,13 @@
  
  #include <mips/vmparam.h>
  
 +/* VA 0xe0000000-0xffffffff is used for wired_map TLB entries. */
 +#undef  VM_MAX_KERNEL_ADDRESS
 +#define VM_MAX_KERNEL_ADDRESS		((vaddr_t)0xDFFFF000)
 +
 +#define VM_MIN_WIRED_MAP_ADDRESS	((vaddr_t)0xE0000000)
 +#define VM_MAX_WIRED_MAP_ADDRESS	((vaddr_t)0xFFFFC000)
 +
  /*
   * Maximum number of contigous physical memory segment.
   */
 Index: arc/jazz/pccons_jazzio.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/jazz/pccons_jazzio.c,v
 retrieving revision 1.5
 diff -u -r1.5 pccons_jazzio.c
 --- arc/jazz/pccons_jazzio.c	22 Jan 2005 07:35:34 -0000	1.5
 +++ arc/jazz/pccons_jazzio.c	3 Nov 2005 15:57:11 -0000
 @@ -38,10 +38,10 @@
  
  #include <machine/autoconf.h>
  #include <machine/bus.h>
 +#include <machine/wired_map.h>
  
  #include <mips/pte.h>
  
 -#include <arc/arc/wired_map.h>
  #include <arc/dev/pcconsvar.h>
  #include <arc/jazz/jazziovar.h>
  #include <arc/jazz/pica.h>
 @@ -97,19 +97,30 @@
  		    PICA_P_LOCAL_VIDEO, PICA_V_LOCAL_VIDEO,
  		    0, PICA_S_LOCAL_VIDEO);
  
 -		arc_enter_wired(PICA_V_LOCAL_VIDEO_CTRL,
 +		arc_wired_enter_page(
 +		    PICA_V_LOCAL_VIDEO_CTRL,
  		    PICA_P_LOCAL_VIDEO_CTRL,
 -		    PICA_P_LOCAL_VIDEO_CTRL + PICA_S_LOCAL_VIDEO_CTRL/2,
 -		    MIPS3_PG_SIZE_1M);
 -		arc_enter_wired(PICA_V_LOCAL_VIDEO,
 +		    PICA_S_LOCAL_VIDEO_CTRL / 2);
 +		arc_wired_enter_page(
 +		    PICA_V_LOCAL_VIDEO_CTRL + PICA_S_LOCAL_VIDEO_CTRL / 2,
 +		    PICA_P_LOCAL_VIDEO_CTRL + PICA_S_LOCAL_VIDEO_CTRL / 2,
 +		    PICA_S_LOCAL_VIDEO_CTRL / 2);
 +
 +		arc_wired_enter_page(PICA_V_LOCAL_VIDEO,
  		    PICA_P_LOCAL_VIDEO,
 -		    PICA_P_LOCAL_VIDEO + PICA_S_LOCAL_VIDEO/2,
 -		    MIPS3_PG_SIZE_4M);
 +		    PICA_S_LOCAL_VIDEO / 2);
 +		arc_wired_enter_page(
 +		    PICA_V_LOCAL_VIDEO + PICA_S_LOCAL_VIDEO / 2,
 +		    PICA_P_LOCAL_VIDEO + PICA_S_LOCAL_VIDEO / 2,
 +		    PICA_S_LOCAL_VIDEO / 2);
  #if 0
 -		arc_enter_wired(PICA_V_EXTND_VIDEO_CTRL,
 +		arc_wired_enter_page(PICA_V_EXTND_VIDEO_CTRL,
  		    PICA_P_EXTND_VIDEO_CTRL,
 -		    PICA_P_EXTND_VIDEO_CTRL + PICA_S_EXTND_VIDEO_CTRL/2,
 -		    MIPS3_PG_SIZE_1M);
 +		    PICA_S_EXTND_VIDEO_CTRL / 2);
 +		arc_wired_enter_page(
 +		    PICA_V_EXTND_VIDEO_CTRL + PICA_S_EXTND_VIDEO_CTRL / 2,
 +		    PICA_P_EXTND_VIDEO_CTRL + PICA_S_EXTND_VIDEO_CTRL / 2,
 +		    PICA_S_EXTND_VIDEO_CTRL / 2);
  #endif
  	}
  	*iotp = &vga_io;
 Index: arc/jazz/vga_jazzio.c
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/arc/jazz/vga_jazzio.c,v
 retrieving revision 1.12
 diff -u -r1.12 vga_jazzio.c
 --- arc/jazz/vga_jazzio.c	3 Jun 2005 12:30:53 -0000	1.12
 +++ arc/jazz/vga_jazzio.c	3 Nov 2005 15:57:11 -0000
 @@ -40,6 +40,7 @@
  
  #include <machine/autoconf.h>
  #include <machine/bus.h>
 +#include <machine/wired_map.h>
  
  #include <mips/pte.h>
  
 @@ -48,7 +49,6 @@
  #include <dev/ic/vgareg.h>
  #include <dev/ic/vgavar.h>
  
 -#include <arc/arc/wired_map.h>
  #include <arc/jazz/jazziovar.h>
  #include <arc/jazz/pica.h>
  #include <arc/jazz/vga_jazziovar.h>
 @@ -91,19 +91,29 @@
  		    PICA_P_LOCAL_VIDEO, PICA_V_LOCAL_VIDEO,
  		    0, PICA_S_LOCAL_VIDEO);
  
 -		arc_enter_wired(PICA_V_LOCAL_VIDEO_CTRL,
 +		arc_wired_enter_page(PICA_V_LOCAL_VIDEO_CTRL,
  		    PICA_P_LOCAL_VIDEO_CTRL,
 +		    PICA_S_LOCAL_VIDEO_CTRL / 2);
 +		arc_wired_enter_page(
 +		    PICA_V_LOCAL_VIDEO_CTRL + PICA_S_LOCAL_VIDEO_CTRL/2,
  		    PICA_P_LOCAL_VIDEO_CTRL + PICA_S_LOCAL_VIDEO_CTRL/2,
 -		    MIPS3_PG_SIZE_1M);
 -		arc_enter_wired(PICA_V_LOCAL_VIDEO,
 +		    PICA_S_LOCAL_VIDEO_CTRL / 2);
 +
 +		arc_wired_enter_page(PICA_V_LOCAL_VIDEO,
  		    PICA_P_LOCAL_VIDEO,
 -		    PICA_P_LOCAL_VIDEO + PICA_S_LOCAL_VIDEO/2,
 -		    MIPS3_PG_SIZE_4M);
 +		    PICA_S_LOCAL_VIDEO / 2);
 +		arc_wired_enter_page(
 +		    PICA_V_LOCAL_VIDEO + PICA_S_LOCAL_VIDEO / 2,
 +		    PICA_P_LOCAL_VIDEO + PICA_S_LOCAL_VIDEO / 2,
 +		    PICA_S_LOCAL_VIDEO / 2);
  #if 0
 -		arc_enter_wired(PICA_V_EXTND_VIDEO_CTRL,
 +		arc_wired_enter_page(PICA_V_EXTND_VIDEO_CTRL,
  		    PICA_P_EXTND_VIDEO_CTRL,
 -		    PICA_P_EXTND_VIDEO_CTRL + PICA_S_EXTND_VIDEO_CTRL/2,
 -		    MIPS3_PG_SIZE_1M);
 +		    PICA_S_EXTND_VIDEO_CTRL / 2);
 +		arc_wired_enter_page(
 +		    PICA_V_EXTND_VIDEO_CTRL + PICA_S_EXTND_VIDEO_CTRL / 2,
 +		    PICA_P_EXTND_VIDEO_CTRL + PICA_S_EXTND_VIDEO_CTRL / 2,
 +		    PICA_S_EXTND_VIDEO_CTRL / 2);
  #endif
  	}
  	*iotp = &vga_io;
 Index: mips/conf/files.mips
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/mips/conf/files.mips,v
 retrieving revision 1.51
 diff -u -r1.51 files.mips
 --- mips/conf/files.mips	24 Jan 2005 10:03:57 -0000	1.51
 +++ mips/conf/files.mips	3 Nov 2005 15:57:13 -0000
 @@ -13,6 +13,7 @@
  					# ENABLE_MIPS_R3NKK
  defflag	opt_mips_cache.h		MIPS3_NO_PV_UNCACHED
  					ENABLE_MIPS4_CACHE_R10K
 +defflag opt_mips3_wired.h		ENABLE_MIPS3_WIRED_MAP
  
  file	arch/mips/mips/locore_mips1.S		mips1
  file	arch/mips/mips/locore_mips3.S		mips3 | mips4 | mips32 | mips64
 @@ -37,6 +38,7 @@
  file	arch/mips/mips/vm_machdep.c
  file	arch/mips/mips/process_machdep.c
  file	arch/mips/mips/cpu_exec.c
 +file	arch/mips/mips/wired_map.c (mips3|mips4|mips32|mips64) & enable_mips3_wired_map
  
  file	arch/mips/mips/cache.c
  file	arch/mips/mips/cache_r3k.c		mips1
 Index: mips/include/locore.h
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/mips/include/locore.h,v
 retrieving revision 1.70
 diff -u -r1.70 locore.h
 --- mips/include/locore.h	30 Oct 2005 04:40:43 -0000	1.70
 +++ mips/include/locore.h	3 Nov 2005 15:57:13 -0000
 @@ -57,6 +57,7 @@
  void	mips3_TBIS(vaddr_t);
  int	mips3_TLBUpdate(u_int, u_int);
  void	mips3_TLBRead(int, struct tlb *);
 +void	mips3_TLBWriteIndexedVPS(int, struct tlb *);
  void	mips3_wbflush(void);
  void	mips3_proc_trampoline(void);
  void	mips3_cpu_switch_resume(void);
 @@ -69,6 +70,7 @@
  void	mips5900_TBIS(vaddr_t);
  int	mips5900_TLBUpdate(u_int, u_int);
  void	mips5900_TLBRead(int, struct tlb *);
 +void	mips5900_TLBWriteIndexedVPS(int, struct tlb *);
  void	mips5900_wbflush(void);
  void	mips5900_proc_trampoline(void);
  void	mips5900_cpu_switch_resume(void);
 @@ -83,6 +85,7 @@
  void	mips32_TBIS(vaddr_t);
  int	mips32_TLBUpdate(u_int, u_int);
  void	mips32_TLBRead(int, struct tlb *);
 +void	mips32_TLBWriteIndexedVPS(int, struct tlb *);
  void	mips32_wbflush(void);
  void	mips32_proc_trampoline(void);
  void	mips32_cpu_switch_resume(void);
 @@ -95,6 +98,7 @@
  void	mips64_TBIS(vaddr_t);
  int	mips64_TLBUpdate(u_int, u_int);
  void	mips64_TLBRead(int, struct tlb *);
 +void	mips64_TLBWriteIndexedVPS(int, struct tlb *);
  void	mips64_wbflush(void);
  void	mips64_proc_trampoline(void);
  void	mips64_cpu_switch_resume(void);
 @@ -228,6 +232,7 @@
  #define MIPS_TBIAP()		mips3_TBIAP(mips_num_tlb_entries)
  #define MIPS_TBIS		mips3_TBIS
  #define MachTLBUpdate		mips3_TLBUpdate
 +#define MachTLBWriteIndexedVPS	mips3_TLBWriteIndexedVPS
  #define proc_trampoline		mips3_proc_trampoline
  #define wbflush()		mips3_wbflush()
  #elif !defined(MIPS1) && !defined(MIPS3) &&  defined(MIPS32) && !defined(MIPS64)
 @@ -235,6 +240,7 @@
  #define MIPS_TBIAP()		mips32_TBIAP(mips_num_tlb_entries)
  #define MIPS_TBIS		mips32_TBIS
  #define MachTLBUpdate		mips32_TLBUpdate
 +#define MachTLBWriteIndexedVPS	mips32_TLBWriteIndexedVPS
  #define proc_trampoline		mips32_proc_trampoline
  #define wbflush()		mips32_wbflush()
  #elif !defined(MIPS1) && !defined(MIPS3) && !defined(MIPS32) &&  defined(MIPS64)
 @@ -243,6 +249,7 @@
  #define MIPS_TBIAP()		mips64_TBIAP(mips_num_tlb_entries)
  #define MIPS_TBIS		mips64_TBIS
  #define MachTLBUpdate		mips64_TLBUpdate
 +#define MachTLBWriteIndexedVPS	mips64_TLBWriteIndexedVPS
  #define proc_trampoline		mips64_proc_trampoline
  #define wbflush()		mips64_wbflush()
  #elif !defined(MIPS1) &&  defined(MIPS3) && !defined(MIPS32) && !defined(MIPS64) && defined(MIPS3_5900)
 @@ -250,6 +257,7 @@
  #define MIPS_TBIAP()		mips5900_TBIAP(mips_num_tlb_entries)
  #define MIPS_TBIS		mips5900_TBIS
  #define MachTLBUpdate		mips5900_TLBUpdate
 +#define MachTLBWriteIndexedVPS	mips5900_TLBWriteIndexedVPS
  #define proc_trampoline		mips5900_proc_trampoline
  #define wbflush()		mips5900_wbflush()
  #else
 Index: mips/include/mips3_pte.h
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/mips/include/mips3_pte.h,v
 retrieving revision 1.18
 diff -u -r1.18 mips3_pte.h
 --- mips/include/mips3_pte.h	10 Oct 2005 02:14:43 -0000	1.18
 +++ mips/include/mips3_pte.h	3 Nov 2005 15:57:13 -0000
 @@ -181,6 +181,9 @@
  #define	MIPS3_PG_SIZE_MASK_TO_SIZE(pg_mask)	\
      ((((pg_mask) | 0x00001fff) + 1) / 2)
  
 +#define	MIPS3_PG_SIZE_TO_MASK(pg_size)		\
 +    ((((pg_size) * 2) - 1) & ~0x00001fff)
 +
  /* NEC Vr41xx uses different pagemask values. */
  #define	MIPS4100_PG_SIZE_1K	0x00000000
  #define	MIPS4100_PG_SIZE_4K	0x00001800
 @@ -190,3 +193,7 @@
  
  #define	MIPS4100_PG_SIZE_MASK_TO_SIZE(pg_mask)	\
      ((((pg_mask) | 0x000007ff) + 1) / 2)
 +
 +#define	MIPS4100_PG_SIZE_TO_MASK(pg_size)		\
 +    ((((pg_size) * 2) - 1) & ~0x000007ff)
 +
 Index: mips/mips/mipsX_subr.S
 ===================================================================
 RCS file: /cvsroot/src/sys/arch/mips/mips/mipsX_subr.S,v
 retrieving revision 1.17
 diff -u -r1.17 mipsX_subr.S
 --- mips/mips/mipsX_subr.S	8 Sep 2005 15:19:58 -0000	1.17
 +++ mips/mips/mipsX_subr.S	3 Nov 2005 15:57:14 -0000
 @@ -118,6 +118,7 @@
  #include "opt_cputype.h"
  #include "opt_ddb.h"
  #include "opt_kgdb.h"
 +#include "opt_mips3_wired.h"
  
  #include <sys/cdefs.h>
  
 @@ -1593,6 +1594,68 @@
  	nop
  END(MIPSX(SetPID))
  
 +#if defined(ENABLE_MIPS3_WIRED_MAP)
 +/*--------------------------------------------------------------------------
 + *
 + * mipsN_TLBWriteIndexedVPS --
 + *
 + *      Write the given entry into the TLB at the given index.
 + *      Pass full R4000 style TLB info including variable page size mask.
 + *
 + *      mipsN_TLBWriteIndexed(unsigned int index, struct tlb *tlb)
 + *
 + * Results:
 + *      None.
 + *
 + * Side effects:
 + *      TLB entry set.
 + *
 + *--------------------------------------------------------------------------
 + */
 +LEAF(MIPSX(TLBWriteIndexedVPS))
 +	mfc0	v1, MIPS_COP_0_STATUS		# Save the status register.
 +	mtc0	zero, MIPS_COP_0_STATUS		# Disable interrupts
 +	COP0_SYNC
 +	nop
 +	lw	a2, 8(a1)			# fetch tlb->tlb_lo0
 +	lw	a3, 12(a1)			# fetch tlb->tlb_lo1
 +	mfc0	v0, MIPS_COP_0_TLB_PG_MASK	# Save current page mask.
 +	_MFC0	t0, MIPS_COP_0_TLB_HI		# Save the current PID.
 +
 +	_MTC0	a2, MIPS_COP_0_TLB_LO0		# Set up entry low0.
 +	COP0_SYNC
 +	_MTC0	a3, MIPS_COP_0_TLB_LO1		# Set up entry low1.
 +	COP0_SYNC
 +	nop
 +	lw	a2, 0(a1)			# fetch tlb->tlb_mask
 +	lw	a3, 4(a1)			# fetch tlb->tlb_hi
 +	nop
 +	mtc0	a0, MIPS_COP_0_TLB_INDEX	# Set the index.
 +	COP0_SYNC
 +	mtc0	a2, MIPS_COP_0_TLB_PG_MASK	# Set up entry pagemask.
 +	COP0_SYNC
 +	_MTC0	a3, MIPS_COP_0_TLB_HI		# Set up entry high.
 +	COP0_SYNC
 +	nop
 +	nop
 +	tlbwi					# Write the TLB
 +	COP0_SYNC
 +	nop
 +	nop
 +	nop					# Delay for effect
 +	nop
 +
 +	_MTC0	t0, MIPS_COP_0_TLB_HI		# Restore the PID.
 +	COP0_SYNC
 +	mtc0	v0, MIPS_COP_0_TLB_PG_MASK	# Restore page mask.
 +	COP0_SYNC
 +	nop
 +	nop
 +	j       ra
 +	mtc0	v1, MIPS_COP_0_STATUS		# Restore the status register
 +END(MIPSX(TLBWriteIndexedVPS))
 +#endif /* ENABLE_MIPS3_WIRED_MAP */
 +	
  /*--------------------------------------------------------------------------
   *
   * mipsN_TLBUpdate --
 --- /dev/null	2005-11-03 23:38:40.000000000 +0900
 +++ arc/arc/wired_map_machdep.c	2005-11-04 00:43:12.000000000 +0900
 @@ -0,0 +1,216 @@
 +/*	$NetBSD: wired_map.c,v 1.9 2005/10/10 02:14:43 tsutsui Exp $	*/
 +
 +/*-
 + * Copyright (C) 2000 Shuichiro URATA.  All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. The name of the author may not be used to endorse or promote products
 + *    derived from this software without specific prior written permission.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#include <sys/cdefs.h>
 +__KERNEL_RCSID(0, "$NetBSD: wired_map.c,v 1.9 2005/10/10 02:14:43 tsutsui Exp $");
 +
 +#include <sys/param.h>
 +#include <sys/systm.h>
 +#include <sys/malloc.h>
 +#include <sys/extent.h>
 +
 +#include <uvm/uvm_extern.h>
 +#include <machine/cpu.h>
 +#include <machine/wired_map.h>
 +#include <machine/vmparam.h>
 +#include <mips/locore.h>
 +#include <mips/pte.h>
 +
 +boolean_t arc_wired_map_paddr_entry(paddr_t pa, vaddr_t *vap, vsize_t *sizep);
 +boolean_t arc_wired_map_vaddr_entry(vaddr_t va, paddr_t *pap, vsize_t *sizep);
 +
 +static struct extent *arc_wired_map_ex;
 +static long wired_map_ex_storage[EXTENT_FIXED_STORAGE_SIZE(8) / sizeof(long)];
 +
 +void
 +arc_init_wired_map(void)
 +{
 +
 +	mips3_nwired_page = 0;
 +	arc_wired_map_ex = extent_create("wired_map",
 +	    VM_MIN_WIRED_MAP_ADDRESS, VM_MAX_WIRED_MAP_ADDRESS, M_DEVBUF,
 +	    (void *)wired_map_ex_storage, sizeof(wired_map_ex_storage),
 +	    EX_NOWAIT);
 +	if (arc_wired_map_ex == NULL)
 +		panic("arc_init_wired_map: can't create extent");
 +}
 +
 +void
 +arc_wired_enter_page(vaddr_t va, paddr_t pa, vaddr_t pg_size)
 +{
 +	int error;
 +
 +	KASSERT((va & (pg_size - 1)) == 0);
 +
 +	if (va < VM_MIN_WIRED_MAP_ADDRESS ||
 +	    va + pg_size > VM_MAX_WIRED_MAP_ADDRESS) {
 +#ifdef DIAGNOSTIC
 +		printf("arc_wired_enter_page: invalid va range.\n");
 +#endif
 +		return;
 +	}
 +
 +	error = extent_alloc_region(arc_wired_map_ex, va, pg_size, EX_NOWAIT);
 +	if (error) {
 +#ifdef DIAGNOSTIC
 +		printf("arc_wired_enter_page: cannot allocate region.\n");
 +#endif
 +		return;
 +	}
 +
 +	mips3_wired_enter_page(va, pa, pg_size);
 +}
 +
 +boolean_t
 +arc_wired_map_paddr_entry(paddr_t pa, vaddr_t *vap, vsize_t *sizep)
 +{
 +	vsize_t size;
 +	int n;
 +	struct wired_map_entry *entry;
 +
 +	n = mips3_nwired_page;
 +	for (entry = mips3_wired_map; --n >= 0; entry++) {
 +		size = MIPS3_PG_SIZE_MASK_TO_SIZE(entry->pgmask);
 +		if (entry->pa0 != 0 &&
 +		    pa >= entry->pa0 && pa < entry->pa0 + size) {
 +			*vap = entry->va;
 +			*sizep = size;
 +			return TRUE;
 +		}
 +		if (entry->pa1 != 0 &&
 +		    pa >= entry->pa1 && pa < entry->pa1 + size) {
 +			*vap = entry->va + size;
 +			*sizep = size;
 +			return TRUE;
 +		}
 +	}
 +	return FALSE;
 +}
 +
 +/* XXX: Using tlbp makes this easier... */
 +boolean_t
 +arc_wired_map_vaddr_entry(vaddr_t va, paddr_t *pap, vsize_t *sizep)
 +{
 +	vsize_t size;
 +	int n;
 +	struct wired_map_entry *entry;
 +
 +	n = mips3_nwired_page;
 +	for (entry = mips3_wired_map; --n >= 0; entry++) {
 +		size = MIPS3_PG_SIZE_MASK_TO_SIZE(entry->pgmask);
 +		if (va >= entry->va && va < entry->va + size * 2) {
 +			paddr_t pa = (va < entry->va + size)
 +			    ? entry->pa0 : entry->pa1;
 +
 +			if (pa != 0) {
 +				*pap = pa;
 +				*sizep = size;
 +				return TRUE;
 +			}
 +		}
 +	}
 +	return FALSE;
 +}
 +
 +vaddr_t
 +arc_contiguously_wired_mapped(paddr_t pa, vsize_t size)
 +{
 +	paddr_t p;
 +	vaddr_t rva, va;
 +	vsize_t vsize, offset;
 +
 +	if (!arc_wired_map_paddr_entry(pa, &rva, &vsize))
 +		return 0;	/* not wired mapped */
 +	/* XXX: same physical address may be wired mapped more than once */
 +	offset = (vsize_t)pa & (vsize - 1);
 +	pa -= offset;
 +	size += offset;
 +	va = rva;
 +	for (;;) {
 +		pa += vsize;
 +		va += vsize;
 +		size -= vsize;
 +		if (size <= 0)
 +			break;
 +		if (!arc_wired_map_vaddr_entry(va, &p, &vsize) || p != pa)
 +			return 0; /* not contiguously wired mapped */
 +	}
 +	return rva + offset;
 +}
 +
 +/* Allocate new wired entries */
 +vaddr_t
 +arc_map_wired(paddr_t pa, vsize_t size)
 +{
 +	vaddr_t va;
 +	vsize_t off;
 +	int error;
 +
 +	/* XXX: may be already partially wired mapped */
 +
 +	off = pa & MIPS3_WIRED_OFFMASK;
 +	pa &= ~(paddr_t)MIPS3_WIRED_OFFMASK;
 +	size += off;
 +
 +	if ((size + MIPS3_WIRED_ENTRY_SIZE(MIPS3_WIRED_SIZE) - 1) /
 +	    MIPS3_WIRED_ENTRY_SIZE(MIPS3_WIRED_SIZE) >
 +	    MIPS3_NWIRED_ENTRY - mips3_nwired_page) {
 +#ifdef DIAGNOSTIC
 +		printf("arc_map_wired(0x%llx, 0x%lx): %d is not enough\n",
 +		    pa + off, size - off,
 +		    MIPS3_NWIRED_ENTRY - mips3_nwired_page);
 +#endif
 +		return 0; /* free wired TLB is not enough */
 +	}
 +
 +	error = extent_alloc(arc_wired_map_ex, size, MIPS3_WIRED_SIZE,
 +	    0, EX_NOWAIT, &va);
 +	if (error) {
 +#ifdef DIAGNOSTIC
 +		printf("arc_map_wired: can't allocate region\n");
 +#endif
 +		return 0;
 +	}
 +	mips3_wired_enter_region(va, pa, MIPS3_WIRED_SIZE);
 +
 +	return va + off;
 +}
 +
 +boolean_t
 +arc_wired_map_extract(vaddr_t va, paddr_t *pap)
 +{
 +	paddr_t pa;
 +	vsize_t size;
 +
 +	if (arc_wired_map_vaddr_entry(va, &pa, &size)) {
 +		*pap = pa + (va & (size - 1));
 +		return TRUE;
 +	} else {
 +		return FALSE;
 +	}
 +}
 --- /dev/null	2005-11-03 23:38:40.000000000 +0900
 +++ arc/include/wired_map.h	2005-11-03 22:46:18.000000000 +0900
 @@ -0,0 +1,42 @@
 +/*	$NetBSD$	*/
 +
 +/*-
 + * Copyright (C) 2000 Shuichiro URATA.  All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. The name of the author may not be used to endorse or promote products
 + *    derived from this software without specific prior written permission.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#define MIPS3_NWIRED_ENTRY	8
 +#define MIPS3_WIRED_SIZE	MIPS3_PG_SIZE_MASK_TO_SIZE(MIPS3_PG_SIZE_16M)
 +
 +#ifndef ARC_THRESHOLD_TO_USE_WIRED_TLB	/* tunable */
 +#define ARC_THRESHOLD_TO_USE_WIRED_TLB	(256 * 1024)
 +#endif
 +
 +#include <mips/wired_map.h>
 +
 +void	arc_init_wired_map(void);
 +void	arc_wired_enter_page(vaddr_t, paddr_t, vsize_t);
 +vaddr_t	arc_contiguously_wired_mapped(paddr_t, vsize_t);
 +vaddr_t	arc_map_wired(paddr_t, vsize_t);
 +boolean_t arc_wired_map_extract(vaddr_t, paddr_t *);
 --- /dev/null	2005-11-03 23:38:40.000000000 +0900
 +++ evbmips/include/wired_map.h	2005-11-03 10:14:41.000000000 +0900
 @@ -0,0 +1,3 @@
 +/*	$NetBSD$	*/
 +
 +#include <mips/wired_map.h>
 --- /dev/null	2005-11-03 23:38:40.000000000 +0900
 +++ mips/include/wired_map.h	2005-11-04 00:39:19.000000000 +0900
 @@ -0,0 +1,103 @@
 +/*	$NetBSD$	*/
 +
 +/*-
 + * Copyright (c) 2005 Tadpole Computer Inc.
 + * All rights reserved.
 + *
 + * Written by Garrett D'Amore for Tadpole Computer Inc.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. The name of Tadpole Computer Inc. may not be used to endorse
 + *    or promote products derived from this software without specific
 + *    prior written permission.
 + *
 + * THIS SOFTWARE IS PROVIDED BY TADPOLE COMPUTER INC. ``AS IS'' AND
 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL TADPOLE COMPUTER INC.
 + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 + * POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#ifndef _MIPS_WIRED_MAP_H
 +#define _MIPS_WIRED_MAP_H
 +
 +/*
 + * Certain machines have peripheral busses which are only accessible
 + * using the TLB.
 + *
 + * For example, certain Alchemy parts place PCI and PCMCIA busses at
 + * physical address spaces which are beyond the normal 32-bit range.
 + * In order to access these spaces TLB entries mapping 36-bit physical
 + * addresses to 32-bit logical addresses must be used.
 + *
 + * Note that all wired mappings are must be 32 MB aligned.  This is
 + * because we use 32 MB mappings in the TLB.  Changing this might get
 + * us more effficent use of the address space, but it would greatly
 + * complicate the code, and would also probably consume additional TLB
 + * entries.
 + *
 + * Note that within a single 32 MB region, you can have multiple
 + * decoders, but they must decode uniquely within the same 32MB of
 + * physical address space.
 + *
 + * BEWARE: The start of KSEG2 (0xC0000000) is used by the NetBSD kernel
 + * for context switching and is associated with wired entry 0.  So you
 + * cannot use that, as I discovered the hard way.
 + *
 + * Note also that at the moment this is not supported on the MIPS-I
 + * ISA (but it shouldn't need it anyway.)
 + */
 +
 +#ifndef MIPS3_WIRED_SIZE
 +#define MIPS3_WIRED_SIZE	MIPS3_PG_SIZE_MASK_TO_SIZE(MIPS3_PG_SIZE_16M)
 +#endif
 +#define MIPS3_WIRED_OFFMASK	(MIPS3_WIRED_SIZE - 1)
 +
 +#define MIPS3_WIRED_ENTRY_SIZE(pgsize)	((pgsize) * 2)
 +#define MIPS3_WIRED_ENTRY_OFFMASK(pgsize) (MIPS3_WIRED_ENTRY_SIZE(pgsize) - 1)
 +
 +/*
 + * This defines the maximum number of wired TLB entries that the wired
 + * map will be allowed to consume.  It can (and probably will!)
 + * consume fewer, but it will not consume more.  Note that NetBSD also
 + * uses one wired entry for context switching (see TLB_WIRED_UPAGES),
 + * and that is not included in this number.
 + */
 +#ifndef MIPS3_NWIRED_ENTRY
 +#define MIPS3_NWIRED_ENTRY	8	/* upper limit */
 +#endif
 +
 +struct wired_map_entry {
 +	paddr_t	pa0;
 +	paddr_t	pa1;
 +	vaddr_t	va;
 +	vsize_t	pgmask;
 +};
 +
 +extern struct wired_map_entry mips3_wired_map[];
 +extern int mips3_nwired_page;
 +
 +/*
 + * Wire down a region of the specified size.
 + */
 +boolean_t mips3_wired_enter_region(vaddr_t, paddr_t, vsize_t);
 +
 +/*
 + * Wire down a single page using specified page size.
 + */
 +boolean_t mips3_wired_enter_page(vaddr_t, paddr_t, vsize_t);
 +
 +#endif	/* _MIPS_WIRED_MAP_H */
 --- /dev/null	2005-11-03 23:38:40.000000000 +0900
 +++ mips/mips/wired_map.c	2005-11-04 00:39:32.000000000 +0900
 @@ -0,0 +1,201 @@
 +/*	$NetBSD$	*/
 +
 +/*-
 + * Copyright (c) 2005 Tadpole Computer Inc.
 + * All rights reserved.
 + *
 + * Written by Garrett D'Amore for Tadpole Computer Inc.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. The name of Tadpole Computer Inc. may not be used to endorse
 + *    or promote products derived from this software without specific
 + *    prior written permission.
 + *
 + * THIS SOFTWARE IS PROVIDED BY TADPOLE COMPUTER INC. ``AS IS'' AND
 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 + * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL TADPOLE COMPUTER INC.
 + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 + * POSSIBILITY OF SUCH DAMAGE.
 + */ 
 +/*
 + * Copyright (C) 2000 Shuichiro URATA.  All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + * 3. The name of the author may not be used to endorse or promote products
 + *    derived from this software without specific prior written permission.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +/*
 + * This code is derived from similiar code in the ARC port of NetBSD, but
 + * it now bears little resemblence to it owing to quite different needs
 + * from the mapping logic.
 + */
 +
 +#include <sys/cdefs.h>
 +__KERNEL_RCSID(0, "$NetBSD$");
 +
 +#include <sys/param.h>
 +#include <sys/systm.h>
 +#include <uvm/uvm_extern.h>
 +#include <machine/cpu.h>
 +#include <machine/pte.h>
 +#include <machine/vmparam.h>
 +#include <machine/wired_map.h>
 +
 +#include <mips/locore.h>
 +#include <mips/pte.h>
 +
 +struct wired_map_entry mips3_wired_map[MIPS3_NWIRED_ENTRY];
 +int mips3_nwired_page;
 +
 +/*
 + * Lower layer API, to supply an explicit page size.  It only wires a
 + * single page at a time.
 + */
 +boolean_t
 +mips3_wired_enter_page(vaddr_t va, paddr_t pa, vsize_t pgsize)
 +{
 +	struct tlb tlb;
 +	vaddr_t va0;
 +	int found, index;
 +
 +	/* make sure entries are aligned */
 +	KASSERT((va & (pgsize - 1)) == 0);
 +	KASSERT((pa & (pgsize - 1)) == 0);
 +
 +	/* TLB entries come in pairs: this is the first address of the pair */
 +	va0 = va & ~MIPS3_WIRED_ENTRY_OFFMASK(pgsize);
 +
 +	found = 0;
 +	for (index = 0; index < mips3_nwired_page; index++) {
 +		if (mips3_wired_map[index].va == va0) {
 +			if ((va & pgsize) == 0) {
 +				/* EntryLo0 */
 +				mips3_wired_map[index].pa0 = pa;
 +			} else {
 +				/* EntryLo1 */
 +				mips3_wired_map[index].pa1 = pa;
 +			}
 +			found = 1;
 +			break;
 +		}
 +	}
 +
 +	if (found == 0) {
 +		/* we have to allocate a new wired entry */
 +		if (mips3_nwired_page >= MIPS3_NWIRED_ENTRY) {
 +#ifdef DIAGNOSTIC
 +			printf("mips3_wired_map: entries exhausted\n");
 +#endif
 +			return FALSE;
 +		}
 +
 +		index = mips3_nwired_page;
 +		mips3_nwired_page++;
 +		if (va == va0) {
 +			/* EntryLo0 */
 +			mips3_wired_map[index].pa0 = pa;
 +			mips3_wired_map[index].pa1 = 0;
 +		} else {
 +			/* EntryLo1 */
 +			mips3_wired_map[index].pa0 = 0;
 +			mips3_wired_map[index].pa1 = pa;
 +		}
 +		mips3_wired_map[index].va = va0;
 +		mips3_wired_map[index].pgmask = MIPS3_PG_SIZE_TO_MASK(pgsize);
 +
 +		/* Allocate new wired entry */
 +		mips3_cp0_wired_write(MIPS3_TLB_WIRED_UPAGES +
 +		    mips3_nwired_page + 1);
 +	}
 +
 +	/* map it */
 +	tlb.tlb_mask = mips3_wired_map[index].pgmask;
 +	tlb.tlb_hi = mips3_vad_to_vpn(va);
 +	if (mips3_wired_map[index].pa0 == 0)
 +		tlb.tlb_lo0 = MIPS3_PG_G;
 +	else
 +		tlb.tlb_lo0 =
 +		    mips3_paddr_to_tlbpfn(mips3_wired_map[index].pa0) |
 +		    MIPS3_PG_IOPAGE(
 +			    PMAP_CCA_FOR_PA(mips3_wired_map[index].pa0));
 +	if (mips3_wired_map[index].pa1 == 0)
 +		tlb.tlb_lo1 = MIPS3_PG_G;
 +	else
 +		tlb.tlb_lo1 = mips3_paddr_to_tlbpfn(
 +			mips3_wired_map[index].pa1) |
 +		    MIPS3_PG_IOPAGE(
 +			    PMAP_CCA_FOR_PA(mips3_wired_map[index].pa1));
 +	MachTLBWriteIndexedVPS(MIPS3_TLB_WIRED_UPAGES + index, &tlb);
 +	return TRUE;
 +}
 +
 +
 +/*
 + * Wire down a mapping from a virtual to physical address.  The size
 + * of the region must be a multiple of MIPS3_WIRED_SIZE, with
 + * matching alignment.
 + *
 + * Typically the caller will just pass a physaddr that is the same as
 + * the vaddr with bits 35-32 set nonzero.
 + */
 +boolean_t
 +mips3_wired_enter_region(vaddr_t va, paddr_t pa, vsize_t size)
 +{
 +	vaddr_t	vend;
 +	/*
 +	 * This routine allows for for wired mappings to be set up,
 +	 * and handles previously defined mappings and mapping
 +	 * overlaps reasonably well.  However, caution should be used
 +	 * not to attempt to change the mapping for a page unless you
 +	 * are certain that you are the only user of the virtual
 +	 * address space, otherwise chaos may ensue.
 +	 */
 +
 +	/* offsets within the page have to be identical */
 +	KASSERT((va & MIPS3_WIRED_OFFMASK) == (pa & MIPS3_WIRED_OFFMASK));
 +
 +	vend = va + size;
 +	/* adjust for alignment */
 +	va &= ~MIPS3_WIRED_OFFMASK;
 +	pa &= ~MIPS3_WIRED_OFFMASK;
 +
 +	while (va < vend) {
 +		if (!mips3_wired_enter_page(va, pa, MIPS3_WIRED_SIZE))
 +			return FALSE;
 +		va += MIPS3_WIRED_SIZE;
 +		pa += MIPS3_WIRED_SIZE;
 +	}
 +	return TRUE;
 +}