Subject: Re: port-mips/31915: provide centralized wired_map logic
To: None <tsutsui@netbsd.org, gnats-admin@netbsd.org,>
From: Garrett D'Amore <garrett_damore@tadpole.com>
List: netbsd-bugs
Date: 11/03/2005 16:40:02
The following reply was made to PR port-mips/31915; it has been noted by GNATS.
From: "Garrett D'Amore" <garrett_damore@tadpole.com>
To: Izumi Tsutsui <tsutsui@ceres.dti.ne.jp>
Cc: soda@sra.co.jp, gnats-bugs@NetBSD.org, port-mips@NetBSD.org
Subject: Re: port-mips/31915: provide centralized wired_map logic
Date: Thu, 03 Nov 2005 08:36:55 -0800
Izumi Tsutsui wrote:
>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.
>
>
OK, sounds good.
>
>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.
>
>
That sounds excellent. Thank-you.
-- Garrett
>---
>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;
>+}
>
>