summaryrefslogtreecommitdiffstats
path: root/arch/mips/mips3
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/mips3')
-rw-r--r--arch/mips/mips3/Makefile25
-rw-r--r--arch/mips/mips3/cache.c309
-rw-r--r--arch/mips/mips3/cpu.c96
-rw-r--r--arch/mips/mips3/fp-context.S170
-rw-r--r--arch/mips/mips3/memcpy.S185
-rw-r--r--arch/mips/mips3/memset.c82
-rw-r--r--arch/mips/mips3/pagetables.c297
-rw-r--r--arch/mips/mips3/r4xx0.S841
-rw-r--r--arch/mips/mips3/showregs.c36
9 files changed, 0 insertions, 2041 deletions
diff --git a/arch/mips/mips3/Makefile b/arch/mips/mips3/Makefile
deleted file mode 100644
index e0f6bcf29..000000000
--- a/arch/mips/mips3/Makefile
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# Makefile for the MIPS III specific parts of the Linux/MIPS kernel.
-#
-# Note! Dependencies are done automagically by 'make dep', which also
-# removes any old dependencies. DON'T put your own dependencies here
-# unless it's something special (ie not a .c file).
-#
-
-.S.s:
- $(CPP) $(CFLAGS) $< -o $*.s
-.S.o:
- $(CC) $(CFLAGS) -c $< -o $*.o
-
-all: mips.o
-EXTRA_ASFLAGS = -mips3 -mcpu=r4400
-O_TARGET := mips.o
-O_OBJS := cache.o cpu.o fp-context.o memcpy.o memset.o r4xx0.o pagetables.o \
- showregs.o
-
-copy_user.o: copy_user.S
-r4xx0.o: r4xx0.S
-
-clean:
-
-include $(TOPDIR)/Rules.make
diff --git a/arch/mips/mips3/cache.c b/arch/mips/mips3/cache.c
deleted file mode 100644
index 3fac95b75..000000000
--- a/arch/mips/mips3/cache.c
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * Cache maintenance for R4000/R4400/R4600 CPUs.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * (C) Copyright 1996 by Ralf Baechle
- * FIXME: Support for SC/MC version is missing.
- */
-#include <linux/kernel.h>
-#include <asm/addrspace.h>
-#include <asm/asm.h>
-#include <asm/bootinfo.h>
-#include <asm/cache.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/system.h>
-
-#define STR(x) __STR(x)
-#define __STR(x) #x
-
-unsigned long page_colour_mask;
-
-/*
- * Size of the caches
- * Line size of the caches
- */
-unsigned int dcache_size, icache_size;
-unsigned int dcache_line_size, icache_line_size;
-unsigned long dcache_line_mask, icache_line_mask;
-
-/*
- * Profiling counter
- */
-extern unsigned int dflushes;
-extern unsigned int iflushes;
-
-/*
- * Pointers to code for particular CPU sub family.
- */
-static void (*wb_inv_d_cache)(void);
-static void (*inv_i_cache)(void);
-
-#define CACHELINES 512 /* number of cachelines (kludgy) */
-
-extern inline void cache(unsigned int cacheop, unsigned long addr,
- unsigned long offset, void *fault)
-{
- __asm__ __volatile__ (
- "1:\tcache\t%0,%2+%1\n\t"
- ".section\t__ex_table,\"a\"\n\t"
- STR(PTR)"\t1b,%3\n\t"
- ".text"
- : /* no outputs */
- :"ri" (cacheop),
- "o" (*(unsigned char *)addr),
- "ri" (offset),
- "ri" (fault));
-}
-
-/*
- * Code for R4000 style primary caches.
- *
- * R4000 style caches are direct-mapped, virtual indexed and physical tagged.
- * The size of cache line is either 16 or 32 bytes.
- * SC/MC versions of the CPUs add support for an second level cache with
- * upto 4mb configured as either joint or split I/D. These level two
- * caches with direct support from CPU aren't yet supported.
- */
-
-static void r4000_wb_inv_d_cache(void)
-{
- unsigned long addr = KSEG0;
- int i;
-
- for (i=CACHELINES;i;i--) {
- cache(Index_Writeback_Inv_D, addr, 0, &&fault);
- addr += 32;
- }
- if (read_32bit_cp0_register(CP0_CONFIG) & CONFIG_DB)
- return;
- for (i=CACHELINES;i;i--) {
- cache(Index_Writeback_Inv_D, addr, 16, &&fault);
- addr += 32;
- }
-fault:
-}
-
-static void r4000_inv_i_cache(void)
-{
- unsigned long addr = KSEG0;
- int i;
-
- for (i=CACHELINES;i;i--) {
- cache(Index_Invalidate_I, addr, 0, &&fault);
- addr += 32;
- }
- if (read_32bit_cp0_register(CP0_CONFIG) & CONFIG_IB)
- return;
- for (i=CACHELINES;i;i--) {
- cache(Index_Invalidate_I, addr, 16, &&fault);
- addr += 32;
- }
-fault:
-}
-
-/*
- * Code for R4600 style primary caches.
- *
- * R4600 has two way primary caches with 32 bytes line size. The way to
- * flush is selected by bith 12 of the physical address given as argument
- * to an Index_* cache operation. CPU supported second level caches are
- * not available.
- *
- * R4600 v1.0 bug: Flush way 2, then way 1 of the instruction cache when
- * using Index_Invalidate_I. IDT says this should work but is untested.
- * If this should not work, we have to disable interrupts for the broken
- * chips. The CPU might otherwise execute code from the wrong cache way
- * during an interrupt.
- */
-static void r4600_wb_inv_d_cache(void)
-{
- unsigned long addr = KSEG0;
- int i;
-
- for (i=CACHELINES;i;i-=2) {
- cache(Index_Writeback_Inv_D, addr, 8192, &&fault);
- cache(Index_Writeback_Inv_D, addr, 0, &&fault);
- addr += 32;
- }
-fault:
-}
-
-static void r4600_inv_i_cache(void)
-{
- unsigned long addr = KSEG0;
- int i;
-
- for (i=CACHELINES;i;i-=2) {
- cache(Index_Invalidate_I, addr, 8192, &&fault);
- cache(Index_Invalidate_I, addr, 0, &&fault);
- addr += 32;
- }
-fault:
-}
-
-/*
- * Flush the cache of R4x00.
- *
- * R4600 v2.0 bug: "The CACHE instructions Hit_Writeback_Invalidate_D,
- * Hit_Writeback_D, Hit_Invalidate_D and Create_Dirty_Exclusive_D will only
- * operate correctly if the internal data cache refill buffer is empty. These
- * CACHE instructions should be separated from any potential data cache miss
- * by a load instruction to an uncached address to empty the response buffer."
- * (Revision 2.0 device errata from IDT available on http://www.idt.com/
- * in .pdf format.)
- *
- * To do: Use Hit_Invalidate where possible to be more economic.
- * Handle SC & MC versions.
- * The decission to nuke the entire cache might be based on a better
- * decission algorithem based on the real costs.
- * Handle different cache sizes.
- * Combine the R4000 and R4600 cases.
- */
-extern inline void
-flush_d_cache(unsigned long addr, unsigned long size)
-{
- unsigned long end;
- unsigned long a;
-
- dflushes++;
- if (1 || size >= dcache_size) {
- wb_inv_d_cache();
- return;
- }
-
- /*
- * Workaround for R4600 bug. Explanation see above.
- */
- *(volatile unsigned long *)KSEG1;
-
- /*
- * Ok, we only have to invalidate parts of the cache.
- */
- a = addr & dcache_line_mask;
- end = (addr + size) & dcache_line_mask;
- while (1) {
- cache(Hit_Writeback_Inv_D, a, 0, &&fault);
- if (a == end) break;
- a += dcache_line_size;
- }
-fault:
- return;
-}
-
-extern inline void
-flush_i_cache(unsigned long addr, unsigned long size)
-{
- unsigned long end;
- unsigned long a;
-
- iflushes++;
- if (1 || size >= icache_size) {
- inv_i_cache();
- return;
- }
-
- /*
- * Ok, we only have to invalidate parts of the cache.
- */
- a = addr & icache_line_mask;
- end = (addr + size) & dcache_line_mask;
- while (1) {
- cache(Hit_Invalidate_I, a, 0, &&fault);
- if (a == end) break;
- a += icache_line_size;
- }
-fault:
- return;
-}
-
-asmlinkage void
-mips3_cacheflush(unsigned long addr, unsigned long size, unsigned int flags)
-{
- if (!(flags & CF_ALL))
- printk("mips3_cacheflush called without cachetype parameter\n");
- if (!(flags & CF_VIRTUAL))
- return; /* Nothing to do */
- if (flags & CF_DCACHE)
- flush_d_cache(addr, size);
- if (flags & CF_ICACHE)
- flush_i_cache(addr, size);
-}
-
-/* Going away. */
-asmlinkage void fd_cacheflush(unsigned long addr, unsigned long size)
-{
- cacheflush(addr, size, CF_DCACHE|CF_VIRTUAL);
-}
-
-void mips3_cache_init(void)
-{
- extern asmlinkage void handle_vcei(void);
- extern asmlinkage void handle_vced(void);
- unsigned int c0_config = read_32bit_cp0_register(CP0_CONFIG);
-
- switch (mips_cputype) {
- case CPU_R4000MC: case CPU_R4400MC:
- case CPU_R4000SC: case CPU_R4400SC:
- /*
- * Handlers not implemented yet.
- */
- set_except_vector(14, handle_vcei);
- set_except_vector(31, handle_vced);
- break;
- default:
- }
-
- /*
- * Which CPU are we running on? There are different styles
- * of primary caches in the MIPS R4xx0 CPUs.
- */
- switch (mips_cputype) {
- case CPU_R4000MC: case CPU_R4400MC:
- case CPU_R4000SC: case CPU_R4400SC:
- case CPU_R4000PC: case CPU_R4400PC:
- inv_i_cache = r4000_inv_i_cache;
- wb_inv_d_cache = r4000_wb_inv_d_cache;
- break;
- case CPU_R4600: case CPU_R4700:
- inv_i_cache = r4600_inv_i_cache;
- wb_inv_d_cache = r4600_wb_inv_d_cache;
- break;
- default:
- panic("Don't know about cache type ...");
- }
- cacheflush = mips3_cacheflush;
-
- /*
- * Find the size of primary instruction and data caches.
- * For most CPUs these sizes are the same.
- */
- dcache_size = 1 << (12 + ((c0_config >> 6) & 7));
- icache_size = 1 << (12 + ((c0_config >> 9) & 7));
- page_colour_mask = (dcache_size - 1) & ~(PAGE_SIZE - 1);
-
- /*
- * Cache line sizes
- */
- dcache_line_size = (c0_config & CONFIG_DB) ? 32 : 16;
- dcache_line_mask = ~(dcache_line_size - 1);
- icache_line_size = (c0_config & CONFIG_IB) ? 32 : 16;
- icache_line_mask = ~(icache_line_size - 1);
-
- printk("Primary D-cache size %dkb bytes, %d byte lines.\n",
- dcache_size >> 10, dcache_line_size);
- printk("Primary I-cache size %dkb bytes, %d byte lines.\n",
- icache_size >> 10, icache_line_size);
-
- /*
- * Second level cache.
- * FIXME ...
- */
- if (!(c0_config & CONFIG_SC)) {
- printk("S-cache detected. This type of of cache is not "
- "supported yet.\n");
- }
-}
diff --git a/arch/mips/mips3/cpu.c b/arch/mips/mips3/cpu.c
deleted file mode 100644
index cd8a293e5..000000000
--- a/arch/mips/mips3/cpu.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1996 Ralf Baechle
- */
-#include <linux/sched.h>
-
-#include <asm/bootinfo.h>
-#include <asm/cache.h>
-#include <asm/mipsregs.h>
-#include <asm/page.h>
-#include <asm/processor.h>
-#include <asm/system.h>
-
-extern asmlinkage void mips3_cacheflush(unsigned long addr, unsigned long nbytes, unsigned int flags);
-
-void (*mips_cache_init)(void);
-void (*switch_to_user_mode)(struct pt_regs *regs);
-
-static void
-mips3_switch_to_user_mode(struct pt_regs *regs)
-{
- regs->cp0_status = (regs->cp0_status & ~(ST0_CU0|ST0_KSU)) | KSU_USER;
-}
-
-unsigned long (*thread_saved_pc)(struct thread_struct *t);
-
-/*
- * Return saved PC of a blocked thread.
- */
-static unsigned long mips3_thread_saved_pc(struct thread_struct *t)
-{
- return ((unsigned long long *)(unsigned long)t->reg29)[11];
-}
-
-unsigned long (*get_wchan)(struct task_struct *p);
-
-static unsigned long mips3_get_wchan(struct task_struct *p)
-{
- /*
- * This one depends on the frame size of schedule(). Do a
- * "disass schedule" in gdb to find the frame size. Also, the
- * code assumes that sleep_on() follows immediately after
- * interruptible_sleep_on() and that add_timer() follows
- * immediately after interruptible_sleep(). Ugly, isn't it?
- * Maybe adding a wchan field to task_struct would be better,
- * after all...
- */
- unsigned long schedule_frame;
- unsigned long pc;
-
- pc = thread_saved_pc(&p->tss);
- if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) {
- schedule_frame = ((unsigned long long *)(long)p->tss.reg30)[10];
- return (unsigned long)((unsigned long long *)schedule_frame)[9];
- }
- return pc;
-}
-
-void (*pgd_init)(unsigned long page);
-void (*copy_page)(unsigned long to, unsigned long from);
-asmlinkage void (*restore_fp_context)(struct sigcontext *sc);
-asmlinkage void (*save_fp_context)(struct sigcontext *sc);
-
-void
-mips3_cpu_init(void)
-{
- extern void mips3_cache_init(void);
- extern void mips3_pgd_init_32byte_lines(unsigned long page);
- extern void mips3_pgd_init_16byte_lines(unsigned long page);
- extern void mips3_clear_page_32byte_lines(unsigned long page);
- extern void mips3_clear_page_16byte_lines(unsigned long page);
- extern void mips3_copy_page_32byte_lines(unsigned long to, unsigned long from);
- extern void mips3_copy_page_16byte_lines(unsigned long to, unsigned long from);
- extern void mips3_copy_page(unsigned long to, unsigned long from);
- extern asmlinkage void mips3_restore_fp_context(struct sigcontext *sc);
- extern asmlinkage void mips3_save_fp_context(struct sigcontext *sc);
-
- mips_cache_init = mips3_cache_init;
- if (read_32bit_cp0_register(CP0_CONFIG) & CONFIG_DB) {
- pgd_init = mips3_pgd_init_32byte_lines;
- clear_page = mips3_clear_page_32byte_lines;
- copy_page = mips3_copy_page_32byte_lines;
- } else {
- pgd_init = mips3_pgd_init_16byte_lines;
- clear_page = mips3_clear_page_16byte_lines;
- copy_page = mips3_copy_page_16byte_lines;
- }
- switch_to_user_mode = mips3_switch_to_user_mode;
- thread_saved_pc = mips3_thread_saved_pc;
- get_wchan = mips3_get_wchan;
- restore_fp_context = mips3_restore_fp_context;
- save_fp_context = mips3_save_fp_context;
-}
diff --git a/arch/mips/mips3/fp-context.S b/arch/mips/mips3/fp-context.S
deleted file mode 100644
index 5e04aa61f..000000000
--- a/arch/mips/mips3/fp-context.S
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Save/restore floating point context for signal handlers.
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1996 by Ralf Baechle
- */
-#include <asm/asm.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsregs.h>
-#include <asm/regdef.h>
-#include <asm/sigcontext.h>
-
-#define SDC1(r,m) \
-7: sdc1 r,m; \
- .section __ex_table,"a"; \
- PTR 7b,bad_stack; \
- .text
-
-#define SW(r,m) \
-7: sw r,m; \
- .section __ex_table,"a"; \
- PTR 7b,bad_stack; \
- .text
-
-#define LDC1(r,m) \
-7: ldc1 r,m; \
- .section __ex_table,"a"; \
- PTR 7b,bad_stack; \
- .text
-
-#define LW(r,m) \
-7: lw r,m; \
- .section __ex_table,"a"; \
- PTR 7b,bad_stack; \
- .text
-
- .set noreorder
-/*
- * Save floating point context
- */
-LEAF(mips3_save_fp_context)
- mfc0 t1,CP0_STATUS
- sll t2,t1,2
- bgez t2,2f
- sll t2,t1,5 # delay slot
- bgez t2,1f
- cfc1 t1,fcr31 # delay slot
- /*
- * Store the 16 odd double precision registers
- */
- SDC1 ($f1,(SC_FPREGS+8)(a0))
- SDC1 ($f3,(SC_FPREGS+24)(a0))
- SDC1 ($f5,(SC_FPREGS+40)(a0))
- SDC1 ($f7,(SC_FPREGS+56)(a0))
- SDC1 ($f9,(SC_FPREGS+72)(a0))
- SDC1 ($f11,(SC_FPREGS+88)(a0))
- SDC1 ($f13,(SC_FPREGS+104)(a0))
- SDC1 ($f15,(SC_FPREGS+120)(a0))
- SDC1 ($f17,(SC_FPREGS+136)(a0))
- SDC1 ($f19,(SC_FPREGS+152)(a0))
- SDC1 ($f21,(SC_FPREGS+168)(a0))
- SDC1 ($f23,(SC_FPREGS+184)(a0))
- SDC1 ($f25,(SC_FPREGS+200)(a0))
- SDC1 ($f27,(SC_FPREGS+216)(a0))
- SDC1 ($f29,(SC_FPREGS+232)(a0))
- SDC1 ($f31,(SC_FPREGS+248)(a0))
-
- /*
- * Store the 16 even double precision registers
- */
-1: SDC1 ($f0,(SC_FPREGS+0)(a0))
- SDC1 ($f2,(SC_FPREGS+16)(a0))
- SDC1 ($f4,(SC_FPREGS+32)(a0))
- SDC1 ($f6,(SC_FPREGS+48)(a0))
- SDC1 ($f8,(SC_FPREGS+64)(a0))
- SDC1 ($f10,(SC_FPREGS+80)(a0))
- SDC1 ($f12,(SC_FPREGS+96)(a0))
- SDC1 ($f14,(SC_FPREGS+112)(a0))
- SDC1 ($f16,(SC_FPREGS+128)(a0))
- SDC1 ($f18,(SC_FPREGS+144)(a0))
- SDC1 ($f20,(SC_FPREGS+160)(a0))
- SDC1 ($f22,(SC_FPREGS+176)(a0))
- SDC1 ($f24,(SC_FPREGS+192)(a0))
- SDC1 ($f26,(SC_FPREGS+208)(a0))
- SDC1 ($f28,(SC_FPREGS+224)(a0))
- SDC1 ($f30,(SC_FPREGS+240)(a0))
- SW t1,SC_FPC_CSR(a0)
- cfc1 t0,$0 # implementation/version
- jr ra
- .set nomacro
- SW t1,SC_FPC_EIR(a0) # delay slot
- .set macro
-
-2: jr ra
- .set nomacro
- nop # delay slot
- .set macro
- END(mips3_save_fp_context)
-
-/*
- * Restore fpu state:
- * - fp gp registers
- * - cp1 status/control register
- *
- * We base the decission which registers to restore from the signal stack
- * frame on the current content of c0_status, not on the content of the
- * stack frame which might have been changed by the user.
- */
-LEAF(mips3_restore_fp_context)
- mfc0 t1,CP0_STATUS
- sll t0,t1,2
- bgez t0,2f
- sll t0,t1,5 # delay slot
- bgez t0,1f
- LW t0,SC_FPC_CSR(a0) # delay slot
- /*
- * Restore the 16 odd double precision registers only
- * when enabled in the cp0 status register.
- */
- LDC1 ($f1,(SC_FPREGS+8)(a0))
- LDC1 ($f3,(SC_FPREGS+24)(a0))
- LDC1 ($f5,(SC_FPREGS+40)(a0))
- LDC1 ($f7,(SC_FPREGS+56)(a0))
- LDC1 ($f9,(SC_FPREGS+72)(a0))
- LDC1 ($f11,(SC_FPREGS+88)(a0))
- LDC1 ($f13,(SC_FPREGS+104)(a0))
- LDC1 ($f15,(SC_FPREGS+120)(a0))
- LDC1 ($f17,(SC_FPREGS+136)(a0))
- LDC1 ($f19,(SC_FPREGS+152)(a0))
- LDC1 ($f21,(SC_FPREGS+168)(a0))
- LDC1 ($f23,(SC_FPREGS+184)(a0))
- LDC1 ($f25,(SC_FPREGS+200)(a0))
- LDC1 ($f27,(SC_FPREGS+216)(a0))
- LDC1 ($f29,(SC_FPREGS+232)(a0))
- LDC1 ($f31,(SC_FPREGS+248)(a0))
-
- /*
- * Restore the 16 even double precision registers
- * when cp1 was enabled in the cp0 status register.
- */
-1: LDC1 ($f0,(SC_FPREGS+0)(a0))
- LDC1 ($f2,(SC_FPREGS+16)(a0))
- LDC1 ($f4,(SC_FPREGS+32)(a0))
- LDC1 ($f6,(SC_FPREGS+48)(a0))
- LDC1 ($f8,(SC_FPREGS+64)(a0))
- LDC1 ($f10,(SC_FPREGS+80)(a0))
- LDC1 ($f12,(SC_FPREGS+96)(a0))
- LDC1 ($f14,(SC_FPREGS+112)(a0))
- LDC1 ($f16,(SC_FPREGS+128)(a0))
- LDC1 ($f18,(SC_FPREGS+144)(a0))
- LDC1 ($f20,(SC_FPREGS+160)(a0))
- LDC1 ($f22,(SC_FPREGS+176)(a0))
- LDC1 ($f24,(SC_FPREGS+192)(a0))
- LDC1 ($f26,(SC_FPREGS+208)(a0))
- LDC1 ($f28,(SC_FPREGS+224)(a0))
- LDC1 ($f30,(SC_FPREGS+240)(a0))
- jr ra
- .set nomacro
- ctc1 t0,fcr31 # delay slot
- .set macro
-
-2: jr ra
- .set nomacro
- nop # delay slot
- .set macro
- END(mips3_restore_fp_context)
- .set reorder
diff --git a/arch/mips/mips3/memcpy.S b/arch/mips/mips3/memcpy.S
deleted file mode 100644
index 6f03032a6..000000000
--- a/arch/mips/mips3/memcpy.S
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * arch/mips/mips3/memcpy.S
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (c) 1996 by Ralf Baechle
- *
- * Less stupid memcpy/user_copy implementation for 64 bit MIPS CPUs.
- * Much faster than the old memcpy but definately work in progress.
- * The list of tricks for a good memcpy is long ...
- */
-#include <asm/asm.h>
-#include <asm/regdef.h>
-#include <asm/mipsregs.h>
-
-#define BLOCK_SIZE (SZREG*4)
-
-#define SWAP(x,y) \
- subu x,x,y; \
- addu y,x,y; \
- subu x,y,x
-
-#define EX(addr,handler) \
- .section __ex_table,"a"; \
- PTR addr, handler; \
- .text
-#define UEX(addr,handler) \
- EX(addr,handler); \
- EX(addr+4,handler)
-
- .set noreorder
- .set noat
-
-/* ---------------------------------------------------------------------- */
-
-not_dw_aligned:
-/*
- * At least one address is missaligned.
- * Let's see if we can fix the alignment.
- */
- LONG_SUBU v1,zero,a0
- andi v1,SZREG-1
- sltu t0,v0,v1
- MOVN(v1,v0,t0)
- beqz v1,still_not_aligned
- LONG_ADDU v1,a0 # delay slot
-1: lb $1,(a1)
- EX(1b, fault)
- LONG_ADDIU a1,1
-2: sb $1,(a0)
- EX(2b, fault)
- LONG_ADDIU a0,1
- bne a0,v1,1b
- LONG_SUBU v0,1 # delay slot
-
-/*
- * Ok, now the destination address is 8-byte aligned.
- * Is the source also aligned?
- */
- andi t0,a1,SZREG-1
- beqz t0,align8 # fine ...
-
-/*
- * Bad. We could only fix the alignment of the destination address.
- * Now let's copy in the usual BLOCK_SIZE byte blocks using unaligned
- * load and aligned stores.
- */
-still_not_aligned:
- ori v1,v0,BLOCK_SIZE-1 # delay slot
- xori v1,BLOCK_SIZE-1
- beqz v1,copy_left_over
- nop # delay slot
- LONG_SUBU v0,v1
- LONG_ADDU v1,a0
-
-1: uld t0,(a1)
- UEX(1b, fault)
-2: uld t1,8(a1)
- UEX(2b, fault)
-2: uld t2,16(a1)
- UEX(2b, fault)
-2: uld t3,24(a1)
- UEX(2b, fault)
-2: sd t0,(a0)
- EX(2b, fault)
-2: sd t1,8(a0)
- EX(2b, fault_plus_one_reg)
-2: sd t2,16(a0)
- EX(2b, fault_plus_two_reg)
-2: sd t3,24(a0)
- EX(2b, fault_plus_three_reg)
- LONG_ADDIU a0,BLOCK_SIZE
- bne a0,v1,1b
- LONG_ADDIU a1,BLOCK_SIZE # delay slot
-9:
- b copy_left_over # < BLOCK_SIZE bytes left
- nop # delay slot
-
-/* ---------------------------------------------------------------------- */
-
-LEAF(__copy_user)
-
- or t1,a0,a1
- andi t1,SZREG-1
- bnez t1,not_dw_aligned
- move v0,a2 # delay slot
-
-align8:
- ori v1,v0,BLOCK_SIZE-1
- xori v1,BLOCK_SIZE-1
- beqz v1,copy_left_over
- nop # delay slot
- LONG_SUBU v0,v1
- LONG_ADDU v1,a0
-
-1: ld t0,(a1)
- EX(1b, fault)
-2: ld t1,8(a1)
- EX(2b, fault)
-2: ld t2,16(a1)
- EX(2b, fault)
-2: ld t3,24(a1)
- EX(2b, fault)
-2: sd t0,(a0)
- EX(2b, fault)
-2: sd t1,8(a0)
- EX(2b, fault_plus_one_reg)
-2: sd t2,16(a0)
- EX(2b, fault_plus_two_reg)
-2: sd t3,24(a0)
- EX(2b, fault_plus_three_reg)
- LONG_ADDIU a0,BLOCK_SIZE
- bne a0,v1,1b
- LONG_ADDIU a1,BLOCK_SIZE # delay slot
-9:
-
-/*
- * We've got upto 31 bytes left to copy ...
- */
-copy_left_over:
- beqz v0,3f
- nop # delay slot
-1: lb $1,(a1)
- EX(1b, fault)
- LONG_ADDIU a1,1
-2: sb $1,(a0)
- EX(2b, fault)
- LONG_SUBU v0,1
- bnez v0,1b
- LONG_ADDIU a0,1
-3: jr ra
- nop # delay slot
-
- END(__copy_user)
- .set at
- .set reorder
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * Access fault. The number of not copied bytes is in v0. We have to
- * correct the number of the not copied bytes in v0 in case of a access
- * fault in an unrolled loop, then return.
- */
-
-fault: jr ra
-fault_plus_one_reg: LONG_ADDIU v0,SZREG
- jr ra
-fault_plus_two_reg: LONG_ADDIU v0,SZREG*2
- jr ra
-fault_plus_three_reg: LONG_ADDIU v0,SZREG*3
- jr ra
-
-/* ---------------------------------------------------------------------- */
-
-/*
- * For now we use __copy_user for __memcpy, too. This is efficient (one
- * instruction penatly) and smaller but adds unwanted error checking we don't
- * need. This hopefully doesn't cover any bugs. The memcpy() wrapper in
- * <asm/string.h> takes care of the return value in a way GCC can optimize.
- */
- .globl __memcpy
-__memcpy = __copy_user
diff --git a/arch/mips/mips3/memset.c b/arch/mips/mips3/memset.c
deleted file mode 100644
index e92a0907f..000000000
--- a/arch/mips/mips3/memset.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1996 by Ralf Baechle
- *
- * Less stupid memset for 64 bit MIPS CPUs.
- */
-#include <linux/linkage.h>
-#include <linux/string.h>
-
-static void __inline__ b_memset(void *s, unsigned long long c, size_t count)
-{
- unsigned char *p = s;
-
- while(count--)
- *(p++) = c;
-}
-
-static void __inline__ dw_memset(void *s, unsigned long long c, size_t count)
-{
- unsigned long long *p = s;
-
- count >>= 3;
- while(count--)
- *(p++) = c;
-}
-
-asm( ".globl\t__generic_memset_b\n\t"
- ".align\t2\n\t"
- ".type\t__generic_memset_b,@function\n\t"
- ".ent\t__generic_memset_b,0\n\t"
- ".frame\t$29,0,$31\n"
- "__generic_memset_b:\n\t"
- "andi\t$5,0xff\n\t"
- "dsll\t$2,$5,8\n\t"
- "or\t$5,$2\n\t"
- "dsll\t$2,$5,16\n\t"
- "or\t$5,$2\n\t"
- "dsll32\t$2,$5,0\n\t"
- "or\t$5,$2\n\t"
- ".end\t__generic_memset_b\n\t"
- ".size\t__generic_memset_b,.-t__generic_memset_b");
-
-/*
- * Fill small area bytewise. For big areas fill the source bytewise
- * until the pointer is doubleword aligned, then fill in doublewords.
- * Fill the rest again in single bytes.
- */
-void __generic_memset_dw(void *s, unsigned long long c, size_t count)
-{
- unsigned long i;
-
- /*
- * Fill small areas bytewise.
- */
- if (count <= 16) {
- b_memset(s, c, count);
- return;
- }
-
- /*
- * Pad for 8 byte boundary
- */
- i = 8 - ((unsigned long)s & 7);
- b_memset(s, c, i);
- s += i;
- count -= i;
-
- /*
- * Now start filling with aligned doublewords
- */
- dw_memset(s, c, count);
- s += (count | 7) ^ 7;
- count &= 7;
-
- /*
- * And do what ever is left over again with single bytes.
- */
- b_memset(s, c, count);
-}
diff --git a/arch/mips/mips3/pagetables.c b/arch/mips/mips3/pagetables.c
deleted file mode 100644
index e8cb83d03..000000000
--- a/arch/mips/mips3/pagetables.c
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * Copyright (C) 1996 Ralf Baechle
- *
- * Functions that manipulate entire pages.
- *
- * Not nice to have all these functions in two versions for cpus with
- * different cache line size but it seems to be by far the fastest thing
- * to schedule the cache instructions immediately before the store
- * instructions. For example using the clear_page() version for 16 byte
- * lines on machine with 32 byte lines gives a measured penalty of
- * ~1280 cycles per page.
- */
-#include <linux/mm.h>
-#include <asm/cache.h>
-#include <asm/mipsconfig.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
-
-extern unsigned int dflushes;
-
-/*
- * Initialize new page directory with pointers to invalid ptes.
- */
-void mips3_pgd_init_32byte_lines(unsigned long page)
-{
- unsigned long dummy1, dummy2;
-
- /*
- * We generate dirty lines in the datacache, overwrite them
- * then writeback the cache.
- */
- __asm__ __volatile__(
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- ".set\tmips3\n\t"
- "dsll32\t$1,%2,0\n\t"
- "dsrl32\t%2,$1,0\n\t"
- "or\t%2,$1\n"
- "1:\tcache\t%5,(%0)\n\t"
- "sd\t%2,(%0)\n\t"
- "sd\t%2,8(%0)\n\t"
- "sd\t%2,16(%0)\n\t"
- "sd\t%2,24(%0)\n\t"
- "daddiu\t%0,64\n\t"
- "cache\t%5,-32(%0)\n\t"
- "sd\t%2,-32(%0)\n\t"
- "sd\t%2,-24(%0)\n\t"
- "sd\t%2,-16(%0)\n\t"
- "bne\t%0,%1,1b\n\t"
- "sd\t%2,-8(%0)\n\t"
- ".set\tmips0\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- :"=&r" (dummy1),
- "=&r" (dummy2)
- :"r" (((unsigned long) invalid_pte_table - PAGE_OFFSET) |
- _PAGE_TABLE),
- "0" (page),
- "1" (page + PAGE_SIZE - 64),
- "i" (Create_Dirty_Excl_D)
- :"$1");
- __asm__ __volatile__(
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- ".set\tmips3\n\t"
- "1:\tcache\t%3,(%0)\n\t"
- "bne\t%0,%1,1b\n\t"
- "daddiu\t%0,32\n\t"
- ".set\tmips0\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- :"=r" (dummy1)
- :"0" (page),
- "r" (page + PAGE_SIZE - 32),
- "i" (Hit_Writeback_D));
- dflushes++;
-
-#if 0
- cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_VIRTUAL);
-#endif
-}
-
-/*
- * Initialize new page directory with pointers to invalid ptes
- */
-void mips3_pgd_init_16byte_lines(unsigned long page)
-{
- unsigned long dummy1, dummy2;
-
- /*
- * We generate dirty lines in the datacache, overwrite them
- * then writeback the cache.
- */
- __asm__ __volatile__(
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- ".set\tmips3\n\t"
- "dsll32\t$1,%2,0\n\t"
- "dsrl32\t%2,$1,0\n\t"
- "or\t%2,$1\n"
- "1:\tcache\t%5,(%0)\n\t"
- "sd\t%2,(%0)\n\t"
- "sd\t%2,8(%0)\n\t"
- "cache\t%5,16(%0)\n\t"
- "sd\t%2,16(%0)\n\t"
- "sd\t%2,24(%0)\n\t"
- "daddiu\t%0,64\n\t"
- "cache\t%5,-32(%0)\n\t"
- "sd\t%2,-32(%0)\n\t"
- "sd\t%2,-24(%0)\n\t"
- "cache\t%5,-16(%0)\n\t"
- "sd\t%2,-16(%0)\n\t"
- "bne\t%0,%1,1b\n\t"
- "sd\t%2,-8(%0)\n\t"
- ".set\tmips0\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- :"=&r" (dummy1),
- "=&r" (dummy2)
- :"r" (((unsigned long) invalid_pte_table - PAGE_OFFSET) |
- _PAGE_TABLE),
- "0" (page),
- "1" (page + PAGE_SIZE - 64),
- "i" (Create_Dirty_Excl_D)
- :"$1");
- __asm__ __volatile__(
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- ".set\tmips3\n\t"
- "1:\tcache\t%3,(%0)\n\t"
- "bne\t%0,%1,1b\n\t"
- "daddiu\t%0,16\n\t"
- ".set\tmips0\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- :"=r" (dummy1)
- :"0" (page),
- "r" (page + PAGE_SIZE - 16),
- "i" (Hit_Writeback_D));
- dflushes++;
-
-#if 0
- cacheflush(page, PAGE_SIZE, CF_DCACHE|CF_VIRTUAL);
-#endif
-}
-
-/*
- * Zero an entire page.
- */
-
-void (*clear_page)(unsigned long page);
-
-void mips3_clear_page_32byte_lines(unsigned long page)
-{
- __asm__ __volatile__(
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- "daddiu\t$1,%0,%2\n"
- "1:\tcache\t%3,(%0)\n\t"
- "sd\t$0,(%0)\n\t"
- "sd\t$0,8(%0)\n\t"
- "sd\t$0,16(%0)\n\t"
- "sd\t$0,24(%0)\n\t"
- "daddiu\t%0,64\n\t"
- "cache\t%3,-32(%0)\n\t"
- "sd\t$0,-32(%0)\n\t"
- "sd\t$0,-24(%0)\n\t"
- "sd\t$0,-16(%0)\n\t"
- "bne\t$1,%0,1b\n\t"
- "sd\t$0,-8(%0)\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- :"=r" (page)
- :"0" (page),
- "I" (PAGE_SIZE),
- "i" (Create_Dirty_Excl_D)
- :"$1","memory");
-}
-
-void mips3_clear_page_16byte_lines(unsigned long page)
-{
- __asm__ __volatile__(
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- "daddiu\t$1,%0,%2\n"
- "1:\tcache\t%3,(%0)\n\t"
- "sd\t$0,(%0)\n\t"
- "sd\t$0,8(%0)\n\t"
- "cache\t%3,16(%0)\n\t"
- "sd\t$0,16(%0)\n\t"
- "sd\t$0,24(%0)\n\t"
- "daddiu\t%0,64\n\t"
- "cache\t%3,-32(%0)\n\t"
- "sd\t$0,-32(%0)\n\t"
- "sd\t$0,-24(%0)\n\t"
- "cache\t%3,-16(%0)\n\t"
- "sd\t$0,-16(%0)\n\t"
- "bne\t$1,%0,1b\n\t"
- "sd\t$0,-8(%0)\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- :"=r" (page)
- :"0" (page),
- "I" (PAGE_SIZE),
- "i" (Create_Dirty_Excl_D)
- :"$1","memory");
-}
-
-/*
- * This is still inefficient. We only can do better if we know the
- * virtual address where the copy will be accessed.
- */
-void (*copy_page)(unsigned long to, unsigned long from);
-
-void mips3_copy_page_32byte_lines(unsigned long to, unsigned long from)
-{
- unsigned long dummy1, dummy2;
- unsigned long reg1, reg2, reg3, reg4;
-
- __asm__ __volatile__(
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- "daddiu\t$1,%0,%8\n"
- "1:\tcache\t%9,(%0)\n\t"
- "ld\t%2,(%1)\n\t"
- "ld\t%3,8(%1)\n\t"
- "ld\t%4,16(%1)\n\t"
- "ld\t%5,24(%1)\n\t"
- "sd\t%2,(%0)\n\t"
- "sd\t%3,8(%0)\n\t"
- "sd\t%4,16(%0)\n\t"
- "sd\t%5,24(%0)\n\t"
- "cache\t%9,32(%0)\n\t"
- "daddiu\t%0,64\n\t"
- "daddiu\t%1,64\n\t"
- "ld\t%2,-32(%1)\n\t"
- "ld\t%3,-24(%1)\n\t"
- "ld\t%4,-16(%1)\n\t"
- "ld\t%5,-8(%1)\n\t"
- "sd\t%2,-32(%0)\n\t"
- "sd\t%3,-24(%0)\n\t"
- "sd\t%4,-16(%0)\n\t"
- "bne\t$1,%0,1b\n\t"
- "sd\t%5,-8(%0)\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- :"=r" (dummy1), "=r" (dummy2),
- "=&r" (reg1), "=&r" (reg2), "=&r" (reg3), "=&r" (reg4)
- :"0" (to), "1" (from),
- "I" (PAGE_SIZE),
- "i" (Create_Dirty_Excl_D));
-}
-
-void mips3_copy_page_16byte_lines(unsigned long to, unsigned long from)
-{
- unsigned dummy1, dummy2;
- unsigned long reg1, reg2;
-
- __asm__ __volatile__(
- ".set\tnoreorder\n\t"
- ".set\tnoat\n\t"
- "daddiu\t$1,%0,%6\n"
- "1:\tcache\t%7,(%0)\n\t"
- "ld\t%2,(%1)\n\t"
- "ld\t%3,8(%1)\n\t"
- "sd\t%2,(%0)\n\t"
- "sd\t%3,8(%0)\n\t"
- "cache\t%7,16(%0)\n\t"
- "ld\t%2,16(%1)\n\t"
- "ld\t%3,24(%1)\n\t"
- "sd\t%2,16(%0)\n\t"
- "sd\t%3,24(%0)\n\t"
- "cache\t%7,32(%0)\n\t"
- "daddiu\t%0,64\n\t"
- "daddiu\t%1,64\n\t"
- "ld\t%2,-32(%1)\n\t"
- "ld\t%3,-24(%1)\n\t"
- "sd\t%2,-32(%0)\n\t"
- "sd\t%3,-24(%0)\n\t"
- "cache\t%7,-16(%0)\n\t"
- "ld\t%2,-16(%1)\n\t"
- "ld\t%3,-8(%1)\n\t"
- "sd\t%2,-16(%0)\n\t"
- "bne\t$1,%0,1b\n\t"
- "sd\t%3,-8(%0)\n\t"
- ".set\tat\n\t"
- ".set\treorder"
- :"=r" (dummy1), "=r" (dummy2),
- "=&r" (reg1), "=&r" (reg2)
- :"0" (to), "1" (from),
- "I" (PAGE_SIZE),
- "i" (Create_Dirty_Excl_D));
-}
diff --git a/arch/mips/mips3/r4xx0.S b/arch/mips/mips3/r4xx0.S
deleted file mode 100644
index a282998ac..000000000
--- a/arch/mips/mips3/r4xx0.S
+++ /dev/null
@@ -1,841 +0,0 @@
-/*
- * arch/mips/mips3/r4xx0.S
- *
- * Copyright (C) 1994, 1995, 1996 by Ralf Baechle and Andreas Busse
- *
- * This file contains most of the R4xx0 specific routines. Due to the
- * similarities this should hopefully also be fine for the R10000. For
- * now we especially support the R10000 by not invalidating entries out of
- * the TLB before calling the C handlers.
- *
- * This code is evil magic. Read appendix F (coprocessor 0 hazards) of
- * all R4xx0 manuals and think about that MIPS means "Microprocessor without
- * Interlocked Pipeline Stages" before you even think about changing this code!
- *
- * CAVEATS: The R4000/R4400/R4600 manual say that the operation of a memory
- * reference associated with a instruction immediately after a tlpb
- * instruction is undefined. It seems that the R4600 v2.0 also
- * failes to handle the case where a tlbp instruction follows a
- * (mapped???) memory reference. In this case c0_index gets
- * overwritten by some value which I suppose to be the entry
- * mapping the associated instruction's memory reference.
- *
- * This needs a complete overhaul; it was written for a Linux kernel that
- * handled it's page tables the old i386 way ...
- */
-#include <linux/config.h>
-
-#include <asm/asm.h>
-#include <asm/bootinfo.h>
-#include <asm/cache.h>
-#include <asm/fpregdef.h>
-#include <asm/mipsconfig.h>
-#include <asm/mipsregs.h>
-#include <asm/pgtable.h>
-#include <asm/processor.h>
-#include <asm/regdef.h>
-#include <asm/stackframe.h>
-
-/*
- * Use this to activate extra TLB error checking
- */
-#define CONF_DEBUG_TLB
-
-/*
- * Use this to activate extra TLB profiling code
- * (not implemented yet)
- */
-#undef CONF_PROFILE_TLB
-
-#ifdef __SMP__
-#error "Fix this for SMP"
-#else
-#define current current_set
-#endif
-
-MODE_ALIAS = 0x0016 # uncachable
-
- .text
- .set noreorder
-
- .align 5
- NESTED(handle_tlbl, FR_SIZE, sp)
- .set noat
- /*
- * Check whether this is a refill or an invalid exception
- *
- * NOTE: Some MIPS manuals say that the R4x00 sets the
- * BadVAddr only when EXL == 0. This is wrong - BadVAddr
- * is being set for all Reload, Invalid and Modified
- * exceptions.
- */
- mfc0 k0,CP0_BADVADDR
- mfc0 k1,CP0_ENTRYHI
- ori k0,0x1fff
- xori k0,0x1fff
- andi k1,0xff
- or k0,k1
- mfc0 k1,CP0_ENTRYHI
- mtc0 k0,CP0_ENTRYHI
- nop # for R4[04]00 pipeline
- nop
- nop
- nop
- tlbp
- nop
- nop # for R4[04]00 pipeline
- nop
- mfc0 k0,CP0_INDEX
- bgez k0,invalid_tlbl # bad addr in c0_badvaddr
- mtc0 k1,CP0_ENTRYHI # delay slot
- /*
- * Damn... The next nop is required on my R4400PC V5.0, but
- * I don't know why - at least there is no documented
- * reason as for the others :-(
- */
- nop
-
-#ifdef CONF_DEBUG_TLB
- /*
- * OK, this is a double fault. Let's see whether this is
- * due to an invalid entry in the page_table.
- */
- dmfc0 k0,CP0_BADVADDR
- srl k0,12
- sll k0,2
- lui k1,%HI(TLBMAP)
- addu k0,k1
- lw k1,(k0)
- andi k1,(_PAGE_PRESENT|_PAGE_ACCESSED)
- bnez k1,reload_pgd_entries
- nop # delay slot
-
- .set noat
- SAVE_ALL
- .set at
- PRINT("Double fault caused by invalid entries in pgd:\n")
- dmfc0 a1,CP0_BADVADDR
- PRINT("Double fault address : %016Lx\n")
- dmfc0 a1,CP0_EPC
- PRINT("c0_epc : %016Lx\n")
- jal show_regs
- move a0,sp
- jal dump_tlb_nonwired
- nop
- dmfc0 a0,CP0_BADVADDR
- jal dump_list_current
- nop
- .set noat
- STI
- .set at
- PANIC("Corrupted pagedir")
- .set noat
-
-reload_pgd_entries:
-#endif /* CONF_DEBUG_TLB */
-
- /*
- * Load missing pair of entries from the pgd and return.
- */
- dmfc0 k1,CP0_CONTEXT
-// mfc0 k1,CP0_CONTEXT
- dsra k1,1
- lwu k0,(k1) # Never causes nested 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 # for R4[04]00 pipeline
- tlbwr
- nop # for R4[04]00 pipeline
- nop
- nop
- /*
- * We don't know whether the original access was read or
- * write, so return and see what happens...
- */
- eret
-
- /*
- * Handle invalid exception
- *
- * There are two possible causes for an invalid (tlbl)
- * exception:
- * 1) pages with present bit set but the valid bit clear
- * 2) nonexistant pages
- * Case one needs fast handling, therefore don't save
- * registers yet.
- *
- * k0 contains c0_index.
- */
-invalid_tlbl:
-#ifdef CONFIG_TLB_SHUTDOWN
- /*
- * Remove entry so we don't need to care later
- * For sake of the R4000 V2.2 pipeline the tlbwi insn
- * has been moved down. Moving it around is juggling with
- * explosives...
- */
- lui k1,0x0008
- or k0,k1
- dsll k0,13
- dmtc0 k0,CP0_ENTRYHI
- dmtc0 zero,CP0_ENTRYLO0
- dmtc0 zero,CP0_ENTRYLO1
-#endif
- /*
- * Test present bit in entry
- */
- dmfc0 k0,CP0_BADVADDR
- srl k0,12
- sll k0,2
-#ifdef CONFIG_TLB_SHUTDOWN
- tlbwi # do not move!
-#endif
- lui k1,%HI(TLBMAP)
- addu k0,k1
- lw k1,(k0)
- andi k1,(_PAGE_PRESENT|_PAGE_READ)
- xori k1,(_PAGE_PRESENT|_PAGE_READ)
- bnez k1,nopage_tlbl
- /*
- * Present and read bits are set -> set valid and accessed bits
- */
- lw k1,(k0) # delay slot
- ori k1,(_PAGE_VALID|_PAGE_ACCESSED)
- sw k1,(k0)
- eret
-
- /*
- * Page doesn't exist. Lots of work which is less important
- * for speed needs to be done, so hand it all over to the
- * kernel memory management routines.
- */
-nopage_tlbl: SAVE_ALL
- dmfc0 a2,CP0_BADVADDR
- STI
- REG_S sp,FR_ORIG_REG2(sp)
- .set at
- /*
- * a0 (struct pt_regs *) regs
- * a1 (unsigned long) 0 for read access
- * a2 (unsigned long) faulting virtual address
- */
- move a0,sp
- jal do_page_fault
- li a1,0 # delay slot
- j ret_from_sys_call
- nop # delay slot
- END(handle_tlbl)
-
- .text
- .align 5
- NESTED(handle_tlbs, FR_SIZE, sp)
- .set noat
- /*
- * It is impossible that is a nested reload exception.
- * Therefore this must be a invalid exception.
- * Two possible cases:
- * 1) Page exists but not dirty.
- * 2) Page doesn't exist yet. Hand over to the kernel.
- *
- * Test whether present bit in entry is set
- */
- dmfc0 k0,CP0_BADVADDR
- srl k0,12
- sll k0,2
- lui k1,%HI(TLBMAP)
- addu k0,k1
- lw k1,(k0)
- nop
- nop
- tlbp # find faulting entry
- nop
- andi k1,(_PAGE_PRESENT|_PAGE_WRITE)
- xori k1,(_PAGE_PRESENT|_PAGE_WRITE)
- bnez k1,nopage_tlbs
- /*
- * Present and writable bits set: set accessed and dirty bits.
- */
- lw k1,(k0) # delay slot
- ori k1,k1,(_PAGE_ACCESSED|_PAGE_MODIFIED| \
- _PAGE_VALID|_PAGE_DIRTY)
- sw k1,(k0)
- /*
- * Now reload the entry into the TLB
- */
- ori k0,0x0004
- xori k0,0x0004
- lw k1,4(k0)
- lw k0,(k0)
- srl k1,6
- srl k0,6
- dmtc0 k1,CP0_ENTRYLO1
- dmtc0 k0,CP0_ENTRYLO0
- nop # for R4[04]00 pipeline
- tlbwi
- nop # for R4[04]00 pipeline
- nop
- nop
- eret
-
- /*
- * Page doesn't exist. Lots of work which is less important
- * for speed needs to be done, so hand it all over to the
- * kernel memory management routines.
- */
-nopage_tlbs:
-nowrite_mod:
-#ifdef CONFIG_TLB_SHUTDOWN
- /*
- * Remove entry so we don't need to care later
- */
- mfc0 k0,CP0_INDEX
-#ifdef CONF_DEBUG_TLB
- bgez k0,2f
- nop
- /*
- * We got a tlbs exception but found no matching entry in
- * the tlb. This should never happen. Paranoia makes us
- * check it, though.
- */
- SAVE_ALL
- jal show_regs
- move a0,sp
- .set at
- dmfc0 a1,CP0_BADVADDR
- PRINT("c0_badvaddr == %016Lx\n")
- mfc0 a1,CP0_INDEX
- PRINT("c0_index == %08x\n")
- dmfc0 a1,CP0_ENTRYHI
- PRINT("c0_entryhi == %016Lx\n")
- .set noat
- STI
- .set at
- PANIC("Tlbs or tlbm exception with no matching entry in tlb")
-1: j 1b
- nop
-2:
-#endif /* CONF_DEBUG_TLB */
- lui k1,0x0008
- or k0,k1
- dsll k0,13
- dmtc0 k0,CP0_ENTRYHI
- dmtc0 zero,CP0_ENTRYLO0
- dmtc0 zero,CP0_ENTRYLO1
- nop # for R4[04]00 pipeline
- nop # R4000 V2.2 requires 4 NOPs
- nop
- nop
- tlbwi
-#endif /* CONFIG_TLB_SHUTDOWN */
- .set noat
- SAVE_ALL
- dmfc0 a2,CP0_BADVADDR
- STI
- REG_S sp,FR_ORIG_REG2(sp)
- .set at
- /*
- * a0 (struct pt_regs *) regs
- * a1 (unsigned long) 1 for write access
- * a2 (unsigned long) faulting virtual address
- */
- move a0,sp
- jal do_page_fault
- li a1,1 # delay slot
- j ret_from_sys_call
- nop # delay slot
- END(handle_tlbs)
-
- .align 5
- NESTED(handle_mod, FR_SIZE, sp)
- .set noat
- /*
- * Two possible cases:
- * 1) Page is writable but not dirty -> set dirty and return
- * 2) Page is not writable -> call C handler
- */
- dmfc0 k0,CP0_BADVADDR
- srl k0,12
- sll k0,2
- lui k1,%HI(TLBMAP)
- addu k0,k1
- lw k1,(k0)
- nop
- nop
- tlbp # find faulting entry
- nop
- andi k1,_PAGE_WRITE
- beqz k1,nowrite_mod
- /*
- * Present and writable bits set: set accessed and dirty bits.
- */
- lw k1,(k0) # delay slot
- ori k1,(_PAGE_ACCESSED|_PAGE_DIRTY)
- sw k1,(k0)
- /*
- * Now reload the entry into the tlb
- */
- ori k0,0x0004
- xori k0,0x0004
- lw k1,4(k0)
- lw k0,(k0)
- srl k1,6
- srl k0,6
- dmtc0 k1,CP0_ENTRYLO1
- dmtc0 k0,CP0_ENTRYLO0
- nop # for R4[04]00 pipeline
- nop
- nop
- tlbwi
- nop # for R4[04]00 pipeline
- nop
- nop
- eret
- END(handle_mod)
- .set at
-
-/*
- * Flush the complete TLB
- */
- .set noreorder
- LEAF(tlbflush)
- li t0,PM_4K
- mtc0 t0,CP0_PAGEMASK
- lw t0,mips_tlb_entries /* mips_tlb_enbtries is set */
- /* by bi_EarlySnarf() */
- dmtc0 zero,CP0_ENTRYLO0
- dmtc0 zero,CP0_ENTRYLO1
- mfc0 t2,CP0_WIRED
-1: subu t0,1
- mtc0 t0,CP0_INDEX
- lui t1,0x0008
- or t1,t0,t1
- dsll t1,13
- dmtc0 t1,CP0_ENTRYHI
- bne t2,t0,1b
- tlbwi # delay slot
- jr ra
- nop # delay slot
- END(tlbflush)
-
-/*
- * Flush a single entry from the TLB
- *
- * Parameters: a0 - unsigned long address
- */
- .set noreorder
- LEAF(tlbflush_page)
- /*
- * Step 1: Wipe out old TLB information. Not shure if
- * we really need that step; call it paranoia ...
- * In order to do that we need to disable interrupts.
- */
- li t3,TLBMAP # then wait 3 cycles
- ori t1,a0,0xfff # mask off low 12 bits
- xori t1,0xfff
- mfc0 t2,CP0_ENTRYHI # copy ASID into address
- andi t2,0xff
- or t2,t1
- mtc0 t2,CP0_ENTRYHI
- srl t4,a0,12 # wait again three cycles
- sll t4,t4,PTRLOG
- dmtc0 zero,CP0_ENTRYLO0
- nop
- tlbp # now query the TLB
- nop
- addu t3,t4 # wait another three cycles
- ori t3,0xffff
- xori t3,0xffff
- mfc0 t1,CP0_INDEX
- bltz t1,1f # No old entry?
- dmtc0 zero,CP0_ENTRYLO1
- or t3,t1 # wait one cycle
- tlbwi
- /*
- * But there still might be an entry for the pgd ...
- */
-1: mtc0 t3,CP0_ENTRYHI
- nop # wait 3 cycles
- nop
- nop
- nop
- tlbp # TLB lookup
- nop
- nop
- nop
- mfc0 t1,CP0_INDEX # wait 3 cycles
- bltz t1,1f # No old entry?
- nop
- tlbwi # gotcha ...
-1: jr ra
- nop # delay slot
- END(tlbflush_page)
-
-/*
- * Code necessary to switch tasks on an Linux/MIPS machine.
- * FIXME: We don't need to disable interrupts anymore.
- * FIXME: Do some cache magic for faster loading/saving.
- */
- .align 5
- LEAF(resume)
- /*
- * Current task's task_struct
- */
- lui t5,%hi(current)
- lw t0,%lo(current)(t5)
-
- /*
- * Save status register
- */
- mfc0 t1,CP0_STATUS
- addu t0,a1 # Add tss offset
- sw t1,TOFF_CP0_STATUS(t0)
-
- /*
- * Disable interrupts
- */
- ori t2,t1,0x1f
- xori t2,0x1e
- mtc0 t2,CP0_STATUS
-
- /*
- * Save non-scratch registers
- * All other registers have been saved on the kernel stack
- */
- sd s0,TOFF_REG16(t0)
- sd s1,TOFF_REG17(t0)
- sd s2,TOFF_REG18(t0)
- sd s3,TOFF_REG19(t0)
- sd s4,TOFF_REG20(t0)
- sd s5,TOFF_REG21(t0)
- sd s6,TOFF_REG22(t0)
- sd s7,TOFF_REG23(t0)
- sd gp,TOFF_REG28(t0)
- sd sp,TOFF_REG29(t0)
- sd fp,TOFF_REG30(t0)
-
- /*
- * Save floating point state
- */
- sll t2,t1,2
- bgez t2,2f
- sd ra,TOFF_REG31(t0) # delay slot
- sll t2,t1,5
- bgez t2,1f
- sdc1 $f0,(TOFF_FPU+0)(t0) # delay slot
- /*
- * Store the 16 odd double precision registers
- */
- sdc1 $f1,(TOFF_FPU+8)(t0)
- sdc1 $f3,(TOFF_FPU+24)(t0)
- sdc1 $f5,(TOFF_FPU+40)(t0)
- sdc1 $f7,(TOFF_FPU+56)(t0)
- sdc1 $f9,(TOFF_FPU+72)(t0)
- sdc1 $f11,(TOFF_FPU+88)(t0)
- sdc1 $f13,(TOFF_FPU+104)(t0)
- sdc1 $f15,(TOFF_FPU+120)(t0)
- sdc1 $f17,(TOFF_FPU+136)(t0)
- sdc1 $f19,(TOFF_FPU+152)(t0)
- sdc1 $f21,(TOFF_FPU+168)(t0)
- sdc1 $f23,(TOFF_FPU+184)(t0)
- sdc1 $f25,(TOFF_FPU+200)(t0)
- sdc1 $f27,(TOFF_FPU+216)(t0)
- sdc1 $f29,(TOFF_FPU+232)(t0)
- sdc1 $f31,(TOFF_FPU+248)(t0)
-
- /*
- * Store the 16 even double precision registers
- */
-1: cfc1 t1,fcr31
- sdc1 $f2,(TOFF_FPU+16)(t0)
- sdc1 $f4,(TOFF_FPU+32)(t0)
- sdc1 $f6,(TOFF_FPU+48)(t0)
- sdc1 $f8,(TOFF_FPU+64)(t0)
- sdc1 $f10,(TOFF_FPU+80)(t0)
- sdc1 $f12,(TOFF_FPU+96)(t0)
- sdc1 $f14,(TOFF_FPU+112)(t0)
- sdc1 $f16,(TOFF_FPU+128)(t0)
- sdc1 $f18,(TOFF_FPU+144)(t0)
- sdc1 $f20,(TOFF_FPU+160)(t0)
- sdc1 $f22,(TOFF_FPU+176)(t0)
- sdc1 $f24,(TOFF_FPU+192)(t0)
- sdc1 $f26,(TOFF_FPU+208)(t0)
- sdc1 $f28,(TOFF_FPU+224)(t0)
- sdc1 $f30,(TOFF_FPU+240)(t0)
- sw t1,(TOFF_FPU+256)(t0)
-
- /*
- * Switch current task
- */
-2: sw a0,%lo(current)(t5)
- addu a0,a1 # Add tss offset
-
- /*
- * Switch address space
- */
-
- /*
- * (Choose new ASID for process)
- * This isn't really required, but would speed up
- * context switching.
- */
-
- /*
- * Switch the root pointer
- */
- lw t0,TOFF_PG_DIR(a0)
- li t1,TLB_ROOT
- mtc0 t1,CP0_ENTRYHI
- mtc0 zero,CP0_INDEX
- srl t0,6
- ori t0,MODE_ALIAS
- mtc0 t0,CP0_ENTRYLO0
- mtc0 zero,CP0_ENTRYLO1
- lw a2,TOFF_CP0_STATUS(a0)
-
- /*
- * Flush tlb
- * (probably not needed, doesn't clobber a0-a3)
- */
- jal tlbflush
- tlbwi # delay slot
-
- /*
- * Restore fpu state:
- * - cp0 status register bits
- * - fp gp registers
- * - cp1 status/control register
- */
- ori t1,a2,1 # pipeline magic
- xori t1,1
- mtc0 t1,CP0_STATUS
- sll t0,a2,2
- bgez t0,2f
- sll t0,a2,5 # delay slot
- bgez t0,1f
- ldc1 $f0,(TOFF_FPU+0)(a0) # delay slot
- /*
- * Restore the 16 odd double precision registers only
- * when enabled in the cp0 status register.
- */
- ldc1 $f1,(TOFF_FPU+8)(a0)
- ldc1 $f3,(TOFF_FPU+24)(a0)
- ldc1 $f5,(TOFF_FPU+40)(a0)
- ldc1 $f7,(TOFF_FPU+56)(a0)
- ldc1 $f9,(TOFF_FPU+72)(a0)
- ldc1 $f11,(TOFF_FPU+88)(a0)
- ldc1 $f13,(TOFF_FPU+104)(a0)
- ldc1 $f15,(TOFF_FPU+120)(a0)
- ldc1 $f17,(TOFF_FPU+136)(a0)
- ldc1 $f19,(TOFF_FPU+152)(a0)
- ldc1 $f21,(TOFF_FPU+168)(a0)
- ldc1 $f23,(TOFF_FPU+184)(a0)
- ldc1 $f25,(TOFF_FPU+200)(a0)
- ldc1 $f27,(TOFF_FPU+216)(a0)
- ldc1 $f29,(TOFF_FPU+232)(a0)
- ldc1 $f31,(TOFF_FPU+248)(a0)
-
- /*
- * Restore the 16 even double precision registers
- * when cp1 was enabled in the cp0 status register.
- */
-1: lw t0,(TOFF_FPU+256)(a0)
- ldc1 $f2,(TOFF_FPU+16)(a0)
- ldc1 $f4,(TOFF_FPU+32)(a0)
- ldc1 $f6,(TOFF_FPU+48)(a0)
- ldc1 $f8,(TOFF_FPU+64)(a0)
- ldc1 $f10,(TOFF_FPU+80)(a0)
- ldc1 $f12,(TOFF_FPU+96)(a0)
- ldc1 $f14,(TOFF_FPU+112)(a0)
- ldc1 $f16,(TOFF_FPU+128)(a0)
- ldc1 $f18,(TOFF_FPU+144)(a0)
- ldc1 $f20,(TOFF_FPU+160)(a0)
- ldc1 $f22,(TOFF_FPU+176)(a0)
- ldc1 $f24,(TOFF_FPU+192)(a0)
- ldc1 $f26,(TOFF_FPU+208)(a0)
- ldc1 $f28,(TOFF_FPU+224)(a0)
- ldc1 $f30,(TOFF_FPU+240)(a0)
- ctc1 t0,fcr31
-
- /*
- * Restore non-scratch registers
- */
-2: ld s0,TOFF_REG16(a0)
- ld s1,TOFF_REG17(a0)
- ld s2,TOFF_REG18(a0)
- ld s3,TOFF_REG19(a0)
- ld s4,TOFF_REG20(a0)
- ld s5,TOFF_REG21(a0)
- ld s6,TOFF_REG22(a0)
- ld s7,TOFF_REG23(a0)
- ld gp,TOFF_REG28(a0)
- ld sp,TOFF_REG29(a0)
- ld fp,TOFF_REG30(a0)
- ld ra,TOFF_REG31(a0)
-
- /*
- * Restore status register
- */
- lw t0,TOFF_KSP(a0)
- sw t0,kernelsp
-
- jr ra
- mtc0 a2,CP0_STATUS # delay slot
- END(resume)
-
-/*
- * Load a new root pointer into the tlb
- */
- .set noreorder
- LEAF(load_pgd)
- /*
- * Switch the root pointer
- */
- mfc0 t0,CP0_STATUS
- ori t1,t0,1
- xori t1,1
- mtc0 t1,CP0_STATUS
- srl a0,6
- ori a0,MODE_ALIAS
- li t1,TLB_ROOT
- mtc0 t1,CP0_ENTRYHI
- mtc0 zero,CP0_INDEX
- mtc0 a0,CP0_ENTRYLO0
- mtc0 zero,CP0_ENTRYLO1
- mtc0 t0,CP0_STATUS
- jr ra
- tlbwi # delay slot
- END(load_pgd)
-
-/*
- * do_syscall calls the function in a1 with upto 7 arguments. If over
- * four arguments are being requested, the additional arguments will
- * be copied from the user stack pointed to by a0->reg29.
- *
- * FIXME: This function will fail for syscalls with more than four
- * arguments from kernelspace.
- *
- * a0 (struct pt_regs *) pointer to user registers
- * a1 (syscall_t) pointer to syscall to do
- * a2 (int) number of arguments to syscall
- */
-#if defined (__MIPSEB__) && defined (__mips64)
-#define bo 4
-#else
-#define bo 0
-#endif
- .set reorder
- .text
-NESTED(do_syscalls, 64, sp)
- LONG_SUBU sp,64
- REG_S ra,56(sp)
- dsll a2,a2,PTRLOG
- lw t1,dst(a2)
- move t2,a1
- REG_L t0,FR_REG29(a0) # get old user stack pointer
- jalr t1
-
-7: lw t1,24+bo(t0) # parameter #7 from usp
- REG_S t1,SZREG*6(sp)
-6: lw t1,20+bo(t0) # parameter #6 from usp
- REG_S t1,SZREG*5(sp)
-5: lw t1,16+bo(t0) # parameter #5 from usp
- REG_S t1,SZREG*4(sp)
-
-4: lw a3,FR_REG7+bo(a0) # 4 args
-3: lw a2,FR_REG6+bo(a0) # 3 args
-2: lw a1,FR_REG5+bo(a0) # 2 args
-1: lw a0,FR_REG4+bo(a0) # 1 args
- jalr t2
- ld ra,56(sp)
- addiu sp,64
- jr ra
-0: jalr t2 # 0 args, just pass a0
- ld ra,56(sp)
- LONG_ADDIU sp,64
- jr ra
- END(do_syscalls)
-
- .rdata
- .align PTRLOG
-dst: PTR 0b, 1b, 2b, 3b, 4b, 5b, 6b, 7b
-
- .section __ex_table,"a"
- PTR 7b,bad_stack
- PTR 6b,bad_stack
- PTR 5b,bad_stack
- .text
-
-#ifdef CONFIG_REVERSE
-
-/*
- * Same as above but for processes running with reverse byte order.
- * When exec(2)ing a file the system detects normal/reverse byteorder in
- * an executable and
- * - sets the appropriate vector for syscalls and other low level
- * routines that depend of userspace byteorder.
- * - set the reverse byteorder flag in c0_status
- * - marks the process as reverse in the process table.
- */
-#define REG_SWAP(r,t) \
- .set push; \
- .set noat; \
- sll $1,r,24; \
- andi t,r,0xff00; \
- sll t,$t,8; \
- or $1,t; \
- srl t,r,8; \
- andi t,$t,0xff00; \
- or $1,t; \
- srl r,r,24; \
- or $1,r; \
- .set pop
-
- .set reorder
- .text
-NESTED(do_syscalls_rev, 64, sp)
- LONG_SUBU sp,64
- REG_S ra,56(sp)
- dsll a2,a2,PTRLOG
- lw t1,dst_rev(a2)
- move t2,a1
- REG_L t0,FR_REG29(a0) # get old user stack pointer
- jalr t1
-
-7: lw t1,24+bo(t0) # parameter #7 from usp
- REG_SWAP(t1,v0) # convert byteorder
- REG_S t1,SZREG*6(sp)
-6: lw t1,20+bo(t0) # parameter #6 from usp
- REG_SWAP(t1,v0) # convert byteorder
- REG_S t1,SZREG*5(sp)
-5: lw t1,16+bo(t0) # parameter #5 from usp
- REG_SWAP(t1,v0) # convert byteorder
- REG_S t1,SZREG*4(sp)
-
-4: lw a3,FR_REG7+bo(a0) # 4 args
-3: lw a2,FR_REG6+bo(a0) # 3 args
-2: lw a1,FR_REG5+bo(a0) # 2 args
-1: lw a0,FR_REG4+bo(a0) # 1 args
- jalr t2
- ld ra,56(sp)
- addiu sp,64
- jr ra
-0: jalr t2 # 0 args, just pass a0
- ld ra,56(sp)
- LONG_ADDIU sp,64
- jr ra
- END(do_syscalls)
-
- .rdata
- .align PTRLOG
-dst_rev: PTR 0b, 1b, 2b, 3b, 4b, 5b, 6b, 7b
-
- .section __ex_table,"a"
- PTR 7b,bad_stack
- PTR 6b,bad_stack
- PTR 5b,bad_stack
- .text
-
-#endif /* CONFIG_REVERSE */
diff --git a/arch/mips/mips3/showregs.c b/arch/mips/mips3/showregs.c
deleted file mode 100644
index 651cb6a24..000000000
--- a/arch/mips/mips3/showregs.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * linux/arch/mips/mips3/showregs.c
- *
- * Copyright (C) 1995, 1996 Ralf Baechle
- */
-#include <linux/kernel.h>
-#include <linux/ptrace.h>
-
-void show_regs(struct pt_regs * regs)
-{
- /*
- * Saved main processor registers
- */
- printk("$0 : %016Lx %016Lx %016Lx %016Lx\n",
- 0ULL, regs->regs[1], regs->regs[2], regs->regs[3]);
- printk("$4 : %016Lx %016Lx %016Lx %016Lx\n",
- regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]);
- printk("$8 : %016Lx %016Lx %016Lx %016Lx\n",
- regs->regs[8], regs->regs[9], regs->regs[10], regs->regs[11]);
- printk("$12: %016Lx %016Lx %016Lx %016Lx\n",
- regs->regs[12], regs->regs[13], regs->regs[14], regs->regs[15]);
- printk("$16: %016Lx %016Lx %016Lx %016Lx\n",
- regs->regs[16], regs->regs[17], regs->regs[18], regs->regs[19]);
- printk("$20: %016Lx %016Lx %016Lx %016Lx\n",
- regs->regs[20], regs->regs[21], regs->regs[22], regs->regs[23]);
- printk("$24: %016Lx %016Lx\n",
- regs->regs[24], regs->regs[25]);
- printk("$28: %016Lx %016Lx %016Lx %016Lx\n",
- regs->regs[28], regs->regs[29], regs->regs[30], regs->regs[31]);
-
- /*
- * Saved cp0 registers
- */
- printk("epc : %016Lx\nStatus: %08x\nCause : %08x\n",
- regs->cp0_epc, regs->cp0_status, regs->cp0_cause);
-}