]> git.neil.brown.name Git - history.git/commitdiff
Import 2.2.8pre5 2.2.8pre5
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:18:52 +0000 (15:18 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:18:52 +0000 (15:18 -0500)
153 files changed:
MAINTAINERS
arch/alpha/kernel/osf_sys.c
arch/arm/kernel/sys_arm.c
arch/arm/mm/Makefile
arch/arm/mm/fault-armo.c
arch/arm/mm/fault-armv.c
arch/arm/mm/fault-common.c [new file with mode: 0644]
arch/arm/mm/init.c
arch/arm/mm/ioremap.c [new file with mode: 0644]
arch/arm/mm/mm-arc.c [deleted file]
arch/arm/mm/mm-armv.c
arch/arm/mm/mm-ebsa285.c [deleted file]
arch/arm/mm/mm-footbridge.c [new file with mode: 0644]
arch/arm/mm/mm-vnc.c [deleted file]
arch/arm/mm/proc-arm2,3.S
arch/arm/mm/proc-arm6,7.S
arch/arm/mm/proc-sa110.S
arch/arm/mm/small_page.c
arch/mips/kernel/irixioctl.c
arch/mips/kernel/sysirix.c
arch/ppc/kernel/syscalls.c
drivers/net/de4x5.c
drivers/net/de4x5.h
fs/autofs/root.c
fs/coda/dir.c
fs/devpts/root.c
fs/dquot.c
fs/hfs/sysdep.c
fs/namei.c
fs/ncpfs/dir.c
fs/nfs/dir.c
fs/nfs/file.c
fs/nfs/inode.c
fs/smbfs/dir.c
fs/umsdos/dir.c
fs/vfat/namei.c
include/asm-arm/a.out.h
include/asm-arm/arch-arc/a.out.h
include/asm-arm/arch-arc/hardware.h
include/asm-arm/arch-arc/irq.h
include/asm-arm/arch-arc/keyboard.h
include/asm-arm/arch-arc/memory.h [new file with mode: 0644]
include/asm-arm/arch-arc/mmu.h [deleted file]
include/asm-arm/arch-arc/oldlatches.h
include/asm-arm/arch-arc/processor.h
include/asm-arm/arch-arc/time.h
include/asm-arm/arch-arc/uncompress.h
include/asm-arm/arch-ebsa110/a.out.h
include/asm-arm/arch-ebsa110/hardware.h
include/asm-arm/arch-ebsa110/irq.h
include/asm-arm/arch-ebsa110/memory.h [new file with mode: 0644]
include/asm-arm/arch-ebsa110/mm-init.h [deleted file]
include/asm-arm/arch-ebsa110/mmu.h [deleted file]
include/asm-arm/arch-ebsa110/oldlatches.h [deleted file]
include/asm-arm/arch-ebsa110/processor.h
include/asm-arm/arch-ebsa110/time.h
include/asm-arm/arch-ebsa285/a.out.h
include/asm-arm/arch-ebsa285/dma.h
include/asm-arm/arch-ebsa285/hardware.h
include/asm-arm/arch-ebsa285/io.h
include/asm-arm/arch-ebsa285/irq.h
include/asm-arm/arch-ebsa285/irqs.h
include/asm-arm/arch-ebsa285/keyboard.h
include/asm-arm/arch-ebsa285/memory.h [new file with mode: 0644]
include/asm-arm/arch-ebsa285/mm-init.h [deleted file]
include/asm-arm/arch-ebsa285/mmu.h [deleted file]
include/asm-arm/arch-ebsa285/oldlatches.h [deleted file]
include/asm-arm/arch-ebsa285/processor.h
include/asm-arm/arch-ebsa285/serial.h
include/asm-arm/arch-ebsa285/system.h
include/asm-arm/arch-ebsa285/time.h
include/asm-arm/arch-ebsa285/timex.h
include/asm-arm/arch-ebsa285/uncompress.h
include/asm-arm/arch-nexuspci/a.out.h
include/asm-arm/arch-nexuspci/hardware.h
include/asm-arm/arch-nexuspci/irq.h
include/asm-arm/arch-nexuspci/memory.h [new file with mode: 0644]
include/asm-arm/arch-nexuspci/mm-init.h [deleted file]
include/asm-arm/arch-nexuspci/mmu.h [deleted file]
include/asm-arm/arch-nexuspci/processor.h
include/asm-arm/arch-nexuspci/time.h
include/asm-arm/arch-rpc/a.out.h
include/asm-arm/arch-rpc/hardware.h
include/asm-arm/arch-rpc/irq.h
include/asm-arm/arch-rpc/keyboard.h
include/asm-arm/arch-rpc/memory.h [new file with mode: 0644]
include/asm-arm/arch-rpc/mmu.h [deleted file]
include/asm-arm/arch-rpc/oldlatches.h [deleted file]
include/asm-arm/arch-rpc/processor.h
include/asm-arm/arch-rpc/system.h
include/asm-arm/arch-rpc/time.h
include/asm-arm/arch-rpc/uncompress.h
include/asm-arm/arch-vnc/a.out.h [deleted file]
include/asm-arm/arch-vnc/dma.h [deleted file]
include/asm-arm/arch-vnc/hardware.h [deleted file]
include/asm-arm/arch-vnc/ide.h [deleted file]
include/asm-arm/arch-vnc/io.h [deleted file]
include/asm-arm/arch-vnc/irq.h [deleted file]
include/asm-arm/arch-vnc/irqs.h [deleted file]
include/asm-arm/arch-vnc/keyboard.h [deleted file]
include/asm-arm/arch-vnc/mm-init.h [deleted file]
include/asm-arm/arch-vnc/mmu.h [deleted file]
include/asm-arm/arch-vnc/oldlatches.h [deleted file]
include/asm-arm/arch-vnc/param.h [deleted file]
include/asm-arm/arch-vnc/processor.h [deleted file]
include/asm-arm/arch-vnc/serial.h [deleted file]
include/asm-arm/arch-vnc/shmparam.h [deleted file]
include/asm-arm/arch-vnc/system.h [deleted file]
include/asm-arm/arch-vnc/time.h [deleted file]
include/asm-arm/arch-vnc/timex.h [deleted file]
include/asm-arm/arch-vnc/uncompress.h [deleted file]
include/asm-arm/dec21285.h
include/asm-arm/dma.h
include/asm-arm/ecard.h
include/asm-arm/fiq.h
include/asm-arm/floppy.h
include/asm-arm/hardware.h
include/asm-arm/init.h
include/asm-arm/io.h
include/asm-arm/ioc.h
include/asm-arm/iomd.h
include/asm-arm/irq.h
include/asm-arm/leds.h
include/asm-arm/memc.h
include/asm-arm/mm-init.h [deleted file]
include/asm-arm/page.h
include/asm-arm/posix_types.h
include/asm-arm/proc-armo/mm-init-flat.h [deleted file]
include/asm-arm/proc-armo/mm-init.h
include/asm-arm/proc-armo/page.h
include/asm-arm/proc-armo/pgtable-flat.h [deleted file]
include/asm-arm/proc-armo/pgtable.h
include/asm-arm/proc-armo/processor.h
include/asm-arm/proc-armo/ptrace.h
include/asm-arm/proc-armo/semaphore.h
include/asm-arm/proc-armv/io.h
include/asm-arm/proc-armv/mm-init.h
include/asm-arm/proc-armv/pgtable.h
include/asm-arm/proc-armv/processor.h
include/asm-arm/proc-armv/ptrace.h
include/asm-arm/proc-armv/semaphore.h
include/asm-arm/proc-armv/uaccess.h
include/asm-arm/proc-fns.h
include/asm-arm/processor.h
include/asm-arm/semaphore-helper.h [new file with mode: 0644]
include/asm-arm/semaphore.h
include/asm-arm/system.h
include/asm-arm/unistd.h
include/asm-arm/vga.h
include/linux/dcache.h
include/linux/fs.h
include/linux/mc146818rtc.h [deleted file]
include/linux/nfs_fs.h

index f852c910535c887839b325d84662975ce2281c70..35dd36adf2448e08b900dfab74ee2a4b048011b4 100644 (file)
@@ -779,14 +779,14 @@ S:        Maintained
 USB HUB AND UHCI DRIVERS
 P:     Johannes Erdfelt
 M:     jerdfelt@sventech.com
-L:     linux-usb@peloncho.fis.ucm.es
+L:     linux-usb@suse.com
 S:     Maintained
 
 USB OHCI DRIVER
 P:     Gregory P. Smith
 M:     greg@electricrain.com
 M:     greg@suitenine.com
-L:     linux-usb@peloncho.fis.ucm.es
+L:     linux-usb@suse.com
 S:     Maintained (not yet usable)
 W:     http://suitenine.com/usb/
 
index 42b0d64eaba15565c77215eb51e3e9140704cafa..aeb27211d078cb65c13909537b8b71a272057a49 100644 (file)
@@ -141,6 +141,7 @@ asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent *dirent,
        struct inode *inode;
        struct osf_dirent_callback buf;
 
+       lock_kernel();
        error = -EBADF;
        file = fget(fd);
        if (!file)
@@ -173,6 +174,7 @@ asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent *dirent,
 out_putf:
        fput(file);
 out:
+       unlock_kernel();
        return error;
 }
 
index 5996398f83904fa25d251667a85e6044ac2c2651..d50b90f8d6812a91e85c177ef55c25af4e150de5 100644 (file)
@@ -77,12 +77,14 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg)
                goto out;
        if (!(a.flags & MAP_ANONYMOUS)) {
                error = -EBADF;
-               if (a.fd >= current->files->max_fds || 
-                   !(file = current->files->fd[a.fd]))
+               file = fget(a.fd);
+               if (!file)
                        goto out;
        }
        a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
        error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
+       if (file)
+               fput(file);
 out:
        unlock_kernel();
        return error;
index fc980914451d734ad09c2c2625839c554db2ed76..665c7c0b12c8f6f3c39731182dacec5d570983cc 100644 (file)
@@ -8,37 +8,30 @@
 # Note 2! The CFLAGS definition is now in the main makefile...
 
 all:   lib first_rule
-ifeq ($(MACHINE),a5k)
-MMARCH=arc
-else
-MMARCH=$(MACHINE)
-endif
 
 O_TARGET := mm.o
-O_OBJS   := init.o extable.o fault-$(PROCESSOR).o mm-$(MMARCH).o
+O_OBJS   := init.o extable.o fault-$(PROCESSOR).o small_page.o
 
 ifeq ($(PROCESSOR),armo)
  O_OBJS += proc-arm2,3.o
 endif
 
 ifeq ($(PROCESSOR),armv)
- O_OBJS += small_page.o proc-arm6,7.o proc-sa110.o
+ O_OBJS += mm-$(MACHINE).o proc-arm6,7.o proc-sa110.o ioremap.o
 endif
 
 include $(TOPDIR)/Rules.make
 
-proc-arm2,3.o: ../lib/constants.h
-proc-arm6,7.o: ../lib/constants.h
-proc-sa110.o:  ../lib/constants.h
-
 %.o: %.S
-ifneq ($(CONFIG_BINUTILS_NEW),y)
-       $(CC) $(CFLAGS) -D__ASSEMBLY__ -E $< | tr ';$$' '\n#' > ..$@.tmp.s
-       $(CC) $(CFLAGS:-pipe=) -c -o $@ ..$@.tmp.s
-       $(RM) ..$@.tmp.s
-else
        $(CC) $(CFLAGS) -D__ASSEMBLY__ -c -o $@ $<
-endif
 
 .PHONY:        lib
 lib:;  @$(MAKE) -C ../lib constants.h
+
+# Special dependencies
+fault-armv.o: fault-common.c
+fault-armo.o: fault-common.c
+proc-arm2,3.o: ../lib/constants.h
+proc-arm6,7.o: ../lib/constants.h
+proc-sa110.o:  ../lib/constants.h
+
index 6fe1f30ffc6599624dee1ab0e4c2da230fb5e428..c51980771827b1520d6287459038a7f79c137a4b 100644 (file)
@@ -1,11 +1,10 @@
 /*
- *  linux/arch/arm/mm/fault.c
+ *  linux/arch/arm/mm/fault-armo.c
  *
  *  Copyright (C) 1995  Linus Torvalds
- *  Modifications for ARM processor (c) 1995, 1996 Russell King
+ *  Modifications for ARM processor (c) 1995-1999 Russell King
  */
 
-#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -15,8 +14,7 @@
 #include <linux/ptrace.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #define FAULT_CODE_WRITE       0x02
 #define FAULT_CODE_USER                0x01
 
-struct pgtable_cache_struct quicklists;
+#define DO_COW(m)              ((m) & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW))
+#define READ_FAULT(m)          (!((m) & FAULT_CODE_WRITE))
 
-void __bad_pmd(pmd_t *pmd)
+#include "fault-common.c"
+
+static void *alloc_table(int size, int prio)
 {
-       printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-#ifdef CONFIG_DEBUG_ERRORS
-       __backtrace();
-#endif
-       set_pmd(pmd, mk_pmd(BAD_PAGETABLE));
+       if (size != 128)
+               printk("invalid table size\n");
+       return (void *)get_page_8k(prio);
 }
 
-void __bad_pmd_kernel(pmd_t *pmd)
+void free_table(void *table)
 {
-       printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
-#ifdef CONFIG_DEBUG_ERRORS
-       __backtrace();
-#endif
-       set_pmd(pmd, mk_pmd(BAD_PAGETABLE));
+       free_page_8k((unsigned long)table);
 }
 
 pgd_t *get_pgd_slow(void)
 {
-       pgd_t *pgd = (pgd_t *) kmalloc(PTRS_PER_PGD * BYTES_PER_PTR, GFP_KERNEL);
+       pgd_t *pgd = (pgd_t *)alloc_table(PTRS_PER_PGD * BYTES_PER_PTR, GFP_KERNEL);
        pgd_t *init;
-       
+
        if (pgd) {
                init = pgd_offset(&init_mm, 0);
-               memzero (pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
-               memcpy (pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+               memzero(pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
+               memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
                        (PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR);
        }
        return pgd;
@@ -65,17 +60,17 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
 {
        pte_t *pte;
 
-       pte = (pte_t *) kmalloc (PTRS_PER_PTE * BYTES_PER_PTR, GFP_KERNEL);
+       pte = (pte_t *)alloc_table(PTRS_PER_PTE * BYTES_PER_PTR, GFP_KERNEL);
        if (pmd_none(*pmd)) {
                if (pte) {
-                       memzero (pte, PTRS_PER_PTE * BYTES_PER_PTR);
+                       memzero(pte, PTRS_PER_PTE * BYTES_PER_PTR);
                        set_pmd(pmd, mk_pmd(pte));
                        return pte + offset;
                }
                set_pmd(pmd, mk_pmd(BAD_PAGETABLE));
                return NULL;
        }
-       kfree (pte);
+       free_table((void *)pte);
        if (pmd_bad(*pmd)) {
                __bad_pmd(pmd);
                return NULL;
@@ -83,126 +78,22 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
        return (pte_t *) pmd_page(*pmd) + offset;
 }
 
-extern void die_if_kernel(char *msg, struct pt_regs *regs, unsigned int err, unsigned int ret);
-
-static void kernel_page_fault (unsigned long addr, int mode, struct pt_regs *regs,
-                              struct task_struct *tsk, struct mm_struct *mm)
-{
-       /*
-        * Oops. The kernel tried to access some bad page. We'll have to
-        * terminate things with extreme prejudice.
-        */
-       pgd_t *pgd;
-       if (addr < PAGE_SIZE)
-           printk (KERN_ALERT "Unable to handle kernel NULL pointer dereference");
-       else
-           printk (KERN_ALERT "Unable to handle kernel paging request");
-       printk (" at virtual address %08lx\n", addr);
-       printk (KERN_ALERT "current->tss.memmap = %08lX\n", tsk->tss.memmap);
-       pgd = pgd_offset (mm, addr);
-       printk (KERN_ALERT "*pgd = %08lx", pgd_val (*pgd));
-       if (!pgd_none (*pgd)) {
-               pmd_t *pmd;
-               pmd = pmd_offset (pgd, addr);
-               printk (", *pmd = %08lx", pmd_val (*pmd));
-               if (!pmd_none (*pmd))
-                       printk (", *pte = %08lx", pte_val (*pte_offset (pmd, addr)));
-       }
-       printk ("\n");
-       die_if_kernel ("Oops", regs, mode, SIGKILL);
-       do_exit (SIGKILL);
-}
-
-static void
-handle_dataabort (unsigned long addr, int mode, struct pt_regs *regs)
-{
-       struct task_struct *tsk;
-       struct mm_struct *mm;
-       struct vm_area_struct *vma;
-       unsigned long fixup;
-
-       lock_kernel();
-       tsk = current;
-       mm = tsk->mm;
-
-       down(&mm->mmap_sem);
-       vma = find_vma (mm, addr);
-       if (!vma)
-               goto bad_area;
-       if (addr >= vma->vm_start)
-               goto good_area;
-       if (!(vma->vm_flags & VM_GROWSDOWN) || expand_stack (vma, addr))
-               goto bad_area;
-
-       /*
-        * Ok, we have a good vm_area for this memory access, so
-        * we can handle it..
-        */
-good_area:
-       if (!(mode & FAULT_CODE_WRITE)) { /* write? */
-               if (!(vma->vm_flags & (VM_READ|VM_EXEC)))
-                       goto bad_area;
-       } else {
-               if (!(vma->vm_flags & VM_WRITE))
-                       goto bad_area;
-       }
-       handle_mm_fault (tsk, vma, addr, mode & (FAULT_CODE_WRITE|FAULT_CODE_FORCECOW));
-       up(&mm->mmap_sem);
-       goto out;
-
-       /*
-        * Something tried to access memory that isn't in our memory map..
-        * Fix it, but check if it's kernel or user first..
-        */
-bad_area:
-       up(&mm->mmap_sem);
-       if (mode & FAULT_CODE_USER) {
-//extern int console_loglevel;
-//cli();
-               tsk->tss.error_code = mode;
-               tsk->tss.trap_no = 14;
-//console_loglevel = 9;
-               printk ("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
-                       tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
-//#ifdef DEBUG
-               show_regs (regs);
-               c_backtrace (regs->ARM_fp, 0);
-//#endif
-               force_sig(SIGSEGV, tsk);
-//while (1);
-               goto out;
-       }
-
-       /* Are we prepared to handle this kernel fault?  */
-       if ((fixup = search_exception_table(instruction_pointer(regs))) != 0) {
-               printk(KERN_DEBUG "%s: Exception at [<%lx>] addr=%lx (fixup: %lx)\n",
-                       tsk->comm, regs->ARM_pc, addr, fixup);
-               regs->ARM_pc = fixup;
-               goto out;
-       }
-
-
-       kernel_page_fault (addr, mode, regs, tsk, mm);
-out:
-       unlock_kernel();
-}
-
 /*
  * Handle a data abort.  Note that we have to handle a range of addresses
  * on ARM2/3 for ldm.  If both pages are zero-mapped, then we have to force
- * a copy-on-write
+ * a copy-on-write.  However, on the second page, we always force COW.
  */
 asmlinkage void
-do_DataAbort (unsigned long min_addr, unsigned long max_addr, int mode, struct pt_regs *regs)
+do_DataAbort(unsigned long min_addr, unsigned long max_addr, int mode, struct pt_regs *regs)
 {
-       handle_dataabort (min_addr, mode, regs);
+       do_page_fault(min_addr, mode, regs);
 
        if ((min_addr ^ max_addr) >> PAGE_SHIFT)
-               handle_dataabort (max_addr, mode | FAULT_CODE_FORCECOW, regs);
+               do_page_fault(max_addr, mode | FAULT_CODE_FORCECOW, regs);
 }
 
 asmlinkage int
-do_PrefetchAbort (unsigned long addr, int mode, struct pt_regs *regs)
+do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
 {
 #if 0
        if (the memc mapping for this page exists - can check now...) {
@@ -210,6 +101,6 @@ do_PrefetchAbort (unsigned long addr, int mode, struct pt_regs *regs)
                return 0;
        }
 #endif
-       handle_dataabort (addr, mode, regs);
+       do_page_fault(addr, FAULT_CODE_USER|FAULT_CODE_PREFETCH, regs);
        return 1;
 }
index f090c5f2c8a15c20a1a7b130af4cede046e04f23..d57d4fb20fb71cbc4f0c0612562bea7754cfec80 100644 (file)
@@ -1,10 +1,11 @@
 /*
- *  linux/arch/arm/mm/fault.c
+ *  linux/arch/arm/mm/fault-armv.c
  *
  *  Copyright (C) 1995  Linus Torvalds
- *  Modifications for ARM processor (c) 1995, 1996 Russell King
+ *  Modifications for ARM processor (c) 1995-1999 Russell King
  */
 
+#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/ptrace.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
 
 #include <asm/system.h>
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
+#include <asm/unaligned.h>
 
 #define FAULT_CODE_READ                0x02
 #define FAULT_CODE_USER                0x01
 
-struct pgtable_cache_struct quicklists;
+#define DO_COW(m)              (!((m) & FAULT_CODE_READ))
+#define READ_FAULT(m)          ((m) & FAULT_CODE_READ)
 
-void __bad_pmd(pmd_t *pmd)
-{
-       printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-       set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE));
-}
-
-void __bad_pmd_kernel(pmd_t *pmd)
-{
-       printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-       set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE));
-}
+#include "fault-common.c"
 
 pgd_t *get_pgd_slow(void)
 {
        /*
         * need to get a 16k page for level 1
         */
-       pgd_t *pgd = (pgd_t *) __get_free_pages(GFP_KERNEL,2);
+       pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL,2);
        pgd_t *init;
-       
+
        if (pgd) {
                init = pgd_offset(&init_mm, 0);
-               memzero ((void *)pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
-               memcpy (pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
+               memzero(pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
+               memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
                        (PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR);
+               clean_cache_area(pgd, PTRS_PER_PGD * BYTES_PER_PTR);
        }
        return pgd;
 }
@@ -59,17 +54,19 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
 {
        pte_t *pte;
 
-       pte = (pte_t *) get_small_page(GFP_KERNEL);
+       pte = (pte_t *)get_page_2k(GFP_KERNEL);
        if (pmd_none(*pmd)) {
                if (pte) {
-                       memzero (pte, PTRS_PER_PTE * BYTES_PER_PTR);
+                       memzero(pte, 2 * PTRS_PER_PTE * BYTES_PER_PTR);
+                       clean_cache_area(pte, PTRS_PER_PTE * BYTES_PER_PTR);
+                       pte += PTRS_PER_PTE;
                        set_pmd(pmd, mk_user_pmd(pte));
                        return pte + offset;
                }
                set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE));
                return NULL;
        }
-       free_small_page ((unsigned long) pte);
+       free_page_2k((unsigned long)pte);
        if (pmd_bad(*pmd)) {
                __bad_pmd(pmd);
                return NULL;
@@ -81,17 +78,19 @@ pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
 {
        pte_t *pte;
 
-       pte = (pte_t *) get_small_page(GFP_KERNEL);
+       pte = (pte_t *)get_page_2k(GFP_KERNEL);
        if (pmd_none(*pmd)) {
                if (pte) {
-                       memzero (pte, PTRS_PER_PTE * BYTES_PER_PTR);
+                       memzero(pte, 2 * PTRS_PER_PTE * BYTES_PER_PTR);
+                       clean_cache_area(pte, PTRS_PER_PTE * BYTES_PER_PTR);
+                       pte += PTRS_PER_PTE;
                        set_pmd(pmd, mk_kernel_pmd(pte));
                        return pte + offset;
                }
                set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE));
                return NULL;
        }
-       free_small_page ((unsigned long) pte);
+       free_page_2k((unsigned long)pte);
        if (pmd_bad(*pmd)) {
                __bad_pmd_kernel(pmd);
                return NULL;
@@ -99,10 +98,8 @@ pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
        return (pte_t *) pmd_page(*pmd) + offset;
 }
 
-extern void die_if_kernel(char *msg, struct pt_regs *regs, unsigned int err, unsigned int ret);
-
 #ifdef DEBUG
-static int sp_valid (unsigned long *sp)
+static int sp_valid(unsigned long *sp)
 {
        unsigned long addr = (unsigned long) sp;
 
@@ -114,187 +111,371 @@ static int sp_valid (unsigned long *sp)
 }
 #endif
 
-static void kernel_page_fault (unsigned long addr, int mode, struct pt_regs *regs,
-                              struct task_struct *tsk, struct mm_struct *mm)
+#ifdef CONFIG_ALIGNMENT_TRAP
+/*
+ * 32-bit misaligned trap handler (c) 1998 San Mehat (CCC) -July 1998
+ * /proc/sys/debug/alignment, modified and integrated into
+ * Linux 2.1 by Russell King
+ *
+ * NOTE!!! This is not portable onto the ARM6/ARM7 processors yet.  Also,
+ * it seems to give a severe performance impact (1 abort/ms - NW runs at
+ * ARM6 speeds) with GCC 2.7.2.2 - needs checking with a later GCC/EGCS.
+ *
+ * IMHO, I don't think that the trap handler is advantageous on ARM6,7
+ * processors (they'll run like an ARM3).  We'll see.
+ */
+#define CODING_BITS(i) (i & 0x0e000000)
+
+#define LDST_I_BIT(i)  (i & (1 << 26))         /* Immediate constant   */
+#define LDST_P_BIT(i)  (i & (1 << 24))         /* Preindex             */
+#define LDST_U_BIT(i)  (i & (1 << 23))         /* Add offset           */
+#define LDST_W_BIT(i)  (i & (1 << 21))         /* Writeback            */
+#define LDST_L_BIT(i)  (i & (1 << 20))         /* Load                 */
+
+#define LDSTH_I_BIT(i) (i & (1 << 22))         /* half-word immed      */
+#define LDM_S_BIT(i)   (i & (1 << 22))         /* write CPSR from SPSR */
+
+#define RN_BITS(i)     ((i >> 16) & 15)        /* Rn                   */
+#define RD_BITS(i)     ((i >> 12) & 15)        /* Rd                   */
+#define RM_BITS(i)     (i & 15)                /* Rm                   */
+
+#define REGMASK_BITS(i)        (i & 0xffff)
+#define OFFSET_BITS(i) (i & 0x0fff)
+
+#define IS_SHIFT(i)    (i & 0x0ff0)
+#define SHIFT_BITS(i)  ((i >> 7) & 0x1f)
+#define SHIFT_TYPE(i)  (i & 0x60)
+#define SHIFT_LSL      0x00
+#define SHIFT_LSR      0x20
+#define SHIFT_ASR      0x40
+#define SHIFT_RORRRX   0x60
+
+static unsigned long ai_user;
+static unsigned long ai_sys;
+static unsigned long ai_skipped;
+static unsigned long ai_half;
+static unsigned long ai_word;
+static unsigned long ai_multi;
+
+static int proc_alignment_read(char *page, char **start, off_t off,
+                              int count, int *eof, void *data)
 {
-       /*
-        * Oops. The kernel tried to access some bad page. We'll have to
-        * terminate things with extreme prejudice.
-        */
-       pgd_t *pgd;
-       if (addr < PAGE_SIZE)
-           printk (KERN_ALERT "Unable to handle kernel NULL pointer dereference");
-       else
-           printk (KERN_ALERT "Unable to handle kernel paging request");
-       printk (" at virtual address %08lx\n", addr);
-       printk (KERN_ALERT "current->tss.memmap = %08lX\n", tsk->tss.memmap);
-       pgd = pgd_offset (mm, addr);
-       printk (KERN_ALERT "*pgd = %08lx", pgd_val (*pgd));
-       if (!pgd_none (*pgd)) {
-               pmd_t *pmd;
-               pmd = pmd_offset (pgd, addr);
-               printk (", *pmd = %08lx", pmd_val (*pmd));
-               if (!pmd_none (*pmd))
-                       printk (", *pte = %08lx", pte_val (*pte_offset (pmd, addr)));
-       }
-       printk ("\n");
-       die_if_kernel ("Oops", regs, mode, SIGKILL);
-       do_exit (SIGKILL);
+       char *p = page;
+       int len;
+
+       p += sprintf(p, "User:\t\t%li\n", ai_user);
+       p += sprintf(p, "System:\t\t%li\n", ai_sys);
+       p += sprintf(p, "Skipped:\t%li\n", ai_skipped);
+       p += sprintf(p, "Half:\t\t%li\n", ai_half);
+       p += sprintf(p, "Word:\t\t%li\n", ai_word);
+       p += sprintf(p, "Multi:\t\t%li\n", ai_multi);
+
+       len = (p - page) - off;
+       if (len < 0)
+               len = 0;
+
+       *eof = (len <= count) ? 1 : 0;
+       *start = page + off;
+
+       return len;
 }
 
-static void page_fault (unsigned long addr, int mode, struct pt_regs *regs)
+/*
+ * This needs to be done after sysctl_init, otherwise sys/
+ * will be overwritten.
+ */
+void __init alignment_init(void)
 {
-       struct task_struct *tsk;
-       struct mm_struct *mm;
-       struct vm_area_struct *vma;
-       unsigned long fixup;
-
-       lock_kernel();
-       tsk = current;
-       mm = tsk->mm;
-
-       down(&mm->mmap_sem);
-       vma = find_vma (mm, addr);
-       if (!vma)
-               goto bad_area;
-       if (vma->vm_start <= addr)
-               goto good_area;
-       if (!(vma->vm_flags & VM_GROWSDOWN) || expand_stack (vma, addr))
-               goto bad_area;
+       struct proc_dir_entry *e;
 
-       /*
-        * Ok, we have a good vm_area for this memory access, so
-        * we can handle it..
-        */
-good_area:
-       if (mode & FAULT_CODE_READ) { /* read? */
-               if (!(vma->vm_flags & (VM_READ|VM_EXEC)))
-                       goto bad_area;
-       } else {
-               if (!(vma->vm_flags & VM_WRITE))
-                       goto bad_area;
+       e = create_proc_entry("sys/debug/alignment", S_IFREG | S_IRUGO, NULL);
+
+       if (e)
+               e->read_proc = proc_alignment_read;
+}
+
+static int
+do_alignment_exception(struct pt_regs *regs)
+{
+       unsigned int instr, rd, rn, correction, nr_regs, regbits;
+       unsigned long eaddr;
+       union { unsigned long un; signed long sn; } offset;
+
+       if (user_mode(regs)) {
+               set_cr(cr_no_alignment);
+               ai_user += 1;
+               return 0;
        }
-       handle_mm_fault (tsk, vma, addr & PAGE_MASK, !(mode & FAULT_CODE_READ));
-       up(&mm->mmap_sem);
-       goto out;
 
-       /*
-        * Something tried to access memory that isn't in our memory map..
-        * Fix it, but check if it's kernel or user first..
-        */
-bad_area:
-       up(&mm->mmap_sem);
-       if (mode & FAULT_CODE_USER) {
-               tsk->tss.error_code = mode;
-               tsk->tss.trap_no = 14;
-               printk ("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
-                       tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
-#ifdef DEBUG
-               {
-                       unsigned int i, j;
-                       unsigned long *sp = (unsigned long *) (regs->ARM_sp - 128);
-                       for (j = 0; j < 20 && sp_valid (sp); j++) {
-                               printk ("%p: ", sp);
-                               for (i = 0; i < 8 && sp_valid (sp); i += 1, sp++)
-                                       printk ("%08lx ", *sp);
-                               printk ("\n");
+       ai_sys += 1;
+
+       instr = *(unsigned long *)instruction_pointer(regs);
+       correction = 4; /* sometimes 8 on ARMv3 */
+       regs->ARM_pc += correction + 4;
+
+       rd = RD_BITS(instr);
+       rn = RN_BITS(instr);
+       eaddr = regs->uregs[rn];
+
+       switch(CODING_BITS(instr)) {
+       case 0x00000000:
+               if ((instr & 0x0ff00ff0) == 0x01000090) {
+                       ai_skipped += 1;
+                       printk(KERN_ERR "Unaligned trap: not handling swp instruction\n");
+                       return 1;
+               }
+
+               if (((instr & 0x0e000090) == 0x00000090) && (instr & 0x60) != 0) {
+                       ai_half += 1;
+                       if (LDSTH_I_BIT(instr))
+                               offset.un = (instr & 0xf00) >> 4 | (instr & 15);
+                       else
+                               offset.un = regs->uregs[RM_BITS(instr)];
+
+                       if (LDST_P_BIT(instr)) {
+                               if (LDST_U_BIT(instr))
+                                       eaddr += offset.un;
+                               else
+                                       eaddr -= offset.un;
                        }
+
+                       if (LDST_L_BIT(instr))
+                               regs->uregs[rd] = get_unaligned((unsigned short *)eaddr);
+                       else
+                               put_unaligned(regs->uregs[rd], (unsigned short *)eaddr);
+
+                       /* signed half-word? */
+                       if (instr & 0x40)
+                               regs->uregs[rd] = (long)((short) regs->uregs[rd]);
+
+                       if (!LDST_P_BIT(instr)) {
+                               if (LDST_U_BIT(instr))
+                                       eaddr += offset.un;
+                               else
+                                       eaddr -= offset.un;
+                               regs->uregs[rn] = eaddr;
+                       } else if (LDST_W_BIT(instr))
+                               regs->uregs[rn] = eaddr;
+                       break;
                }
-               show_regs (regs);
-               c_backtrace (regs->ARM_fp, regs->ARM_cpsr);
-#endif
-               force_sig(SIGSEGV, tsk);
-               goto out;
-       }
 
-       /* Are we prepared to handle this kernel fault?  */
-       if ((fixup = search_exception_table(instruction_pointer(regs))) != 0) {
-               printk(KERN_DEBUG "%s: Exception at [<%lx>] addr=%lx (fixup: %lx)\n",
-                       tsk->comm, regs->ARM_pc, addr, fixup);
-               regs->ARM_pc = fixup;
-               goto out;
+       default:
+               ai_skipped += 1;
+               panic("Alignment trap: not handling instruction %08X at %08lX",
+                               instr, regs->ARM_pc - correction - 4);
+               break;
+
+       case 0x04000000:
+               offset.un = OFFSET_BITS(instr);
+               goto ldr_str;
+
+       case 0x06000000:
+               offset.un = regs->uregs[RM_BITS(instr)];
+
+               if (IS_SHIFT(instr)) {
+                       unsigned int shiftval = SHIFT_BITS(instr);
+
+                       switch(SHIFT_TYPE(instr)) {
+                       case SHIFT_LSL:
+                               offset.un <<= shiftval;
+                               break;
+
+                       case SHIFT_LSR:
+                               offset.un >>= shiftval;
+                               break;
+
+                       case SHIFT_ASR:
+                               offset.sn >>= shiftval;
+                               break;
+
+                       case SHIFT_RORRRX:
+                               if (shiftval == 0) {
+                                       offset.un >>= 1;
+                                       if (regs->ARM_cpsr & CC_C_BIT)
+                                               offset.un |= 1 << 31;
+                               } else
+                                       offset.un = offset.un >> shiftval |
+                                                         offset.un << (32 - shiftval);
+                               break;
+                       }
+               }
+
+       ldr_str:
+               ai_word += 1;
+               if (LDST_P_BIT(instr)) {
+                       if (LDST_U_BIT(instr))
+                               eaddr += offset.un;
+                       else
+                               eaddr -= offset.un;
+               } else {
+                       if (LDST_W_BIT(instr)) {
+                               printk(KERN_ERR "Not handling ldrt/strt correctly\n");
+                               return 1;
+                       }
+               }
+
+               if (LDST_L_BIT(instr)) {
+                       regs->uregs[rd] = get_unaligned((unsigned long *)eaddr);
+                       if (rd == 15)
+                               correction = 0;
+               } else
+                       put_unaligned(regs->uregs[rd], (unsigned long *)eaddr);
+
+               if (!LDST_P_BIT(instr)) {
+                       if (LDST_U_BIT(instr))
+                               eaddr += offset.un;
+                       else
+                               eaddr -= offset.un;
+
+                       regs->uregs[rn] = eaddr;
+               } else if (LDST_W_BIT(instr))
+                       regs->uregs[rn] = eaddr;
+               break;
+
+       case 0x08000000:
+               if (LDM_S_BIT(instr))
+                       panic("Alignment trap: not handling LDM with s-bit\n");
+               ai_multi += 1;
+
+               for (regbits = REGMASK_BITS(instr), nr_regs = 0; regbits; regbits >>= 1)
+                       nr_regs += 4;
+
+               if  (!LDST_U_BIT(instr))
+                       eaddr -= nr_regs;
+
+               if ((LDST_U_BIT(instr) == 0 && LDST_P_BIT(instr) == 0) ||
+                   (LDST_U_BIT(instr)      && LDST_P_BIT(instr)))
+                       eaddr += 4;
+
+               for (regbits = REGMASK_BITS(instr), rd = 0; regbits; regbits >>= 1, rd += 1)
+                       if (regbits & 1) {
+                               if (LDST_L_BIT(instr)) {
+                                       regs->uregs[rd] = get_unaligned((unsigned long *)eaddr);
+                                       if (rd == 15)
+                                               correction = 0;
+                               } else
+                                       put_unaligned(regs->uregs[rd], (unsigned long *)eaddr);
+                               eaddr += 4;
+                       }
+
+               if (LDST_W_BIT(instr)) {
+                       if (LDST_P_BIT(instr) && !LDST_U_BIT(instr))
+                               eaddr -= nr_regs;
+                       else if (LDST_P_BIT(instr))
+                               eaddr -= 4;
+                       else if (!LDST_U_BIT(instr))
+                               eaddr -= 4 + nr_regs;
+                       regs->uregs[rn] = eaddr;
+               }
+               break;
        }
 
-       kernel_page_fault (addr, mode, regs, tsk, mm);
-out:
-       unlock_kernel();
+       regs->ARM_pc -= correction;
+
+       return 0;
 }
 
-/*
- * Handle a data abort.  Note that we have to handle a range of addresses
- * on ARM2/3 for ldm.  If both pages are zero-mapped, then we have to force
- * a copy-on-write
- */
+#endif
+
 asmlinkage void
-do_DataAbort (unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
+do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
 {
        if (user_mode(regs))
                error_code |= FAULT_CODE_USER;
+
 #define DIE(signr,nam)\
                force_sig(signr, current);\
-               die_if_kernel(nam, regs, fsr, signr);\
-               break;
+               die(nam, regs, fsr);\
+               do_exit(signr);\
+               break
 
        switch (fsr & 15) {
-       case 2:
-               DIE(SIGKILL, "Terminal exception")
+       /*
+        *  0 - vector exception
+        */
        case 0:
-               DIE(SIGSEGV, "Vector exception")
+               force_sig(SIGSEGV, current);
+               if (!user_mode(regs)) {
+                       die("vector exception", regs, fsr);
+                       do_exit(SIGSEGV);
+               }
+               break;
+
+       /*
+        * 15 - permission fault on page
+        *  5 - page-table entry descriptor fault
+        *  7 - first-level descriptor fault
+        */
+       case 15: case 5: case 7:
+               do_page_fault(addr, error_code, regs);
+               break;
+
+       /*
+        * 13 - permission fault on section
+        */
+       case 13:
+               force_sig(SIGSEGV, current);
+               if (!user_mode(regs)) {
+                       die("section permission fault", regs, fsr);
+                       do_exit(SIGSEGV);
+               } else {
+#ifdef CONFIG_DEBUG_USER
+                       printk("%s: permission fault on section, "
+                              "address=0x%08lx, code %d\n",
+                              current->comm, addr, error_code);
+#ifdef DEBUG
+                       {
+                               unsigned int i, j;
+                               unsigned long *sp;
+
+                               sp = (unsigned long *) (regs->ARM_sp - 128);
+                               for (j = 0; j < 20 && sp_valid(sp); j++) {
+                                       printk("%p: ", sp);
+                                       for (i = 0; i < 8 && sp_valid(sp); i += 1, sp++)
+                                               printk("%08lx ", *sp);
+                                       printk("\n");
+                               }
+                               show_regs(regs);
+                               c_backtrace(regs->ARM_fp, regs->ARM_cpsr);
+                       }
+#endif
+#endif
+               }
+               break;
+
        case 1:
        case 3:
-               DIE(SIGBUS, "Alignment exception")
+#ifdef CONFIG_ALIGNMENT_TRAP
+               if (!do_alignment_exception(regs))
+                       break;
+#endif
+               /*
+                * this should never happen
+                */
+               DIE(SIGBUS, "Alignment exception");
+               break;
+
+       case 2:
+               DIE(SIGKILL, "Terminal exception");
        case 12:
        case 14:
-               DIE(SIGBUS, "External abort on translation")
+               DIE(SIGBUS, "External abort on translation");
        case 9:
        case 11:
-               DIE(SIGSEGV, "Domain fault")
-       case 13:/* permission fault on section */
-#ifdef DEBUG
-               {
-                       unsigned int i, j;
-                       unsigned long *sp;
-
-                       printk ("%s: section permission fault (bad address=0x%08lx, code %d)\n",
-                               current->comm, addr, error_code);
-                       sp = (unsigned long *) (regs->ARM_sp - 128);
-                       for (j = 0; j < 20 && sp_valid (sp); j++) {
-                               printk ("%p: ", sp);
-                               for (i = 0; i < 8 && sp_valid (sp); i += 1, sp++)
-                                       printk ("%08lx ", *sp);
-                               printk ("\n");
-                       }
-                       show_regs (regs);
-                       c_backtrace(regs->ARM_fp, regs->ARM_cpsr);
-               }
-#endif
-               DIE(SIGSEGV, "Permission fault")
+               DIE(SIGSEGV, "Domain fault");
 
-       case 15:/* permission fault on page */
-       case 5: /* page-table entry descriptor fault */
-       case 7: /* first-level descriptor fault */
-               page_fault (addr, error_code, regs);
-               break;
        case 4:
        case 6:
-               DIE(SIGBUS, "External abort on linefetch")
+               DIE(SIGBUS, "External abort on linefetch");
        case 8:
        case 10:
-               DIE(SIGBUS, "External abort on non-linefetch")
+               DIE(SIGBUS, "External abort on non-linefetch");
        }
 }
 
 asmlinkage int
-do_PrefetchAbort (unsigned long addr, struct pt_regs *regs)
+do_PrefetchAbort(unsigned long addr, struct pt_regs *regs)
 {
-#if 0
-       /* does this still apply ? */
-       if (the memc mapping for this page exists - can check now...) {
-               printk ("Page in, but got abort (undefined instruction?)\n");
-               return 0;
-       }
-#endif
-       page_fault (addr, FAULT_CODE_USER|FAULT_CODE_READ, regs);
+       do_page_fault(addr, FAULT_CODE_USER|FAULT_CODE_READ, regs);
        return 1;
 }
-
diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c
new file mode 100644 (file)
index 0000000..810dea6
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+ *  linux/arch/arm/mm/fault-common.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Modifications for ARM processor (c) 1995-1999 Russell King
+ */
+#include <linux/config.h>
+
+extern void die(char *msg, struct pt_regs *regs, unsigned int err);
+
+void __bad_pmd(pmd_t *pmd)
+{
+       printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
+#ifdef CONFIG_DEBUG_ERRORS
+       __backtrace();
+#endif
+       set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE));
+}
+
+void __bad_pmd_kernel(pmd_t *pmd)
+{
+       printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
+#ifdef CONFIG_DEBUG_ERRORS
+       __backtrace();
+#endif
+       set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE));
+}
+
+static void
+kernel_page_fault(unsigned long addr, int mode, struct pt_regs *regs,
+                 struct task_struct *tsk, struct mm_struct *mm)
+{
+       char *reason;
+       /*
+        * Oops. The kernel tried to access some bad page. We'll have to
+        * terminate things with extreme prejudice.
+        */
+       pgd_t *pgd;
+
+       if (addr < PAGE_SIZE)
+               reason = "NULL pointer dereference";
+       else
+               reason = "paging request";
+
+       printk(KERN_ALERT "Unable to handle kernel %s at virtual address %08lx\n",
+               reason, addr);
+       printk(KERN_ALERT "memmap = %08lX, pgd = %p\n", tsk->tss.memmap, mm->pgd);
+       pgd = pgd_offset(mm, addr);
+       printk(KERN_ALERT "*pgd = %08lx", pgd_val(*pgd));
+
+       do {
+               pmd_t *pmd;
+               pte_t *pte;
+
+               if (pgd_none(*pgd))
+                       break;
+
+               if (pgd_bad(*pgd)) {
+                       printk("(bad)\n");
+                       break;
+               }
+
+               pmd = pmd_offset(pgd, addr);
+               printk(", *pmd = %08lx", pmd_val(*pmd));
+
+               if (pmd_none(*pmd))
+                       break;
+
+               if (pmd_bad(*pmd)) {
+                       printk("(bad)\n");
+                       break;
+               }
+
+               pte = pte_offset(pmd, addr);
+               printk(", *pte = %08lx", pte_val(*pte));
+               printk(", *ppte = %08lx", pte_val(pte[-PTRS_PER_PTE]));
+       } while(0);
+
+       printk("\n");
+       die("Oops", regs, mode);
+
+       do_exit(SIGKILL);
+}
+
+static void do_page_fault(unsigned long addr, int mode, struct pt_regs *regs)
+{
+       struct task_struct *tsk;
+       struct mm_struct *mm;
+       struct vm_area_struct *vma;
+       unsigned long fixup;
+
+       tsk = current;
+       mm  = tsk->mm;
+
+       /*
+        * If we're in an interrupt or have no user
+        * context, we must not take the fault..
+        */
+       if (in_interrupt() || mm == &init_mm)
+               goto no_context;
+
+       down(&mm->mmap_sem);
+       vma = find_vma(mm, addr);
+       if (!vma)
+               goto bad_area;
+       if (vma->vm_start <= addr)
+               goto good_area;
+       if (!(vma->vm_flags & VM_GROWSDOWN) || expand_stack(vma, addr))
+               goto bad_area;
+
+       /*
+        * Ok, we have a good vm_area for this memory access, so
+        * we can handle it..
+        */
+good_area:
+       if (READ_FAULT(mode)) { /* read? */
+               if (!(vma->vm_flags & (VM_READ|VM_EXEC)))
+                       goto bad_area;
+       } else {
+               if (!(vma->vm_flags & VM_WRITE))
+                       goto bad_area;
+       }
+
+       /*
+        * If for any reason at all we couldn't handle the fault,
+        * make sure we exit gracefully rather than endlessly redo
+        * the fault.
+        */
+       if (!handle_mm_fault(tsk, vma, addr & PAGE_MASK, DO_COW(mode)))
+               goto do_sigbus;
+
+       up(&mm->mmap_sem);
+       return;
+
+       /*
+        * Something tried to access memory that isn't in our memory map..
+        * Fix it, but check if it's kernel or user first..
+        */
+bad_area:
+       up(&mm->mmap_sem);
+
+       /* User mode accesses just cause a SIGSEGV */
+       if (mode & FAULT_CODE_USER) {
+               tsk->tss.error_code = mode;
+               tsk->tss.trap_no = 14;
+#ifdef CONFIG_DEBUG_USER
+               printk("%s: memory violation at pc=0x%08lx, lr=0x%08lx (bad address=0x%08lx, code %d)\n",
+                       tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
+#endif
+               force_sig(SIGSEGV, tsk);
+               return;
+       }
+
+no_context:
+       /* Are we prepared to handle this kernel fault?  */
+       if ((fixup = search_exception_table(instruction_pointer(regs))) != 0) {
+#ifdef DEBUG
+               printk(KERN_DEBUG "%s: Exception at [<%lx>] addr=%lx (fixup: %lx)\n",
+                       tsk->comm, regs->ARM_pc, addr, fixup);
+#endif
+               regs->ARM_pc = fixup;
+               return;
+       }
+
+       kernel_page_fault(addr, mode, regs, tsk, mm);
+       return;
+
+do_sigbus:
+       /*
+        * We ran out of memory, or some other thing happened to us that made
+        * us unable to handle the page fault gracefully.
+        */
+       up(&mm->mmap_sem);
+
+       /*
+        * Send a sigbus, regardless of whether we were in kernel
+        * or user mode.
+        */
+       tsk->tss.error_code = mode;
+       tsk->tss.trap_no = 14;
+       force_sig(SIGBUS, tsk);
+
+       /* Kernel mode? Handle exceptions or die */
+       if (!(mode & FAULT_CODE_USER))
+               goto no_context;
+}
+
+
index b3b0ecf566eb9ab6921916a39595c35f8fe88e30..47a2cfde70ea6644666e5addd435d61f3974a039 100644 (file)
@@ -29,6 +29,9 @@
 #include <asm/proc/mm-init.h>
 
 pgd_t swapper_pg_dir[PTRS_PER_PGD];
+#ifndef CONFIG_NO_PGT_CACHE
+struct pgtable_cache_struct quicklists;
+#endif
 
 extern char _etext, _stext, _edata, __bss_start, _end;
 extern char __init_begin, __init_end;
@@ -36,6 +39,7 @@ extern char __init_begin, __init_end;
 int do_check_pgt_cache(int low, int high)
 {
        int freed = 0;
+#ifndef CONFIG_NO_PGT_CACHE
        if(pgtable_cache_size > high) {
                do {
                        if(pgd_quicklist)
@@ -46,6 +50,7 @@ int do_check_pgt_cache(int low, int high)
                                free_pte_slow(get_pte_fast()), freed++;
                } while(pgtable_cache_size > low);
        }
+#endif
        return freed;
 }
 
@@ -63,17 +68,18 @@ int do_check_pgt_cache(int low, int high)
  * data and COW.
  */
 #if PTRS_PER_PTE != 1
-unsigned long *empty_bad_page_table;
+pte_t *empty_bad_page_table;
 
 pte_t *__bad_pagetable(void)
 {
-       int i;
        pte_t bad_page;
+       int i;
 
        bad_page = BAD_PAGE;
        for (i = 0; i < PTRS_PER_PTE; i++)
-               empty_bad_page_table[i] = (unsigned long)pte_val(bad_page);
-       return (pte_t *) empty_bad_page_table;
+               set_pte(empty_bad_page_table + i, bad_page);
+
+       return empty_bad_page_table;
 }
 #endif
 
@@ -128,8 +134,11 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_
        empty_bad_page = (unsigned long *)start_mem;
        start_mem += PAGE_SIZE;
 #if PTRS_PER_PTE != 1
-       empty_bad_page_table = (unsigned long *)start_mem;
-       start_mem += PTRS_PER_PTE * sizeof (void *);
+#ifdef CONFIG_CPU_32
+       start_mem += PTRS_PER_PTE * BYTES_PER_PTR;
+#endif
+       empty_bad_page_table = (pte_t *)start_mem;
+       start_mem += PTRS_PER_PTE * BYTES_PER_PTR;
 #endif
        memzero (empty_zero_page, PAGE_SIZE);
        start_mem = setup_pagetables (start_mem, end_mem);
@@ -137,6 +146,9 @@ __initfunc(unsigned long paging_init(unsigned long start_mem, unsigned long end_
        flush_tlb_all();
        update_memc_all();
 
+       end_mem &= PAGE_MASK;
+       high_memory = (void *)end_mem;
+
        return free_area_init(start_mem, end_mem);
 }
 
@@ -161,19 +173,18 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
        /* mark usable pages in the mem_map[] */
        mark_usable_memory_areas(&start_mem, end_mem);
 
+#define BETWEEN(w,min,max) ((w) >= (unsigned long)(min) && \
+                           (w) < (unsigned long)(max))
+
        for (tmp = PAGE_OFFSET; tmp < end_mem ; tmp += PAGE_SIZE) {
                if (PageReserved(mem_map+MAP_NR(tmp))) {
-                       if (tmp >= KERNTOPHYS(_stext) &&
-                           tmp < KERNTOPHYS(_edata)) {
-                               if (tmp < KERNTOPHYS(_etext))
-                                       codepages++;
-                               else
-                                       datapages++;
-                       } else if (tmp >= KERNTOPHYS(__init_begin)
-                                  && tmp < KERNTOPHYS(__init_end))
+                       if (BETWEEN(tmp, &__init_begin, &__init_end))
                                initpages++;
-                       else if (tmp >= KERNTOPHYS(__bss_start)
-                                && tmp < (unsigned long) start_mem)
+                       else if (BETWEEN(tmp, &_stext, &_etext))
+                               codepages++;
+                       else if (BETWEEN(tmp, &_etext, &_edata))
+                               datapages++;
+                       else if (BETWEEN(tmp, &__bss_start, start_mem))
                                datapages++;
                        else
                                reservedpages++;
@@ -181,13 +192,16 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
                }
                atomic_set(&mem_map[MAP_NR(tmp)].count, 1);
 #ifdef CONFIG_BLK_DEV_INITRD
-               if (!initrd_start || (tmp < initrd_start || tmp >= initrd_end))
+               if (!initrd_start || !BETWEEN(tmp, initrd_start, initrd_end))
 #endif
                        free_page(tmp);
        }
-       printk ("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
+
+#undef BETWEEN
+
+       printk ("Memory: %luk/%luM available (%dk code, %dk reserved, %dk data, %dk init)\n",
                 (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
-                max_mapnr << (PAGE_SHIFT-10),
+                max_mapnr >> (20 - PAGE_SHIFT),
                 codepages << (PAGE_SHIFT-10),
                 reservedpages << (PAGE_SHIFT-10),
                 datapages << (PAGE_SHIFT-10),
@@ -203,17 +217,45 @@ __initfunc(void mem_init(unsigned long start_mem, unsigned long end_mem))
 #endif
 }
 
-void free_initmem (void)
+static void free_area(unsigned long addr, unsigned long end, char *s)
 {
-       unsigned long addr;
+       unsigned int size = (end - addr) >> 10;
 
-       addr = (unsigned long)(&__init_begin);
-       for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
+       for (; addr < end; addr += PAGE_SIZE) {
                mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
                atomic_set(&mem_map[MAP_NR(addr)].count, 1);
                free_page(addr);
        }
-       printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
+
+       if (size)
+               printk(" %dk %s", size, s);
+}
+
+void free_initmem (void)
+{
+       printk("Freeing unused kernel memory:");
+
+       free_area((unsigned long)(&__init_begin),
+                 (unsigned long)(&__init_end),
+                 "init");
+
+#ifdef CONFIG_FOOTBRIDGE
+       {
+       extern int __netwinder_begin, __netwinder_end, __ebsa285_begin, __ebsa285_end;
+
+       if (!machine_is_netwinder())
+               free_area((unsigned long)(&__netwinder_begin),
+                         (unsigned long)(&__netwinder_end),
+                         "netwinder");
+
+       if (!machine_is_ebsa285() && !machine_is_cats())
+               free_area((unsigned long)(&__ebsa285_begin),
+                         (unsigned long)(&__ebsa285_end),
+                         "ebsa285/cats");
+       }
+#endif
+
+       printk("\n");
 }
 
 void si_meminfo(struct sysinfo *val)
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
new file mode 100644 (file)
index 0000000..70d7c77
--- /dev/null
@@ -0,0 +1,149 @@
+/*
+ * arch/arm/mm/ioremap.c
+ *
+ * Re-map IO memory to kernel address space so that we can access it.
+ *
+ * (C) Copyright 1995 1996 Linus Torvalds
+ *
+ * Hacked for ARM by Phil Blundell <philb@gnu.org>
+ * Hacked to allow all architectures to build, and various cleanups
+ * by Russell King
+ */
+
+/*
+ * This allows a driver to remap an arbitrary region of bus memory into
+ * virtual space.  One should *only* use readl, writel, memcpy_toio and
+ * so on with such remapped areas.
+ *
+ * Because the ARM only has a 32-bit address space we can't address the
+ * whole of the (physical) PCI space at once.  PCI huge-mode addressing
+ * allows us to circumvent this restriction by splitting PCI space into
+ * two 2GB chunks and mapping only one at a time into processor memory.
+ * We use MMU protection domains to trap any attempt to access the bank
+ * that is not currently mapped.  (This isn't fully implemented yet.)
+ *
+ * DC21285 currently has a bug in that the PCI address extension
+ * register affects the address of any writes waiting in the outbound
+ * FIFO.  Unfortunately, it is not possible to tell the DC21285 to
+ * flush this - flushing the area causes the bus to lock.
+ */
+
+#include <linux/vmalloc.h>
+#include <asm/io.h>
+
+static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
+       unsigned long phys_addr, pgprot_t pgprot)
+{
+       unsigned long end;
+
+       address &= ~PMD_MASK;
+       end = address + size;
+       if (end > PMD_SIZE)
+               end = PMD_SIZE;
+       do {
+               if (!pte_none(*pte))
+                       printk("remap_area_pte: page already exists\n");
+               set_pte(pte, mk_pte_phys(phys_addr, pgprot));
+               address += PAGE_SIZE;
+               phys_addr += PAGE_SIZE;
+               pte++;
+       } while (address < end);
+}
+
+static inline int remap_area_pmd(pmd_t * pmd, unsigned long address, unsigned long size,
+       unsigned long phys_addr, unsigned long flags)
+{
+       unsigned long end;
+       pgprot_t pgprot;
+
+       address &= ~PGDIR_MASK;
+       end = address + size;
+
+       if (end > PGDIR_SIZE)
+               end = PGDIR_SIZE;
+
+       phys_addr -= address;
+       pgprot = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY | L_PTE_WRITE | flags);
+       do {
+               pte_t * pte = pte_alloc_kernel(pmd, address);
+               if (!pte)
+                       return -ENOMEM;
+               remap_area_pte(pte, address, end - address, address + phys_addr, pgprot);
+               address = (address + PMD_SIZE) & PMD_MASK;
+               pmd++;
+       } while (address < end);
+       return 0;
+}
+
+static int remap_area_pages(unsigned long address, unsigned long phys_addr,
+                                unsigned long size, unsigned long flags)
+{
+       pgd_t * dir;
+       unsigned long end = address + size;
+
+       phys_addr -= address;
+       dir = pgd_offset(&init_mm, address);
+       flush_cache_all();
+       while (address < end) {
+               pmd_t *pmd = pmd_alloc_kernel(dir, address);
+               if (!pmd)
+                       return -ENOMEM;
+               if (remap_area_pmd(pmd, address, end - address,
+                                        phys_addr + address, flags))
+                       return -ENOMEM;
+               set_pgdir(address, *dir);
+               address = (address + PGDIR_SIZE) & PGDIR_MASK;
+               dir++;
+       }
+       flush_tlb_all();
+       return 0;
+}
+
+/*
+ * Remap an arbitrary physical address space into the kernel virtual
+ * address space. Needed when the kernel wants to access high addresses
+ * directly.
+ *
+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously
+ * have to convert them into an offset in a page-aligned mapping, but the
+ * caller shouldn't need to know that small detail.
+ *
+ * 'flags' are the extra L_PTE_ flags that you want to specify for this
+ * mapping.  See include/asm-arm/proc-armv/pgtable.h for more information.
+ */
+void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flags)
+{
+       void * addr;
+       struct vm_struct * area;
+       unsigned long offset;
+
+       /*
+        * Mappings have to be page-aligned
+        */
+       offset = phys_addr & ~PAGE_MASK;
+       size = PAGE_ALIGN(size + offset);
+
+       /*
+        * Don't allow mappings that wrap..
+        */
+       if (!size || size > phys_addr + size)
+               return NULL;
+
+       /*
+        * Ok, go for it..
+        */
+       area = get_vm_area(size);
+       if (!area)
+               return NULL;
+       addr = area->addr;
+       if (remap_area_pages(VMALLOC_VMADDR(addr), phys_addr, size, flags)) {
+               vfree(addr);
+               return NULL;
+       }
+       return (void *) (offset + (char *)addr);
+}
+
+void iounmap(void *addr)
+{
+       return vfree((void *) (PAGE_MASK & (unsigned long) addr));
+}
diff --git a/arch/arm/mm/mm-arc.c b/arch/arm/mm/mm-arc.c
deleted file mode 100644 (file)
index 6bb92f0..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * arch/arm/mm/mm-arc.c
- *
- * Extra MM routines for the Archimedes architecture
- *
- * Copyright (C) 1998 Russell King
- */
-#include <linux/init.h>
-#include <asm/hardware.h>
-#include <asm/pgtable.h>
-
-unsigned long phys_screen_end;
-
-/*
- * This routine needs more work to make it dynamically release/allocate mem!
- */
-__initfunc(unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update))
-{
-       static int updated = 0;
-
-       if (updated)
-               return 0;
-
-       updated = update;
-
-       if (update) {
-               unsigned long address = log_start, offset;
-               pgd_t *pgdp;
-
-               kmem = (kmem + 3) & ~3;
-
-               pgdp = pgd_offset (&init_mm, address);                          /* +31 */
-               offset = SCREEN_START;
-               while (address < SCREEN1_END) {
-                       unsigned long addr_pmd, end_pmd;
-                       pmd_t *pmdp;
-
-                       /* if (pgd_none (*pgdp)) alloc pmd */
-                       pmdp = pmd_offset (pgdp, address);                      /* +0 */
-                       addr_pmd = address & ~PGDIR_MASK;                       /* 088000 */
-                       end_pmd = addr_pmd + SCREEN1_END - address;             /* 100000 */
-                       if (end_pmd > PGDIR_SIZE)
-                               end_pmd = PGDIR_SIZE;
-
-                       do {
-                               unsigned long addr_pte, end_pte;
-                               pte_t *ptep;
-
-                               if (pmd_none (*pmdp)) {
-                                       pte_t *new_pte = (pte_t *)kmem;
-                                       kmem += PTRS_PER_PTE * BYTES_PER_PTR;
-                                       memzero (new_pte, PTRS_PER_PTE * BYTES_PER_PTR);
-                                       set_pmd (pmdp, mk_pmd(new_pte));
-                               }
-
-                               ptep = pte_offset (pmdp, addr_pmd);             /* +11 */
-                               addr_pte = addr_pmd & ~PMD_MASK;                /* 088000 */
-                               end_pte = addr_pte + end_pmd - addr_pmd;        /* 100000 */
-                               if (end_pte > PMD_SIZE)
-                                       end_pte = PMD_SIZE;
-
-                               do {
-                                       set_pte (ptep, mk_pte(offset, PAGE_KERNEL));
-                                       addr_pte += PAGE_SIZE;
-                                       offset += PAGE_SIZE;
-                                       ptep++;
-                               } while (addr_pte < end_pte);
-
-                               pmdp++;
-                               addr_pmd = (addr_pmd + PMD_SIZE) & PMD_MASK;
-                       } while (addr_pmd < end_pmd);
-
-                       address = (address + PGDIR_SIZE) & PGDIR_MASK;
-                       pgdp ++;
-               }
-
-               phys_screen_end = offset;
-               flush_tlb_all ();
-               update_memc_all ();
-       }
-       return kmem;
-}
index 8a226526bd2e7bbad8947ce09993d1dcd5d136ac..4481fc32b437297dee9c31558d6cb2348dfa4aec 100644 (file)
@@ -37,7 +37,8 @@ __initfunc(unsigned long setup_io_pagetables(unsigned long start_mem))
                virtual = mp->virtual;
                physical = mp->physical;
                length = mp->length;
-               prot = (mp->prot_read ? PTE_AP_READ : 0) | (mp->prot_write ? PTE_AP_WRITE : 0);
+               prot = (mp->prot_read ? L_PTE_USER : 0) | (mp->prot_write ? L_PTE_WRITE : 0)
+                       | L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY;
 
                while ((virtual & 1048575 || physical & 1048575) && length >= PAGE_SIZE) {
                        alloc_init_page(&start_mem, virtual, physical, mp->domain, prot);
@@ -56,7 +57,8 @@ __initfunc(unsigned long setup_io_pagetables(unsigned long start_mem))
                        physical += 1048576;
                }
 
-               prot = (mp->prot_read ? PTE_AP_READ : 0) | (mp->prot_write ? PTE_AP_WRITE : 0);
+               prot = (mp->prot_read ? L_PTE_USER : 0) | (mp->prot_write ? L_PTE_WRITE : 0)
+                       | L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY;
 
                while (length >= PAGE_SIZE) {
                        alloc_init_page(&start_mem, virtual, physical, mp->domain, prot);
diff --git a/arch/arm/mm/mm-ebsa285.c b/arch/arm/mm/mm-ebsa285.c
deleted file mode 100644 (file)
index a5b17c6..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * arch/arm/mm/mm-ebsa285.c
- *
- * Extra MM routines for the EBSA285 architecture
- *
- * Copyright (C) 1998 Russell King, Dave Gilbert.
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/io.h>
-#include <asm/proc/mm-init.h>
-#include <asm/dec21285.h>
-
-/*
- * This is to allow us to fiddle with the EEPROM
- *  This entry will go away in time, once the fmu
- *  can mmap() the flash.
- *
- * These ones are so that we can fiddle
- *  with the various cards (eg VGA)
- *  until we're happy with them...
- */
-#define MAPPING \
-  { 0xd8000000, DC21285_FLASH,               0x00400000, DOMAIN_USER, 1, 1 },  /* EEPROM */        \
-  { 0xdc000000, 0x7c000000,                  0x00100000, DOMAIN_USER, 1, 1 },  /* VGA */           \
-  { 0xe0000000, DC21285_PCI_MEM,             0x18000000, DOMAIN_USER, 1, 1 },  /* VGA */           \
-  { 0xf8000000, DC21285_PCI_TYPE_0_CONFIG,    0x01000000, DOMAIN_IO  , 0, 1 }, /* Type 0 Config */ \
-  { 0xf9000000, DC21285_PCI_TYPE_1_CONFIG,    0x01000000, DOMAIN_IO  , 0, 1 }, /* Type 1 Config */ \
-  { PCI_IACK,  DC21285_PCI_IACK,             0x01000000, DOMAIN_IO  , 0, 1 },  /* PCI IACK      */ \
-  { 0xfd000000, DC21285_OUTBOUND_WRITE_FLUSH, 0x01000000, DOMAIN_IO  , 0, 1 }, /* Out wrflsh    */ \
-  { 0xfe000000, DC21285_ARMCSR_BASE,         0x01000000, DOMAIN_IO  , 0, 1 },  /* CSR           */ \
-  { 0xffe00000, DC21285_PCI_IO,              0x00100000, DOMAIN_IO  , 0, 1 },  /* PCI I/O       */ \
-  { 0xfff00000, 0x40000000,                  0x00100000, DOMAIN_IO  , 0, 1 },  /* X-Bus         */
-
-#include "mm-armv.c"
diff --git a/arch/arm/mm/mm-footbridge.c b/arch/arm/mm/mm-footbridge.c
new file mode 100644 (file)
index 0000000..ec7e64c
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ * arch/arm/mm/mm-ebsa285.c
+ *
+ * Extra MM routines for the EBSA285 architecture
+ *
+ * Copyright (C) 1998 Russell King, Dave Gilbert.
+ */
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/io.h>
+#include <asm/proc/mm-init.h>
+#include <asm/dec21285.h>
+
+/*
+ * The first entry allows us to fiddle with the EEPROM from user-space.
+ *  This entry will go away in time, once the fmu32 can mmap() the
+ *  flash.  It can't at the moment.
+ *
+ * If you want to fiddle with PCI VGA cards from user space, then
+ * change the '0, 1 }' for the PCI MEM and PCI IO to '1, 1 }'
+ * You can then access the PCI bus at 0xe0000000 and 0xffe00000.
+ */
+
+#ifdef CONFIG_HOST_FOOTBRIDGE
+
+/*
+ * The mapping when the footbridge is in host mode.
+ */
+#define MAPPING \
+ { FLASH_BASE,   DC21285_FLASH,                        FLASH_SIZE,     DOMAIN_IO, 0, 1 }, \
+ { PCIMEM_BASE,  DC21285_PCI_MEM,              PCIMEM_SIZE,    DOMAIN_IO, 0, 1 }, \
+ { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG,    PCICFG0_SIZE,   DOMAIN_IO, 0, 1 }, \
+ { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG,    PCICFG1_SIZE,   DOMAIN_IO, 0, 1 }, \
+ { PCIIACK_BASE, DC21285_PCI_IACK,             PCIIACK_SIZE,   DOMAIN_IO, 0, 1 }, \
+ { WFLUSH_BASE,  DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE,    DOMAIN_IO, 0, 1 }, \
+ { ARMCSR_BASE,  DC21285_ARMCSR_BASE,          ARMCSR_SIZE,    DOMAIN_IO, 0, 1 }, \
+ { PCIO_BASE,    DC21285_PCI_IO,               PCIO_SIZE,      DOMAIN_IO, 0, 1 }, \
+ { XBUS_BASE,    0x40000000,                   XBUS_SIZE,      DOMAIN_IO, 0, 1 }
+
+#else
+
+/*
+ * These two functions convert virtual addresses to PCI addresses
+ * and PCI addresses to virtual addresses.  Note that it is only
+ * legal to use these on memory obtained via get_free_page or
+ * kmalloc.
+ */
+unsigned long __virt_to_bus(unsigned long res)
+{
+#ifdef CONFIG_DEBUG_ERRORS
+       if (res < PAGE_OFFSET || res >= (unsigned long)high_memory) {
+               printk("__virt_to_phys: invalid virtual address 0x%08lx\n", res);
+               __backtrace();
+       }
+#endif
+       return (res - PAGE_OFFSET) + (*CSR_PCISDRAMBASE & 0xfffffff0);
+}
+
+unsigned long __bus_to_virt(unsigned long res)
+{
+       res -= (*CSR_PCISDRAMBASE & 0xfffffff0);
+       res += PAGE_OFFSET;
+
+#ifdef CONFIG_DEBUG_ERRORS
+       if (res < PAGE_OFFSET || res >= (unsigned long)high_memory) {
+               printk("__phys_to_virt: invalid virtual address 0x%08lx\n", res);
+               __backtrace();
+       }
+#endif
+       return res;
+}
+
+/*
+ * The mapping when the footbridge is in add-in mode.
+ */
+#define MAPPING \
+ { PCIO_BASE,   DC21285_PCI_IO,                PCIO_SIZE,      DOMAIN_IO, 0, 1 }, \
+ { XBUS_BASE,   0x40000000,                    XBUS_SIZE,      DOMAIN_IO, 0, 1 }, \
+ { ARMCSR_BASE,  DC21285_ARMCSR_BASE,          ARMCSR_SIZE,    DOMAIN_IO, 0, 1 }, \
+ { WFLUSH_BASE,         DC21285_OUTBOUND_WRITE_FLUSH,  WFLUSH_SIZE,    DOMAIN_IO, 0, 1 }, \
+ { FLASH_BASE,  DC21285_FLASH,                 FLASH_SIZE,     DOMAIN_IO, 0, 1 }, \
+ { PCIMEM_BASE,         DC21285_PCI_MEM,               PCIMEM_SIZE,    DOMAIN_IO, 0, 1 }
+
+#endif
+
+#include "mm-armv.c"
diff --git a/arch/arm/mm/mm-vnc.c b/arch/arm/mm/mm-vnc.c
deleted file mode 100644 (file)
index 94e0374..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * arch/arm/mm/mm-vnc.c
- *
- * Extra MM routines for the Corel VNC architecture
- *
- * Copyright (C) 1998 Russell King
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/io.h>
-#include <asm/proc/mm-init.h>
-#include <asm/dec21285.h>
-
-/* Table describing the MMU translation mapping
- * mainly used to set up the I/O mappings.
- */ 
-#define MAPPING \
-  { 0xd0000000, DC21285_FLASH,               0x00800000, DOMAIN_IO  , 0, 1 },  /* Flash         */ \
-  { 0xe0000000, DC21285_PCI_MEM,             0x18000000, DOMAIN_IO  , 0, 1 },  /* PCI Mem       */ \
-  { 0xf8000000, DC21285_PCI_TYPE_0_CONFIG,    0x01000000, DOMAIN_IO  , 0, 1 }, /* Type 0 Config */ \
-  { 0xf9000000, DC21285_PCI_TYPE_1_CONFIG,    0x01000000, DOMAIN_IO  , 0, 1 }, /* Type 1 Config */ \
-  { PCI_IACK,  DC21285_PCI_IACK,             0x01000000, DOMAIN_IO  , 0, 1 },  /* PCI IACK      */ \
-  { 0xfd000000, DC21285_OUTBOUND_WRITE_FLUSH, 0x01000000, DOMAIN_IO  , 0, 1 }, /* Out wrflsh    */ \
-  { 0xfe000000, DC21285_ARMCSR_BASE,         0x01000000, DOMAIN_IO  , 0, 1 },  /* CSR           */ \
-  { 0xffe00000, DC21285_PCI_IO,              0x00100000, DOMAIN_IO  , 0, 1 },  /* PCI I/O       */ \
-
-#include "mm-armv.c"
index 86cab564af3f0a784d38ba1d9f430dec307400a5..263d79708f478602947995bc554c137cf4ead040 100644 (file)
@@ -193,7 +193,7 @@ _arm2_3_data_abort:
                movs    pc, lr
 
 _arm2_3_check_bugs:
-               movs    pc, lr
+               bics    pc, lr, #0x04000000             @ Clear FIQ disable bit
 
 /*
  * Processor specific - ARM2
@@ -206,6 +206,8 @@ LC0:                .word   SYMBOL_NAME(page_nr)
  * Params  : prev      Old task structure
  *        : next       New task structure for process to run
  *
+ * Returns : prev
+ *
  * Purpose : Perform a task switch, saving the old processes state, and restoring
  *          the new.
  *
@@ -218,15 +220,15 @@ _arm2_switch_to:
                str     sp, [r0, #TSS_SAVE]             @ Save sp_SVC
                ldr     sp, [r1, #TSS_SAVE]             @ Get saved sp_SVC
                mov     r4, r1
-               add     r0, r1, #TSS_MEMCMAP            @ Remap MEMC
+               add     r7, r1, #TSS_MEMCMAP            @ Remap MEMC
                ldr     r1, LC0
                ldr     r1, [r1]
-1:             ldmia   r0!, {r2, r3, r5, r6}
+1:             ldmia   r7!, {r2, r3, r5, r6}
                strb    r2, [r2]
                strb    r3, [r3]
                strb    r5, [r5]
                strb    r6, [r6]
-               ldmia   r0!, {r2, r3, r5, r6}
+               ldmia   r7!, {r2, r3, r5, r6}
                strb    r2, [r2]
                strb    r3, [r3]
                strb    r5, [r5]
@@ -318,6 +320,8 @@ _arm2_proc_fin:     movs    pc, lr
  * Params  : prev      Old task structure
  *        : next       New task structure for process to run
  *
+ * Returns : prev
+ *
  * Purpose : Perform a task switch, saving the old processes state, and restoring
  *          the new.
  *
@@ -330,22 +334,22 @@ _arm3_switch_to:
                str     sp, [r0, #TSS_SAVE]             @ Save sp_SVC
                ldr     sp, [r1, #TSS_SAVE]             @ Get saved sp_SVC
                mov     r4, r1
-               add     r0, r1, #TSS_MEMCMAP            @ Remap MEMC
+               add     r7, r1, #TSS_MEMCMAP            @ Remap MEMC
                ldr     r1, LC0
                ldr     r1, [r1]
-1:             ldmia   r0!, {r2, r3, r5, r6}
+1:             ldmia   r7!, {r2, r3, r5, r6}
                strb    r2, [r2]
                strb    r3, [r3]
                strb    r5, [r5]
                strb    r6, [r6]
-               ldmia   r0!, {r2, r3, r5, r6}
+               ldmia   r7!, {r2, r3, r5, r6}
                strb    r2, [r2]
                strb    r3, [r3]
                strb    r5, [r5]
                strb    r6, [r6]
                subs    r1, r1, #8
                bhi     1b
-               mcr     p15, 0, r0, c1, c0, 0           @ flush cache
+               mcr     p15, 0, r7, c1, c0, 0           @ flush cache
                ldmfd   sp!, {r4 - r9, fp, pc}^         @ Load all regs saved previously
 /*
  * Function: arm3_remap_memc (struct task_struct *tsk)
index b7119a330125197e41d1cdad9b1d1b840e1eff6b..b817ae2b4c37e4ce052f4187b1acf816d3d41919 100644 (file)
@@ -52,13 +52,14 @@ _arm6_7_flush_tlb_area:
                blt     1b
                mov     pc, lr
 
-@LC0:          .word   _current
 /*
  * Function: arm6_7_switch_to (struct task_struct *prev, struct task_struct *next)
  *
  * Params  : prev      Old task structure
  *        : next       New task structure for process to run
  *
+ * Returns : prev
+ *
  * Purpose : Perform a task switch, saving the old processes state, and restoring
  *          the new.
  *
@@ -72,15 +73,15 @@ _arm6_7_switch_to:
                stmfd   sp!, {ip}                       @ Save cpsr_SVC
                str     sp, [r0, #TSS_SAVE]             @ Save sp_SVC
                ldr     sp, [r1, #TSS_SAVE]             @ Get saved sp_SVC
-               ldr     r0, [r1, #TSK_ADDR_LIMIT]
-               teq     r0, #0
-               moveq   r0, #DOM_KERNELDOMAIN
-               movne   r0, #DOM_USERDOMAIN
-               mcr     p15, 0, r0, c3, c0              @ Set domain reg
-               ldr     r0, [r1, #TSS_MEMMAP]           @ Page table pointer
+               ldr     r2, [r1, #TSK_ADDR_LIMIT]
+               teq     r2, #0
+               moveq   r2, #DOM_KERNELDOMAIN
+               movne   r2, #DOM_USERDOMAIN
+               mcr     p15, 0, r2, c3, c0              @ Set domain reg
+               ldr     r2, [r1, #TSS_MEMMAP]           @ Page table pointer
                mov     r1, #0
                mcr     p15, 0, r1, c7, c0, 0           @ flush cache
-               mcr     p15, 0, r0, c2, c0, 0           @ update page table ptr
+               mcr     p15, 0, r2, c2, c0, 0           @ update page table ptr
                mcr     p15, 0, r1, c5, c0, 0           @ flush TLBs
                ldmfd   sp!, {ip}
                msr     spsr, ip                        @ Save tasks CPSR into SPSR for this return
@@ -368,6 +369,35 @@ _arm7_set_pmd:     tst     r1, #3
                str     r1, [r0]
                mov     pc, lr
 
+/*
+ * Function: arm6_7_set_pte(pte_t *ptep, pte_t pte)
+ * Params  : r0 = Address to set
+ *        : r1 = value to set
+ * Purpose : Set a PTE and flush it out of any WB cache
+ */
+               .align  5
+_arm6_7_set_pte:
+               str     r1, [r0], #-1024                @ linux version
+
+               bic     r2, r1, #0xff0
+               bic     r2, r2, #3
+               orr     r2, r2, #HPTE_TYPE_SMALL
+
+               tst     r1, #LPTE_USER | LPTE_EXEC
+               orrne   r2, r2, #HPTE_AP_READ
+
+               tst     r1, #LPTE_WRITE
+               tstne   r1, #LPTE_DIRTY
+               orrne   r2, r2, #HPTE_AP_WRITE
+
+               tst     r1, #LPTE_PRESENT
+               tstne   r1, #LPTE_YOUNG
+               moveq   r2, #0
+
+               str     r2, [r0]                        @ hardware version
+               mcr     p15, 0, r0, c7, c10, 1          @ clean D entry  (drain is done by TLB fns)
+               mov     pc, lr
+
 /*
  * Function: _arm6_7_reset
  *
@@ -405,8 +435,12 @@ ENTRY(arm6_processor_functions)
                .word   _arm6_7_flush_tlb_all           @ 44
                .word   _arm6_7_flush_tlb_area          @ 48
                .word   _arm6_set_pmd                   @ 52
-               .word   _arm6_7_reset                   @ 54
-               .word   _arm6_7_flush_cache             @ 58
+               .word   _arm6_7_set_pte                 @ 56
+               .word   _arm6_7_reset                   @ 60
+               .word   _arm6_7_flush_cache             @ 64
+
+               .word   _arm6_7_flush_cache             @ 68
+               .word   _arm6_7_flush_cache             @ 72
 
 /*
  * Purpose : Function pointers used to access above functions - all calls
@@ -431,8 +465,9 @@ ENTRY(arm7_processor_functions)
                .word   _arm6_7_flush_tlb_all           @ 44
                .word   _arm6_7_flush_tlb_area          @ 48
                .word   _arm7_set_pmd                   @ 52
-               .word   _arm6_7_reset                   @ 56
-               .word   _arm6_7_flush_cache             @ 60
-
+               .word   _arm6_7_set_pte                 @ 56
+               .word   _arm6_7_reset                   @ 60
                .word   _arm6_7_flush_cache             @ 64
+
                .word   _arm6_7_flush_cache             @ 68
+               .word   _arm6_7_flush_cache             @ 72
index 221797862611ed16aed44bf5a527f003d1cee5aa..ff55c8ffa170ad596ce4a309472e0e8fca1a4cd8 100644 (file)
@@ -8,6 +8,7 @@
  */
 #include <linux/linkage.h>
 #include <asm/assembler.h>
+#include <asm/hardware.h>
 #include "../lib/constants.h"
 
 /* This is the maximum size of an area which will be flushed.  If the area
@@ -21,7 +22,6 @@ Lclean_switch:        .long   0
 
 /*
  * Function: sa110_flush_cache_all (void)
- *
  * Purpose : Flush all cache lines
  */
                .align  5
@@ -33,7 +33,7 @@ _sa110_flush_cache_all_r2:
                ands    r1, r1, #1
                eor     r1, r1, #1
                str     r1, [r3]
-               ldr     ip, =0xdf000000
+               ldr     ip, =FLUSH_BASE
                addne   ip, ip, #32768
                add     r1, ip, #16384                  @ only necessary for 16k
 1:             ldr     r3, [ip], #32
@@ -47,11 +47,9 @@ _sa110_flush_cache_all_r2:
 
 /*
  * Function: sa110_flush_cache_area (unsigned long address, int end, int flags)
- *
  * Params  : address   Area start address
  *        : end        Area end address
  *        : flags      b0 = I cache as well
- *
  * Purpose : clean & flush all cache lines associated with this area of memory
  */
                .align  5
@@ -74,10 +72,8 @@ _sa110_flush_cache_area:
 
 /*
  * Function: sa110_cache_wback_area(unsigned long address, unsigned long end)
- *
  * Params  : address   Area start address
  *        : end        Area end address
- *
  * Purpose : ensure all dirty cachelines in the specified area have been
  *          written out to memory (for DMA)
  */
@@ -99,13 +95,10 @@ _sa110_cache_wback_area:
 
 /*
  * Function: sa110_cache_purge_area(unsigned long address, unsigned long end)
- *
  * Params  : address   Area start address
  *        : end        Area end address
- *
  * Purpose : throw away all D-cached data in specified region without
- *          an obligation to write it ack.
- *
+ *          an obligation to write it back.
  * Note    : Must clean the D-cached entries around the boundaries if the
  *          start and/or end address are not cache aligned.
  */
@@ -124,9 +117,7 @@ _sa110_cache_purge_area:
 
 /*
  * Function: sa110_flush_cache_entry (unsigned long address)
- *
  * Params  : address   Address of cache line to flush
- *
  * Purpose : clean & flush an entry
  */
                .align  5
@@ -138,24 +129,23 @@ _sa110_flush_cache_entry:
                mov     pc, lr
 
 /*
- * Function: sa110_flush_cache_pte (unsigned long address)
- *
+ * Function: sa110_clean_cache_area(unsigned long start, unsigned long size)
  * Params  : address   Address of cache line to clean
- *
  * Purpose : Ensure that physical memory reflects cache at this location
  *          for page table purposes.
  */
-_sa110_flush_cache_pte:
-               mcr     p15, 0, r0, c7, c10, 1          @ clean D entry  (drain is done by TLB fns)
+_sa110_clean_cache_area:
+1:             mcr     p15, 0, r0, c7, c10, 1          @ clean D entry  (drain is done by TLB fns)
+               add     r0, r0, #32
+               subs    r1, r1, #32
+               bhi     1b
                mov     pc, lr
 
 /*
  * Function: sa110_flush_ram_page (unsigned long page)
- *
  * Params  : address   Area start address
  *        : size       size of area
  *        : flags      b0 = I cache as well
- *
  * Purpose : clean & flush all cache lines associated with this area of memory
  */
                .align  5
@@ -176,7 +166,6 @@ _sa110_flush_ram_page:
 
 /*
  * Function: sa110_flush_tlb_all (void)
- *
  * Purpose : flush all TLB entries in all caches
  */
                .align  5
@@ -188,11 +177,9 @@ _sa110_flush_tlb_all:
 
 /*
  * Function: sa110_flush_tlb_area (unsigned long address, unsigned long end, int flags)
- *
  * Params  : address   Area start address
  *        : end        Area end address
  *        : flags      b0 = I cache as well
- *
  * Purpose : flush a TLB entry
  */
                .align  5
@@ -212,22 +199,21 @@ _sa110_flush_tlb_area:
 
                .align  5
 _sa110_flush_icache_area:
-               mov     r3, #0
 1:             mcr     p15, 0, r0, c7, c10, 1          @ Clean D entry
                add     r0, r0, #32
-               cmp     r0, r1
-               blt     1b
+               subs    r1, r1, #32
+               bhi     1b
+               mov     r0, #0
+               mcr     p15, 0, r0, c7, c10, 4          @ drain WB
                mcr     p15, 0, r0, c7, c5, 0           @ flush I cache
                mov     pc, lr
 /*
  * Function: sa110_switch_to (struct task_struct *prev, struct task_struct *next)
- *
  * Params  : prev      Old task structure
  *        : next       New task structure for process to run
- *
+ * Returns : prev
  * Purpose : Perform a task switch, saving the old processes state, and restoring
  *          the new.
- *
  * Notes   : We don't fiddle with the FP registers here - we postpone this until
  *          the new task actually uses FP.  This way, we don't swap FP for tasks
  *          that do not require it.
@@ -237,20 +223,30 @@ _sa110_switch_to:
                stmfd   sp!, {r4 - r9, fp, lr}          @ Store most regs on stack
                mrs     ip, cpsr
                stmfd   sp!, {ip}                       @ Save cpsr_SVC
+               ldr     r2, [r0, #TSS_MEMMAP]           @ Get old page tables
                str     sp, [r0, #TSS_SAVE]             @ Save sp_SVC
                ldr     sp, [r1, #TSS_SAVE]             @ Get saved sp_SVC
-               ldr     r0, [r1, #TSK_ADDR_LIMIT]
-               teq     r0, #0
-               moveq   r0, #DOM_KERNELDOMAIN
-               movne   r0, #DOM_USERDOMAIN
-               mcr     p15, 0, r0, c3, c0              @ Set segment
-               ldr     r0, [r1, #TSS_MEMMAP]           @ Page table pointer
+               ldr     r4, [r1, #TSK_ADDR_LIMIT]
+               teq     r4, #0
+               moveq   r4, #DOM_KERNELDOMAIN
+               movne   r4, #DOM_USERDOMAIN
+               mcr     p15, 0, r4, c3, c0              @ Set segment
+               ldr     r4, [r1, #TSS_MEMMAP]           @ Page table pointer
+/*
+ * Flushing the cache is nightmarishly slow, so we take any excuse
+ * to get out of it.  If the old page table is the same as the new,
+ * this is a CLONE_VM relative of the old task and there is no need
+ * to flush.  The overhead of the tests isn't even on the radar
+ * compared to the cost of the flush itself.
+ */
+               teq     r4, r2
+               beq     2f
                ldr     r3, =Lclean_switch
                ldr     r2, [r3]
                ands    r2, r2, #1
                eor     r2, r2, #1
                str     r2, [r3]
-               ldr     r2, =0xdf000000
+               ldr     r2, =FLUSH_BASE
                addne   r2, r2, #32768
                add     r1, r2, #16384                  @ only necessary for 16k
 1:             ldr     r3, [r2], #32
@@ -259,19 +255,16 @@ _sa110_switch_to:
                mov     r1, #0
                mcr     p15, 0, r1, c7, c5, 0           @ flush I cache
                mcr     p15, 0, r1, c7, c10, 4          @ drain WB
-               mcr     p15, 0, r0, c2, c0, 0           @ load page table pointer
+               mcr     p15, 0, r4, c2, c0, 0           @ load page table pointer
                mcr     p15, 0, r1, c8, c7, 0           @ flush TLBs
-               ldmfd   sp!, {ip}
+2:             ldmfd   sp!, {ip}
                msr     spsr, ip                        @ Save tasks CPSR into SPSR for this return
                ldmfd   sp!, {r4 - r9, fp, pc}^         @ Load all regs saved previously
 
 /*
  * Function: sa110_data_abort ()
- *
  * Params  : r0 = address of aborted instruction
- *
  * Purpose : obtain information about current aborted instruction
- *
  * Returns : r0 = address of abort
  *        : r1 = FSR
  *        : r2 != 0 if writing
@@ -288,36 +281,62 @@ _sa110_data_abort:
                mov     pc, lr
 
 /*
- * Function: sa110_set_pmd ()
- *
+ * Function: sa110_set_pmd(pmd_t *pmdp, pmd_t pmd)
  * Params  : r0 = Address to set
  *        : r1 = value to set
- *
- * Purpose : Set a PMD and flush it out of any WB cache
+ * Purpose : Set a PMD and flush it out
  */
                .align  5
 _sa110_set_pmd:        str     r1, [r0]
                mcr     p15, 0, r0, c7, c10, 1          @ clean D entry  (drain is done by TLB fns)
                mov     pc, lr
 
+/*
+ * Function: sa110_set_pte(pte_t *ptep, pte_t pte)
+ * Params  : r0 = Address to set
+ *        : r1 = value to set
+ * Purpose : Set a PTE and flush it out
+ */
+               .align  5
+_sa110_set_pte:        str     r1, [r0], #-1024                @ linux version
+
+               eor     r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+               bic     r2, r1, #0xff0
+               bic     r2, r2, #3
+               orr     r2, r2, #HPTE_TYPE_SMALL
+
+               tst     r1, #LPTE_USER | LPTE_EXEC      @ User or Exec?
+               orrne   r2, r2, #HPTE_AP_READ
+
+               tst     r1, #LPTE_WRITE | LPTE_DIRTY    @ Write and Dirty?
+               orreq   r2, r2, #HPTE_AP_WRITE
+
+               tst     r1, #LPTE_PRESENT | LPTE_YOUNG  @ Present and Young?
+               movne   r2, #0
+
+               str     r2, [r0]                        @ hardware version
+               mov     r0, r0
+               mcr     p15, 0, r0, c7, c10, 1          @ clean D entry  (drain is done by TLB fns)
+               mov     pc, lr
+
 /*
  * Function: sa110_check_bugs (void)
  *        : sa110_proc_init (void)
  *        : sa110_proc_fin (void)
- *
  * Notes   : This processor does not require these
  */
 _sa110_check_bugs:
                mrs     ip, cpsr
                bic     ip, ip, #F_BIT
                msr     cpsr, ip
+
 _sa110_proc_init:
 _sa110_proc_fin:
                mov     pc, lr
 
 /*
  * Function: sa110_reset
- *
  * Notes   : This sets up everything for a reset
  */
 _sa110_reset:  mrs     r1, cpsr
@@ -350,14 +369,15 @@ ENTRY(sa110_processor_functions)
                .word   _sa110_flush_cache_all          @ 24
                .word   _sa110_flush_cache_area         @ 28
                .word   _sa110_flush_cache_entry        @ 32
-               .word   _sa110_flush_cache_pte          @ 36
+               .word   _sa110_clean_cache_area         @ 36
                .word   _sa110_flush_ram_page           @ 40
                .word   _sa110_flush_tlb_all            @ 44
                .word   _sa110_flush_tlb_area           @ 48
 
                .word   _sa110_set_pmd                  @ 52
-               .word   _sa110_reset                    @ 56
-               .word   _sa110_flush_icache_area        @ 60
+               .word   _sa110_set_pte                  @ 56
+               .word   _sa110_reset                    @ 60
+               .word   _sa110_flush_icache_area        @ 64
 
-               .word   _sa110_cache_wback_area         @ 64
-               .word   _sa110_cache_purge_area         @ 68
+               .word   _sa110_cache_wback_area         @ 68
+               .word   _sa110_cache_purge_area         @ 72
index 2f8cad9a36ab1d78787a0046b443ece020da2de9..6bdc6cfc7cb599db6240815a8eba5ec67f873cda 100644 (file)
@@ -5,6 +5,8 @@
  *
  * Changelog:
  *  26/01/1996 RMK     Cleaned up various areas to make little more generic
+ *  07/02/1999 RMK     Support added for 16K and 32K page sizes
+ *                     containing 8K blocks
  */
 
 #include <linux/signal.h>
 #include <linux/swap.h>
 #include <linux/smp.h>
 
-#define SMALL_ALLOC_SHIFT      (10)
+#if PAGE_SIZE == 4096
+/* 2K blocks */
+#define SMALL_ALLOC_SHIFT      (11)
+#define NAME(x)                        x##_2k
+#elif PAGE_SIZE == 32768 || PAGE_SIZE == 16384
+/* 8K blocks */
+#define SMALL_ALLOC_SHIFT      (13)
+#define NAME(x)                        x##_8k
+#endif
+
 #define SMALL_ALLOC_SIZE       (1 << SMALL_ALLOC_SHIFT)
 #define NR_BLOCKS              (PAGE_SIZE / SMALL_ALLOC_SIZE)
+#define BLOCK_MASK             ((1 << NR_BLOCKS) - 1)
 
-#if NR_BLOCKS != 4
-#error I only support 4 blocks per page!
-#endif
-
-#define USED(pg)               ((atomic_read(&(pg)->count) >> 8) & 15)
+#define USED(pg)               ((atomic_read(&(pg)->count) >> 8) & BLOCK_MASK)
 #define SET_USED(pg,off)       (atomic_read(&(pg)->count) |= 256 << off)
 #define CLEAR_USED(pg,off)     (atomic_read(&(pg)->count) &= ~(256 << off))
+#define ALL_USED               BLOCK_MASK
 #define IS_FREE(pg,off)                (!(atomic_read(&(pg)->count) & (256 << off)))
-#define PAGE_PTR(page,block)   ((struct free_small_page *)((page) + \
+#define SM_PAGE_PTR(page,block)        ((struct free_small_page *)((page) + \
                                        ((block) << SMALL_ALLOC_SHIFT)))
 
+#if NR_BLOCKS != 2 && NR_BLOCKS != 4
+#error I only support 2 or 4 blocks per page
+#endif
+
 struct free_small_page {
        unsigned long next;
        unsigned long prev;
@@ -52,6 +65,7 @@ static unsigned char offsets[1<<NR_BLOCKS] = {
        1,      /* 0001 */
        0,      /* 0010 */
        2,      /* 0011 */
+#if NR_BLOCKS == 4
        0,      /* 0100 */
        1,      /* 0101 */
        0,      /* 0110 */
@@ -64,6 +78,7 @@ static unsigned char offsets[1<<NR_BLOCKS] = {
        1,      /* 1101 */
        0,      /* 1110 */
        4       /* 1111 */
+#endif
 };
 
 static inline void clear_page_links(unsigned long page)
@@ -72,7 +87,7 @@ static inline void clear_page_links(unsigned long page)
        int i;
 
        for (i = 0; i < NR_BLOCKS; i++) {
-               fsp = PAGE_PTR(page, i);
+               fsp = SM_PAGE_PTR(page, i);
                fsp->next = fsp->prev = 0;
        }
 }
@@ -90,7 +105,7 @@ static inline void set_page_links_prev(unsigned long page, unsigned long prev)
        for (i = 0; i < NR_BLOCKS; i++) {
                if (mask & (1 << i))
                        continue;
-               fsp = PAGE_PTR(page, i);
+               fsp = SM_PAGE_PTR(page, i);
                fsp->prev = prev;
        }
 }
@@ -108,12 +123,12 @@ static inline void set_page_links_next(unsigned long page, unsigned long next)
        for (i = 0; i < NR_BLOCKS; i++) {
                if (mask & (1 << i))
                        continue;
-               fsp = PAGE_PTR(page, i);
+               fsp = SM_PAGE_PTR(page, i);
                fsp->next = next;
        }
 }
 
-unsigned long get_small_page(int priority)
+unsigned long NAME(get_page)(int priority)
 {
        struct free_small_page *fsp;
        unsigned long new_page;
@@ -129,8 +144,8 @@ again:
        page = mem_map + MAP_NR(small_page_ptr);
        offset = offsets[USED(page)];
        SET_USED(page, offset);
-       new_page = (unsigned long)PAGE_PTR(small_page_ptr, offset);
-       if (USED(page) == 15) {
+       new_page = (unsigned long)SM_PAGE_PTR(small_page_ptr, offset);
+       if (USED(page) == ALL_USED) {
                fsp = (struct free_small_page *)new_page;
                set_page_links_prev (fsp->next, 0);
                small_page_ptr = fsp->next;
@@ -156,30 +171,31 @@ need_new_page:
        goto again;
 }
 
-void free_small_page(unsigned long spage)
+void NAME(free_page)(unsigned long spage)
 {
        struct free_small_page *ofsp, *cfsp;
        unsigned long flags;
        struct page *page;
        int offset, oldoffset;
 
+       if (!spage)
+               goto none;
+
        offset = (spage >> SMALL_ALLOC_SHIFT) & (NR_BLOCKS - 1);
        spage -= offset << SMALL_ALLOC_SHIFT;
 
        page = mem_map + MAP_NR(spage);
-       if (!PageReserved(page) || !USED(page)) {
-               printk ("Trying to free non-small page from %p\n", __builtin_return_address(0));
-               return;
-       }
-       if (IS_FREE(page, offset)) {
-               printk ("Trying to free free small page from %p\n", __builtin_return_address(0));
-               return;
-       }
+       if (!PageReserved(page) || !USED(page))
+               goto non_small;
+
+       if (IS_FREE(page, offset))
+               goto free;
+
        save_flags_cli (flags);
        oldoffset = offsets[USED(page)];
        CLEAR_USED(page, offset);
-       ofsp = PAGE_PTR(spage, oldoffset);
-       cfsp = PAGE_PTR(spage, offset);
+       ofsp = SM_PAGE_PTR(spage, oldoffset);
+       cfsp = SM_PAGE_PTR(spage, offset);
 
        if (oldoffset == NR_BLOCKS) { /* going from totally used to mostly used */
                cfsp->prev = 0;
@@ -197,4 +213,13 @@ void free_small_page(unsigned long spage)
        } else
                *cfsp = *ofsp;
        restore_flags(flags);
+       return;
+
+non_small:
+       printk ("Trying to free non-small page from %p\n", __builtin_return_address(0));
+       return;
+free:
+       printk ("Trying to free free small page from %p\n", __builtin_return_address(0));
+none:
+       return;
 }
index 0bc8caea9460c88e837b9fd225d1337c1be934dc..6ba091e0c4dc1a329aab4782e75467c11bfd4c50 100644 (file)
@@ -33,13 +33,15 @@ static struct tty_struct *get_tty(int fd)
 {
        struct file *filp;
 
-       if(fd >= NR_OPEN || !(filp = current->files->fd[fd]))
+       file = fcheck(fd);
+       if(!file)
                return ((struct tty_struct *) 0);
        if(filp->private_data) {
                struct tty_struct *ttyp = (struct tty_struct *) filp->private_data;
 
-               if(ttyp->magic == TTY_MAGIC)
+               if(ttyp->magic == TTY_MAGIC) {
                        return ttyp;
+               }
        }
        return ((struct tty_struct *) 0);
 }
index 8a652abba8460c8c8e00bff3e14535d8a1be6b32..9ad9a07d6e8d13d74db884431f208e24c128dcb5 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/utsname.h>
+#include <linux/file.h>
 
 #include <asm/ptrace.h>
 #include <asm/page.h>
@@ -734,6 +735,7 @@ asmlinkage int irix_statfs(const char *path, struct irix_statfs *buf,
        int error, i;
 
        /* We don't support this feature yet. */
+       lock_kernel();
        if(fs_type) {
                error = -EINVAL;
                goto out;
@@ -776,7 +778,6 @@ out:
 
 asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
 {
-       struct dentry *dentry;
        struct inode *inode;
        struct statfs kbuf;
        mm_segment_t old_fs;
@@ -787,25 +788,22 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
        error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statfs));
        if (error)
                goto out;
-       if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+       if (!(file = fget(fd))) {
                error = -EBADF;
                goto out;
        }
-       if (!(dentry = file->f_dentry)) {
+
+       if (!(inode = file->f_dentry->d_inode)) {
                error = -ENOENT;
-               goto out;
-       }
-       if (!(inode = dentry->d_inode)) {
-               error = -ENOENT;
-               goto out;
+               goto out_f;
        }
        if (!inode->i_sb) {
                error = -ENODEV;
-               goto out;
+               goto out_f;
        }
        if (!inode->i_sb->s_op->statfs) {
                error = -ENOSYS;
-               goto out;
+               goto out_f;
        }
 
        old_fs = get_fs(); set_fs(get_ds());
@@ -813,7 +811,7 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
                                          sizeof(struct statfs));
        set_fs(old_fs);
        if (error)
-               goto out;
+               goto out_f;
 
        __put_user(kbuf.f_type, &buf->f_type);
        __put_user(kbuf.f_bsize, &buf->f_bsize);
@@ -826,9 +824,9 @@ asmlinkage int irix_fstatfs(unsigned int fd, struct irix_statfs *buf)
                __put_user(0, &buf->f_fname[i]);
                __put_user(0, &buf->f_fpack[i]);
        }
-       error = 0;
 
-       dput(dentry);
+out_f:
+       fput(file);
 out:
        unlock_kernel();
        return error;
@@ -1110,7 +1108,7 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
 
        lock_kernel();
        if(!(flags & MAP_ANONYMOUS)) {
-               if(fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+               if(!(file = fget(fd))) {
                        retval = -EBADF;
                        goto out;
                }
@@ -1130,6 +1128,8 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
        retval = do_mmap(file, addr, len, prot, flags, offset);
+       if (file)
+               fput(file);
 
 out:
        unlock_kernel();
@@ -1568,7 +1568,6 @@ out:
 
 asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
 {
-       struct dentry *dentry;
        struct inode *inode;
        mm_segment_t old_fs;
        struct statfs kbuf;
@@ -1582,21 +1581,21 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
        error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
        if (error)
                goto out;
-       if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+       if (!(file = fget(fd))) {
                error = -EBADF;
                goto out;
        }
-       if (!(dentry = file->f_dentry)) {
+       if (!(inode = file->f_dentry->d_inode)) {
                error = -ENOENT;
-               goto out;
+               goto out_f;
        }
-       if (!(inode = dentry->d_inode)) {
-               error = -ENOENT;
-               goto out;
+       if (!inode->i_sb) {
+               error = -ENODEV;
+               goto out_f;
        }
        if (!inode->i_sb->s_op->statfs) {
                error = -ENOSYS;
-               goto out;
+               goto out_f;
        }
 
        old_fs = get_fs(); set_fs(get_ds());
@@ -1604,7 +1603,7 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
                                          sizeof(struct statfs));
        set_fs(old_fs);
        if (error)
-               goto out;
+               goto out_f;
 
        __put_user(kbuf.f_bsize, &buf->f_bsize);
        __put_user(kbuf.f_frsize, &buf->f_frsize);
@@ -1626,9 +1625,8 @@ asmlinkage int irix_fstatvfs(int fd, struct irix_statvfs *buf)
        for(i = 0; i < 32; i++)
                __put_user(0, &buf->f_fstr[i]);
 
-       error = 0;
-
-       dput(dentry);
+out_f:
+       fput(file);
 out:
        unlock_kernel();
        return error;
@@ -1726,7 +1724,7 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
        }
 
        if(!(flags & MAP_ANONYMOUS)) {
-               if(fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+               if(!(file = fcheck(fd))) {
                        error = -EBADF;
                        goto out;
                }
@@ -1812,6 +1810,7 @@ asmlinkage int irix_statvfs64(char *fname, struct irix_statvfs64 *buf)
        struct statfs kbuf;
        int error, i;
 
+       lock_kernel();
        printk("[%s:%ld] Wheee.. irix_statvfs(%s,%p)\n",
               current->comm, current->pid, fname, buf);
        error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
@@ -1864,7 +1863,6 @@ out:
 
 asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
 {
-       struct dentry *dentry;
        struct inode *inode;
        mm_segment_t old_fs;
        struct statfs kbuf;
@@ -1878,21 +1876,21 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
        error = verify_area(VERIFY_WRITE, buf, sizeof(struct irix_statvfs));
        if (error)
                goto out;
-       if (fd >= NR_OPEN || !(file = current->files->fd[fd])) {
+       if (!(file = fget(fd))) {
                error = -EBADF;
                goto out;
        }
-       if (!(dentry = file->f_dentry)) {
+       if (!(inode = file->f_dentry->d_inode)) {
                error = -ENOENT;
-               goto out;
+               goto out_f;
        }
-       if (!(inode = dentry->d_inode)) {
-               error = -ENOENT;
-               goto out;
+       if (!inode->i_sb) {
+               error = -ENODEV;
+               goto out_f;
        }
        if (!inode->i_sb->s_op->statfs) {
                error = -ENOSYS;
-               goto out;
+               goto out_f;
        }
 
        old_fs = get_fs(); set_fs(get_ds());
@@ -1900,7 +1898,7 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
                                          sizeof(struct statfs));
        set_fs(old_fs);
        if (error)
-               goto out;
+               goto out_f;
 
        __put_user(kbuf.f_bsize, &buf->f_bsize);
        __put_user(kbuf.f_frsize, &buf->f_frsize);
@@ -1921,10 +1919,8 @@ asmlinkage int irix_fstatvfs64(int fd, struct irix_statvfs *buf)
        __put_user(kbuf.f_namelen, &buf->f_namemax);
        for(i = 0; i < 32; i++)
                __put_user(0, &buf->f_fstr[i]);
-
-       error = 0;
-
-       dput(dentry);
+out_f:
+       fput(file);
 out:
        unlock_kernel();
        return error;
@@ -1994,7 +1990,6 @@ static int irix_filldir32(void *__buf, const char *name, int namlen, off_t offse
        unsigned short reclen = ROUND_UP32(NAME_OFFSET32(dirent) + namlen + 1);
        int retval;
 
-       lock_kernel();
 #ifdef DEBUG_GETDENTS
        printk("\nirix_filldir32[reclen<%d>namlen<%d>count<%d>]",
               reclen, namlen, buf->count);
@@ -2020,14 +2015,12 @@ static int irix_filldir32(void *__buf, const char *name, int namlen, off_t offse
        retval = 0;
 
 out:
-       unlock_kernel();
        return retval;
 }
 
 asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count, int *eob)
 {
        struct file *file;
-       struct dentry *dentry;
        struct inode *inode;
        struct irix_dirent32 *lastdirent;
        struct irix_dirent32_callback buf;
@@ -2039,46 +2032,56 @@ asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count
               current->pid, fd, dirent, count, eob);
 #endif
        error = -EBADF;
-       if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+       file = fget(fd);
+       if (!file)
                goto out;
 
-       dentry = file->f_dentry;
-       if (!dentry)
-               goto out;
+       inode = file->f_dentry->d_inode;
+       if (!inode)
+               goto out_putf;
 
        inode = dentry->d_inode;
        if (!inode)
-               goto out;
+               goto out_putf;
 
-       error = -ENOTDIR;
-       if (!file->f_op || !file->f_op->readdir)
-               goto out;
-
-       error = -EFAULT;
-       if(!access_ok(VERIFY_WRITE, dirent, count) ||
-          !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
-               goto out;
-
-       __put_user(0, eob);
        buf.current_dir = (struct irix_dirent32 *) dirent;
        buf.previous = NULL;
        buf.count = count;
        buf.error = 0;
 
+       error = -ENOTDIR;
+       if (!file->f_op || !file->f_op->readdir)
+               goto out_putf;
+
+       /*
+        * Get the inode's semaphore to prevent changes
+        * to the directory while we read it.
+        */
+       down(&inode->i_sem);
        error = file->f_op->readdir(file, &buf, irix_filldir32);
+       up(&inode->i_sem);
        if (error < 0)
-               goto out;
+               goto out_putf;
+       error = buf.error;
        lastdirent = buf.previous;
-       if (!lastdirent) {
-               error = buf.error;
-               goto out;
+       if (lastdirent) {
+               put_user(file->f_pos, &lastdirent->d_off);
+               error = count - buf.count;
        }
-       lastdirent->d_off = (u32) file->f_pos;
+
+       if (put_user(0, eob) < 0) {
+               error = EFAULT;
+               goto out_putf;
+       }
+
+
 #ifdef DEBUG_GETDENTS
        printk("eob=%d returning %d\n", *eob, count - buf.count);
 #endif
        error = count - buf.count;
 
+out_putf:
+       fput(file);
 out:
        unlock_kernel();
        return error;
@@ -2110,7 +2113,6 @@ static int irix_filldir64(void * __buf, const char * name, int namlen,
        unsigned short reclen = ROUND_UP64(NAME_OFFSET64(dirent) + namlen + 1);
        int retval;
 
-       lock_kernel();
        buf->error = -EINVAL;   /* only used if we fail.. */
        if (reclen > buf->count) {
                retval = -EINVAL;
@@ -2131,14 +2133,12 @@ static int irix_filldir64(void * __buf, const char * name, int namlen,
 
        retval = 0;
 out:
-       unlock_kernel();
        return retval;
 }
 
 asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
 {
        struct file *file;
-       struct dentry *dentry;
        struct inode *inode;
        struct irix_dirent64 *lastdirent;
        struct irix_dirent64_callback buf;
@@ -2150,40 +2150,38 @@ asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
               current->pid, fd, dirent, cnt);
 #endif
        error = -EBADF;
-       if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
-               goto out;
-
-       dentry = file->f_dentry;
-       if (!dentry)
+       if (!(file = fget(fd)))
                goto out;
 
-       inode = dentry->d_inode;
+       inode = file->f_dentry->d_inode;
        if (!inode)
-               goto out;
+               goto out_f;
 
        error = -ENOTDIR;
        if (!file->f_op || !file->f_op->readdir)
-               goto out;
+               goto out_f;
 
        error = -EFAULT;
        if(!access_ok(VERIFY_WRITE, dirent, cnt))
-               goto out;
+               goto out_f;
 
        error = -EINVAL;
        if(cnt < (sizeof(struct irix_dirent64) + 255))
-               goto out;
+               goto out_f;
 
        buf.curr = (struct irix_dirent64 *) dirent;
        buf.previous = NULL;
        buf.count = cnt;
        buf.error = 0;
+       down(&inode->i_sem);
        error = file->f_op->readdir(file, &buf, irix_filldir64);
+       up(&inode->i_sem);
        if (error < 0)
-               goto out;
+               goto out_f;
        lastdirent = buf.previous;
        if (!lastdirent) {
                error = buf.error;
-               goto out;
+               goto out_f;
        }
        lastdirent->d_off = (u64) file->f_pos;
 #ifdef DEBUG_GETDENTS
@@ -2191,6 +2189,8 @@ asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
 #endif
        error = cnt - buf.count;
 
+out_f:
+       fput(file);
 out:
        unlock_kernel();
        return error;
@@ -2199,7 +2199,6 @@ out:
 asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
 {
        struct file *file;
-       struct dentry *dentry;
        struct inode *inode;
        struct irix_dirent64 *lastdirent;
        struct irix_dirent64_callback buf;
@@ -2211,42 +2210,40 @@ asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
               current->pid, fd, dirent, cnt);
 #endif
        error = -EBADF;
-       if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
-               goto out;
-
-       dentry = file->f_dentry;
-       if (!dentry)
+       if (!(file = fget(fd)))
                goto out;
 
-       inode = dentry->d_inode;
+       inode = file->f_dentry->d_inode;
        if (!inode)
-               goto out;
+               goto out_f;
 
        error = -ENOTDIR;
        if (!file->f_op || !file->f_op->readdir)
-               goto out;
+               goto out_f;
 
        error = -EFAULT;
        if(!access_ok(VERIFY_WRITE, dirent, cnt) ||
           !access_ok(VERIFY_WRITE, eob, sizeof(*eob)))
-               goto out;
+               goto out_f;
 
        error = -EINVAL;
        if(cnt < (sizeof(struct irix_dirent64) + 255))
-               goto out;
+               goto out_f;
 
        *eob = 0;
        buf.curr = (struct irix_dirent64 *) dirent;
        buf.previous = NULL;
        buf.count = cnt;
        buf.error = 0;
+       down(&inode->i_sem);
        error = file->f_op->readdir(file, &buf, irix_filldir64);
+       up(&inode->i_sem);
        if (error < 0)
-               goto out;
+               goto out_f;
        lastdirent = buf.previous;
        if (!lastdirent) {
                error = buf.error;
-               goto out;
+               goto out_f;
        }
        lastdirent->d_off = (u64) file->f_pos;
 #ifdef DEBUG_GETDENTS
@@ -2254,6 +2251,8 @@ asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
 #endif
        error = cnt - buf.count;
 
+out_f:
+       fput(file);
 out:
        unlock_kernel();
        return error;
index b974562260a4b4dce19b7d2c811f0a901a89d915..4d96a6f0af8748e0db7698dc74f06181a979f158 100644 (file)
@@ -205,12 +205,15 @@ asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
 
        lock_kernel();
        if (!(flags & MAP_ANONYMOUS)) {
-               if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
+               file = fget(fd);
+               if (!file)
                        goto out;
        }
        
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
        ret = do_mmap(file, addr, len, prot, flags, offset);
+       if (file)
+               fput(file);
 out:
        unlock_kernel();
        return ret;
index 0ce0e89f90990c4897b45987c2add20f36baad34..f0edae26161f4fd1a636e011588928b526c026f6 100644 (file)
     to  determine this in  advance other than by  trial and error and common
     sense, e.g. call a BNC connectored port 'BNC', not '10Mb'.
 
-    TO DO:
+    Changed the bus probing.  EISA used to be  done first,  followed by PCI.
+    Most people probably don't even know  what a de425 is today and the EISA
+    probe has messed  up some SCSI cards  in the past,  so now PCI is always
+    probed  first  followed by  EISA if  a) the architecture allows EISA and
+    either  b) there have been no PCI cards detected or  c) an EISA probe is
+    forced by  the user.  To force  a probe  include  "force_eisa"  in  your
+    insmod "args" line;  for built-in kernels either change the driver to do
+    this  automatically  or include  #define DE4X5_FORCE_EISA  on or  before
+    line 1040 in the driver.
+
+    TO DO: 
     ------
 
-    o check what revision numbers the 21142 and 21143 have
-    o
-
     Revision History
     ----------------
 
                           access traps. This flag is merely for log messages:
                           should do something more definitive though...
       0.543  30-Dec-98    Add SMP spin locking.
-
+      0.544   8-May-99    Fix for buggy SROM in Motorola embedded boards using
+                           a 21143 by <mmporter@home.com>.
+                         Change PCI/EISA bus probing order.
     =========================================================================
 */
 
-static const char *version = "de4x5.c:V0.543 1998/12/30 davies@maniac.ultranet.com\n";
+static const char *version = "de4x5.c:V0.544 1999/5/8 davies@maniac.ultranet.com\n";
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -1027,8 +1037,11 @@ static char name[DE4X5_NAME_LENGTH + 1];
 #if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
 static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST;
 static int lastEISA = 0;
-#else
-static int lastEISA = MAX_EISA_SLOTS;           /* Only PCI probes */
+#  ifdef DE4X5_FORCE_EISA                 /* Force an EISA bus probe or not */
+static int forceEISA = 1;
+#  else
+static int forceEISA = 0;
+#  endif
 #endif
 static int num_de4x5s = 0;
 static int cfrv = 0, useSROM = 0;
@@ -1098,12 +1111,12 @@ de4x5_probe(struct device *dev))
 {
     u_long iobase = dev->base_addr;
 
+    pci_probe(dev, iobase);
 #if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
-    eisa_probe(dev, iobase);
-#endif
-    if (lastEISA == MAX_EISA_SLOTS) {
-       pci_probe(dev, iobase);
+    if ((lastPCI == NO_MORE_PCI) && ((num_de4x5s == 0) || forceEISA)) {
+        eisa_probe(dev, iobase);
     }
+#endif
     
     return (dev->priv ? 0 : -ENODEV);
 }
@@ -1230,6 +1243,7 @@ de4x5_hw_init(struct device *dev, u_long iobase))
        if ((tmp = (void *)kmalloc(RX_BUFF_SZ * NUM_RX_DESC + ALIGN, 
                                   GFP_KERNEL)) == NULL) {
            kfree(lp->cache.priv);
+           lp->cache.priv = NULL;
            return -ENOMEM;
        }
 
@@ -2066,38 +2080,36 @@ eisa_probe(struct device *dev, u_long ioaddr))
     }
     
     for (status = -ENODEV; (i<maxSlots) && (dev!=NULL); i++, iobase+=EISA_SLOT_INC) {
-       if (EISA_signature(name, EISA_ID)) {
-           cfid = (u32) inl(PCI_CFID);
-           cfrv = (u_short) inl(PCI_CFRV);
-           device = (cfid >> 8) & 0x00ffff00;
-           vendor = (u_short) cfid;
+       if (check_region(iobase, DE4X5_EISA_TOTAL_SIZE)) continue;
+       if (!EISA_signature(name, EISA_ID)) continue;
+
+       cfid = (u32) inl(PCI_CFID);
+       cfrv = (u_short) inl(PCI_CFRV);
+       device = (cfid >> 8) & 0x00ffff00;
+       vendor = (u_short) cfid;
            
-           /* Read the EISA Configuration Registers */
-           irq = inb(EISA_REG0);
-           irq = de4x5_irq[(irq >> 1) & 0x03];
+       /* Read the EISA Configuration Registers */
+       irq = inb(EISA_REG0);
+       irq = de4x5_irq[(irq >> 1) & 0x03];
 
-           if (is_DC2114x) {
-               device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
-           }
-           lp->chipset = device;
+       if (is_DC2114x) {
+           device = ((cfrv & CFRV_RN) < DC2114x_BRK ? DC21142 : DC21143);
+       }
+       lp->chipset = device;
 
-           /* Write the PCI Configuration Registers */
-           outl(PCI_COMMAND_IO | PCI_COMMAND_MASTER, PCI_CFCS);
-           outl(0x00006000, PCI_CFLT);
-           outl(iobase, PCI_CBIO);
+       /* Write the PCI Configuration Registers */
+       outl(PCI_COMMAND_IO | PCI_COMMAND_MASTER, PCI_CFCS);
+       outl(0x00006000, PCI_CFLT);
+       outl(iobase, PCI_CBIO);
            
-           DevicePresent(EISA_APROM);
-           if (check_region(iobase, DE4X5_EISA_TOTAL_SIZE) == 0) {
-               dev->irq = irq;
-               if ((status = de4x5_hw_init(dev, iobase)) == 0) {
-                   num_de4x5s++;
-                   if (loading_module) link_modules(lastModule, dev);
-                   lastEISA = i;
-                   return;
-               }
-           } else if (ioaddr != 0) {
-               printk("%s: region already allocated at 0x%04lx.\n", dev->name,iobase);
-           }
+       DevicePresent(EISA_APROM);
+
+       dev->irq = irq;
+       if ((status = de4x5_hw_init(dev, iobase)) == 0) {
+           num_de4x5s++;
+           if (loading_module) link_modules(lastModule, dev);
+           lastEISA = i;
+           return;
        }
     }
 
@@ -4794,6 +4806,7 @@ type3_infoblock(struct device *dev, u_char count, u_char *p)
     if (lp->state == INITIALISED) {
         lp->ibn = 3;
         lp->active = *p++;
+       if (MOTO_SROM_BUG) lp->active = 0;
        lp->phy[lp->active].gep = (*p ? p : 0); p += (2 * (*p) + 1);
        lp->phy[lp->active].rst = (*p ? p : 0); p += (2 * (*p) + 1);
        lp->phy[lp->active].mc  = TWIDDLE(p); p += 2;
@@ -5326,6 +5339,9 @@ de4x5_parse_params(struct device *dev)
        t = *q;
        *q = '\0';
 
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
+       if (strstr(p, "force_eisa") || strstr(p, "FORCE_EISA")) forceEISA = 1;
+#endif
        if (strstr(p, "fdx") || strstr(p, "FDX")) lp->params.fdx = 1;
 
        if (strstr(p, "autosense") || strstr(p, "AUTOSENSE")) {
@@ -5766,6 +5782,12 @@ init_module(void)
                release_region(p->base_addr, (lp->bus == PCI ? 
                                              DE4X5_PCI_TOTAL_SIZE :
                                              DE4X5_EISA_TOTAL_SIZE));
+               if (lp->cache.buf) {        /* MAC buffers allocated?    */
+                   kfree(lp->cache.buf);   /* Free the MAC buffers      */
+               }
+               if (lp->cache.priv) {       /* Private area allocated?   */
+                   kfree(lp->cache.priv);  /* Free the private area     */
+               }
            }
            kfree(p);
        } else {
@@ -5799,10 +5821,10 @@ unlink_modules(struct device *p)
        if (lp->cache.buf) {                /* MAC buffers allocated?    */
            kfree(lp->cache.buf);           /* Free the MAC buffers      */
        }
-       kfree(lp->cache.priv);              /* Free the private area     */
        release_region(p->base_addr, (lp->bus == PCI ? 
                                      DE4X5_PCI_TOTAL_SIZE :
                                      DE4X5_EISA_TOTAL_SIZE));
+       kfree(lp->cache.priv);              /* Free the private area     */
     }
     unregister_netdev(p);
     kfree(p);                               /* Free the device structure */
@@ -5867,6 +5889,9 @@ insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)))
  * Local variables:
  *  compile-command: "gcc -D__KERNEL__ -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c de4x5.c"
  *
- *  compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c de4x5.c"
+ * Delete -D__SMP__ below if you didn't define this in your kernel
+ * Delete -DMODVERSIONS below if you didn't define this in your kernel
+ *
+ *  compile-command: "gcc -D__KERNEL__ -DMODULE -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -DMODVERSIONS -include /linux/include/linux/modversions.h -c de4x5.c"
  * End:
  */
index 6e5aeae0fd0eea248f5f0b65bf308e28e1fe5973..9cffbb0b98d4e4697691839b0fe0dec860e8f1a4 100644 (file)
@@ -1027,3 +1027,5 @@ struct de4x5_ioctl {
 #define DE4X5_GET_REG           0x0e /* Get the DE4X5 Registers */
 
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+
+#define MOTO_SROM_BUG    ((lp->active == 8) && ((*((s32 *)le32_to_cpu(get_unaligned(dev->dev_addr)))&0x00ffffff)==0x3e0008))
index c860f13ebce21373b7b924ace6859ff84977af31..c0caee9df5653e406ef9f7a2ae53bbfc276d8158 100644 (file)
@@ -168,7 +168,7 @@ static int try_to_fill_dentry(struct dentry *dentry, struct super_block *sb, str
  * yet completely filled in, and revalidate has to delay such
  * lookups..
  */
-static int autofs_revalidate(struct dentry * dentry)
+static int autofs_revalidate(struct dentry * dentry, int flags)
 {
        struct inode * dir = dentry->d_parent->d_inode;
        struct autofs_sb_info *sbi = autofs_sbi(dir->i_sb);
@@ -241,7 +241,7 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr
        d_add(dentry, NULL);
 
        up(&dir->i_sem);
-       autofs_revalidate(dentry);
+       autofs_revalidate(dentry, 0);
        down(&dir->i_sem);
 
        /*
index 136c817be85f3acd6588bcccc203b3565f16ebcd..b3c0195a3bea43e58182926a7b0743ecb5c4c504 100644 (file)
@@ -44,7 +44,7 @@ static int coda_rename(struct inode *old_inode, struct dentry *old_dentry,
 static int coda_readdir(struct file *file, void *dirent, filldir_t filldir);
 
 /* dentry ops */
-static int coda_dentry_revalidate(struct dentry *de);
+static int coda_dentry_revalidate(struct dentry *de, int);
 static void coda_dentry_delete(struct dentry *);
 
 /* support routines */
@@ -778,7 +778,7 @@ exit:
 }
 
 /* called when a cache lookup succeeds */
-static int coda_dentry_revalidate(struct dentry *de)
+static int coda_dentry_revalidate(struct dentry *de, int flags)
 {
        int valid = 1;
        struct inode *inode = de->d_inode;
index 84388c763722b69dd1e5e6ca74049d9fe221d22a..c284f1d97bfbdd097d68cb08dfd120bd8f7b0089 100644 (file)
@@ -18,7 +18,7 @@
 
 static int devpts_root_readdir(struct file *,void *,filldir_t);
 static struct dentry *devpts_root_lookup(struct inode *,struct dentry *);
-static int devpts_revalidate(struct dentry *);
+static int devpts_revalidate(struct dentry *, int);
 
 static struct file_operations devpts_root_operations = {
        NULL,                   /* llseek */
@@ -116,7 +116,7 @@ static int devpts_root_readdir(struct file *filp, void *dirent, filldir_t filldi
  * the pty really does still exist.  Never revalidate negative dentries;
  * for simplicity (fix later?)
  */
-static int devpts_revalidate(struct dentry * dentry)
+static int devpts_revalidate(struct dentry * dentry, int flags)
 {
        struct devpts_sb_info *sbi;
 
index b2797d1a8286375b1d4dbde7f486f8a6e0cd18f4..76630352f2a6d9c0c6a108036d88458646cadfa1 100644 (file)
@@ -1349,8 +1349,8 @@ asmlinkage int sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
                case Q_GETSTATS:
                        break;
                case Q_GETQUOTA:
-                       if (((type == USRQUOTA && current->uid != id) ||
-                            (type == GRPQUOTA && current->gid != id)) &&
+                       if (((type == USRQUOTA && current->euid != id) ||
+                            (type == GRPQUOTA && current->egid != id)) &&
                            !capable(CAP_SYS_RESOURCE))
                                goto out;
                        break;
index 0524808f7af86a2e6280d18cbb2fbc96199604d5..fb68e9ab21e658b80ae05702218ab31b9670236b 100644 (file)
@@ -18,7 +18,7 @@
 #include <linux/hfs_fs_i.h>
 #include <linux/hfs_fs.h>
 
-static int hfs_revalidate_dentry(struct dentry *);
+static int hfs_revalidate_dentry(struct dentry *, int);
 static int hfs_hash_dentry(struct dentry *, struct qstr *);
 static int hfs_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
 static void hfs_dentry_iput(struct dentry *, struct inode *);
@@ -89,7 +89,7 @@ static void hfs_dentry_iput(struct dentry *dentry, struct inode *inode)
        iput(inode);
 }
 
-static int hfs_revalidate_dentry(struct dentry *dentry)
+static int hfs_revalidate_dentry(struct dentry *dentry, int flags)
 {
        struct inode *inode = dentry->d_inode;
        int diff;
index 512fc9be5c0868386afb3213597b1fff42842c5c..b91b43a1f774689bcf53e76b1b2a8b7df67db8f3 100644 (file)
 #include <asm/page.h>
 #include <asm/pgtable.h>
 
-/*
- * The bitmask for a lookup event:
- *  - follow links at the end
- *  - require a directory
- *  - ending slashes ok even for nonexistent files
- *  - internal "there are more path compnents" flag
- */
-#define LOOKUP_FOLLOW          (1)
-#define LOOKUP_DIRECTORY       (2)
-#define LOOKUP_SLASHOK         (4)
-#define LOOKUP_CONTINUE                (8)
-
 #include <asm/namei.h>
 
 /* This can be removed after the beta phase. */
@@ -225,12 +213,12 @@ static struct dentry * reserved_lookup(struct dentry * parent, struct qstr * nam
 /*
  * Internal lookup() using the new generic dcache.
  */
-static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name)
+static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags)
 {
        struct dentry * dentry = d_lookup(parent, name);
 
        if (dentry && dentry->d_op && dentry->d_op->d_revalidate) {
-               if (!dentry->d_op->d_revalidate(dentry) && !d_invalidate(dentry)) {
+               if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) {
                        dput(dentry);
                        dentry = NULL;
                }
@@ -245,7 +233,7 @@ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name)
  * We get the directory semaphore, and after getting that we also
  * make sure that nobody added the entry to the dcache in the meantime..
  */
-static struct dentry * real_lookup(struct dentry * parent, struct qstr * name)
+static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags)
 {
        struct dentry * result;
        struct inode *dir = parent->d_inode;
@@ -258,7 +246,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name)
         * FIXME! This could use version numbering or similar to
         * avoid unnecessary cache lookups.
         */
-       result = cached_lookup(parent, name);
+       result = cached_lookup(parent, name, flags);
        if (!result) {
                struct dentry * dentry = d_alloc(parent, name);
                result = ERR_PTR(-ENOMEM);
@@ -392,9 +380,9 @@ struct dentry * lookup_dentry(const char * name, struct dentry * base, unsigned
                /* This does the actual lookups.. */
                dentry = reserved_lookup(base, &this);
                if (!dentry) {
-                       dentry = cached_lookup(base, &this);
+                       dentry = cached_lookup(base, &this, flags);
                        if (!dentry) {
-                               dentry = real_lookup(base, &this);
+                               dentry = real_lookup(base, &this, flags);
                                if (IS_ERR(dentry))
                                        break;
                        }
index 5648f6725553e9e0f2b5e1c08d5bd433ee982c27..cacc0d5c5bb2c82acb1edbd110e098b0c2acb5b7 100644 (file)
@@ -112,14 +112,14 @@ ncp_dir_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
 /*
  * Dentry operations routines
  */
-static int ncp_lookup_validate(struct dentry *);
+static int ncp_lookup_validate(struct dentry *, int);
 static int ncp_hash_dentry(struct dentry *, struct qstr *);
 static int ncp_compare_dentry (struct dentry *, struct qstr *, struct qstr *);
 static void ncp_delete_dentry(struct dentry *);
 
 struct dentry_operations ncp_dentry_operations =
 {
-       ncp_lookup_validate,    /* d_validate(struct dentry *) */
+       ncp_lookup_validate,    /* d_revalidate(struct dentry *, int) */
        ncp_hash_dentry,        /* d_hash */
        ncp_compare_dentry,     /* d_compare */
        ncp_delete_dentry       /* d_delete(struct dentry *) */
@@ -345,7 +345,7 @@ leave_me:;
 
 
 static int
-ncp_lookup_validate(struct dentry * dentry)
+ncp_lookup_validate(struct dentry * dentry, int flags)
 {
        struct ncp_server *server;
        struct inode *dir = dentry->d_parent->d_inode;
index df84e618c6f368e8f57a2c82ae27c1697ece6d63..36931e02a0da2520bcf667af2d9f4dc5535b0d04 100644 (file)
@@ -72,9 +72,9 @@ static struct file_operations nfs_dir_operations = {
        NULL,                   /* select - default */
        NULL,                   /* ioctl - default */
        NULL,                   /* mmap */
-       nfs_open,               /* open - revalidate the inode */
+       nfs_open,               /* open */
        NULL,                   /* flush */
-       NULL,                   /* no special release code */
+       nfs_release,            /* release */
        NULL                    /* fsync */
 };
 
@@ -364,7 +364,43 @@ static inline void nfs_renew_times(struct dentry * dentry)
        dentry->d_time = jiffies;
 }
 
-#define NFS_REVALIDATE_INTERVAL (5*HZ)
+static inline int nfs_dentry_force_reval(struct dentry *dentry, int flags)
+{
+       struct inode *inode = dentry->d_inode;
+       unsigned long timeout = NFS_ATTRTIMEO(inode);
+
+       /*
+        * If it's the last lookup in a series, we use a stricter
+        * cache consistency check!
+        */
+       if (!(flags & LOOKUP_CONTINUE))
+               timeout = 0;
+       
+       return time_after(jiffies,dentry->d_time + timeout);
+}
+
+/*
+ * We judge how long we want to trust negative
+ * dentries by looking at the parent inode mtime.
+ *
+ * If mtime is close to present time, we revalidate
+ * more often.
+ */
+static inline int nfs_neg_need_reval(struct dentry *dentry)
+{
+       unsigned long timeout = 30 * HZ;
+       struct inode *dir = dentry->d_parent->d_inode;
+
+       if (dir) {
+               /* Modified in the last two minutes? */
+               long diff = CURRENT_TIME - dir->i_mtime;
+               if (diff < 2*60)
+                       timeout = 1 * HZ;
+       }
+
+       return time_after(jiffies, dentry->d_time + timeout);
+}
+
 /*
  * This is called every time the dcache has a lookup hit,
  * and we should check whether we can really trust that
@@ -377,7 +413,7 @@ static inline void nfs_renew_times(struct dentry * dentry)
  * we do a new lookup and verify that the dentry is still
  * correct.
  */
-static int nfs_lookup_revalidate(struct dentry * dentry)
+static int nfs_lookup_revalidate(struct dentry * dentry, int flags)
 {
        struct dentry * parent = dentry->d_parent;
        struct inode * inode = dentry->d_inode;
@@ -386,11 +422,12 @@ static int nfs_lookup_revalidate(struct dentry * dentry)
        struct nfs_fattr fattr;
 
        /*
-        * If we don't have an inode, let's just assume
-        * a 5-second "live" time for negative dentries.
+        * If we don't have an inode, let's look at the parent
+        * directory mtime to get a hint about how often we
+        * should validate things..
         */
        if (!inode) {
-               if (time_after(jiffies, dentry->d_time + NFS_REVALIDATE_INTERVAL))
+               if (nfs_neg_need_reval(dentry))
                        goto out_bad;
                goto out_valid;
        }
@@ -401,16 +438,16 @@ static int nfs_lookup_revalidate(struct dentry * dentry)
                goto out_bad;
        }
 
-       if (time_before(jiffies,dentry->d_time+NFS_ATTRTIMEO(inode)))
+       if (IS_ROOT(dentry))
                goto out_valid;
 
-       if (IS_ROOT(dentry))
+       if (!nfs_dentry_force_reval(dentry, flags))
                goto out_valid;
 
        /*
         * Do a new lookup and check the dentry attributes.
         */
-       error = nfs_proc_lookup(NFS_DSERVER(parent), NFS_FH(parent), 
+       error = nfs_proc_lookup(NFS_DSERVER(parent), NFS_FH(parent),
                                dentry->d_name.name, &fhandle, &fattr);
        if (error)
                goto out_bad;
@@ -489,7 +526,7 @@ static void nfs_dentry_release(struct dentry *dentry)
 }
 
 struct dentry_operations nfs_dentry_operations = {
-       nfs_lookup_revalidate,  /* d_validate(struct dentry *) */
+       nfs_lookup_revalidate,  /* d_revalidate(struct dentry *, int) */
        NULL,                   /* d_hash */
        NULL,                   /* d_compare */
        nfs_dentry_delete,      /* d_delete(struct dentry *) */
index 8a7d1571a55cdb31f3e8c02ef632173216f06994..1cf40d3ae3f3c73a05b9a401205bb951b534a125 100644 (file)
@@ -46,9 +46,9 @@ static struct file_operations nfs_file_operations = {
        NULL,                   /* select - default */
        NULL,                   /* ioctl - default */
        nfs_file_mmap,          /* mmap */
-       nfs_open,               /* open - revalidate the inode */
+       nfs_open,               /* open */
        nfs_file_flush,         /* flush */
-       NULL,                   /* release */
+       nfs_release,            /* release */
        nfs_fsync,              /* fsync */
        NULL,                   /* fasync */
        NULL,                   /* check_media_change */
index 6617893921a709cba23fc1ebefd35e7e27348262..c46eeb57bb505cf4c4a2da639dca5fa4852ca3d7 100644 (file)
@@ -696,25 +696,19 @@ nfs_revalidate(struct dentry *dentry)
 }
 
 /*
- * Revalidate the file on open (this
- * is separate from the path-revalidation
- * that we do on any lookup).
- *
- * When we actually open a file, we want
- * fairly strict consistency: make sure that
- * we've updated the attributes within the
- * last second or so..
+ * These are probably going to contain hooks for
+ * allocating and releasing RPC credentials for
+ * the file. I'll have to think about Tronds patch
+ * a bit more..
  */
 int nfs_open(struct inode *inode, struct file *filp)
 {
-       int retval = 0;
+       return 0;
+}
 
-       if (time_after(jiffies, NFS_READTIME(inode) + HZ/2)) {
-               struct dentry *dentry = filp->f_dentry;
-               struct nfs_server *server = NFS_DSERVER(dentry);
-               retval = _nfs_revalidate_inode(server, dentry);
-       }
-       return retval;
+int nfs_release(struct inode *inode, struct file *filp)
+{
+       return 0;
 }
 
 /*
index b6d0364fc6caeef4d7baa4e394e468cdc8933850..4f942db800415f00369968206ba081257a4c0dbc 100644 (file)
@@ -191,14 +191,14 @@ file->f_dentry->d_name.name);
 /*
  * Dentry operations routines
  */
-static int smb_lookup_validate(struct dentry *);
+static int smb_lookup_validate(struct dentry *, int);
 static int smb_hash_dentry(struct dentry *, struct qstr *);
 static int smb_compare_dentry(struct dentry *, struct qstr *, struct qstr *);
 static void smb_delete_dentry(struct dentry *);
 
 static struct dentry_operations smbfs_dentry_operations =
 {
-       smb_lookup_validate,    /* d_validate(struct dentry *) */
+       smb_lookup_validate,    /* d_revalidate(struct dentry *) */
        smb_hash_dentry,        /* d_hash */
        smb_compare_dentry,     /* d_compare */
        smb_delete_dentry       /* d_delete(struct dentry *) */
@@ -208,7 +208,7 @@ static struct dentry_operations smbfs_dentry_operations =
  * This is the callback when the dcache has a lookup hit.
  */
 static int
-smb_lookup_validate(struct dentry * dentry)
+smb_lookup_validate(struct dentry * dentry, int flags)
 {
        struct inode * inode = dentry->d_inode;
        unsigned long age = jiffies - dentry->d_time;
index 07a12a6a4b5c6036680f6a2a8079d7268fd01b50..799f685de5236d186c9e3d1233c5d72779c8cace 100644 (file)
@@ -30,7 +30,7 @@ extern struct inode *pseudo_root;
  */
 
 /* nothing for now ... */
-static int umsdos_dentry_validate(struct dentry *dentry)
+static int umsdos_dentry_validate(struct dentry *dentry, int flags)
 {
        return 1;
 }
@@ -46,7 +46,7 @@ static void umsdos_dentry_dput(struct dentry *dentry)
 
 struct dentry_operations umsdos_dentry_operations =
 {
-       umsdos_dentry_validate, /* d_validate(struct dentry *) */
+       umsdos_dentry_validate, /* d_revalidate(struct dentry *, int) */
        NULL,                   /* d_hash */
        NULL,                   /* d_compare */
        umsdos_dentry_dput,     /* d_delete(struct dentry *) */
index 25a11251b95f7831b149536d0ec9e219bb9a5ec9..f79ef1b4499c224e02e810cdcec3029ceb825abe 100644 (file)
@@ -71,7 +71,7 @@ static int vfat_hashi(struct dentry *parent, struct qstr *qstr);
 static int vfat_hash(struct dentry *parent, struct qstr *qstr);
 static int vfat_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
 static int vfat_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b);
-static int vfat_revalidate(struct dentry *dentry);
+static int vfat_revalidate(struct dentry *dentry, int);
 
 static struct dentry_operations vfat_dentry_ops[4] = {
        {
@@ -106,7 +106,7 @@ void vfat_put_super(struct super_block *sb)
        MOD_DEC_USE_COUNT;
 }
 
-static int vfat_revalidate(struct dentry *dentry)
+static int vfat_revalidate(struct dentry *dentry, int flags)
 {
        PRINTK1(("vfat_revalidate: %s\n", dentry->d_name.name));
        if (dentry->d_time == dentry->d_parent->d_inode->i_version) {
index 489d76eb52344e9ea3b693fd64ac2e1b60ec356f..ae967b0a6ae518d74a59da5b4f87d0d241ea8bd0 100644 (file)
@@ -26,7 +26,9 @@ struct exec
 
 #define M_ARM 103
 
+#ifdef __KERNEL__
 #include <asm/arch/a.out.h>
+#endif
 
 #ifndef LIBRARY_START_TEXT
 #define LIBRARY_START_TEXT     (0x00c00000)
index e00511463b2e4329f92efc2de5d14fe170cf8e65..0c13102d04cfa5e87ceb86e44034a51795cd7157 100644 (file)
@@ -1,16 +1,14 @@
 /*
  * linux/include/asm-arm/arch-arc/a.out.h
  *
- * Copyright (C) 1996 Russell King
- *
- * Acorn Archimedes/A5000 a.out.h specs
+ * Copyright (C) 1996-1999 Russell King
  */
 #ifndef __ASM_ARCH_A_OUT_H
 #define __ASM_ARCH_A_OUT_H
 
-#ifdef __KERNEL__
-#define STACK_TOP              (0x01a00000)
-#endif
+#include <asm/arch/memory.h>
+
+#define STACK_TOP      TASK_SIZE
 
 #endif
 
index c59007f3cabbc8694b5886c26cf1479f4db615dc..33b4659f8bde9e2f1e34f36261412ee14e61aebc 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * linux/include/asm-arm/arch-arc/hardware.h
  *
- * Copyright (C) 1996 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
  *
  * This file contains the hardware definitions of the
  * Acorn Archimedes/A5000 machines.
@@ -9,21 +9,20 @@
  * Modifications:
  *  04-04-1998 PJB/RMK Merged arc and a5k versions
  */
-
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
 #include <linux/config.h>
 
+#include <asm/arch/memory.h>
+
 /*
  * What hardware must be present - these can be tested by the kernel
  * source.
  */
 #define HAS_IOC
-#include <asm/ioc.h>
 #define HAS_MEMC
 #include <asm/memc.h>
-#define HAS_MEMC1A
 #define HAS_VIDC
 
 /*
  * for use with inb/outb
  */
 #define IO_VIDC_BASE           0x80100000
+#ifdef CONFIG_ARCH_A5K
+#define IOEB_VID_CTL           0x800d4012
+#define IOEB_PRESENT           0x800d4014
+#define IOEB_PSCLR             0x800d4016
+#define IOEB_MONTYPE           0x800d401c
+#endif
 #ifdef CONFIG_ARCH_ARC
 #define LATCHAADDR             0x80094010
 #define LATCHBADDR             0x80094006
 #define IO_EC_IOC_BASE         0x80090000
 #define IO_EC_MEMC_BASE                0x80000000
 
+#ifdef CONFIG_ARCH_ARC
+/* A680 hardware */
+#define WD1973_BASE            0x03290000
+#define WD1973_LATCH           0x03350000
+#define Z8530_BASE             0x032b0008
+#define SCSI_BASE              0x03100000
+#endif
+
 /*
  * IO definitions
  */
 /*
  * RAM definitions
  */
-#define MAPTOPHYS(a)           (((unsigned long)a & 0x007fffff) + PAGE_OFFSET)
-#define KERNTOPHYS(a)          ((((unsigned long)(&a)) & 0x007fffff) + PAGE_OFFSET)
 #define GET_MEMORY_END(p)      (PAGE_OFFSET + (p->u1.s.page_size) * (p->u1.s.nr_pages))
 #define PARAMS_BASE            (PAGE_OFFSET + 0x7c000)
-#define KERNEL_BASE            (PAGE_OFFSET + 0x80000)
 
 #else
 
index 0faabaf4ddc7765f384a88d7317cd4f2b09b27a7..97d3722bd52190c714a2c877bdc368daa9bae408 100644 (file)
@@ -10,6 +10,9 @@
  *   11-01-1998        RMK     Added mask_and_ack_irq
  *   22-08-1998        RMK     Restructured IRQ routines
  */
+#include <asm/ioc.h>
+
+#define fixup_irq(x) (x)
 
 static void arc_mask_irq_ack_a(unsigned int irq)
 {
@@ -108,10 +111,17 @@ static __inline__ void irq_init_irq(void)
        outb(0, IOC_FIQMASK);
 
        for (irq = 0; irq < NR_IRQS; irq++) {
-               switch (irq & 0xf8) {
+               switch (irq) {
                case 0 ... 6:
                        irq_desc[irq].probe_ok = 1;
+                       irq_desc[irq].valid    = 1;
+                       irq_desc[irq].mask_ack = arc_mask_irq_ack_a;
+                       irq_desc[irq].mask     = arc_mask_irq_a;
+                       irq_desc[irq].unmask   = arc_unmask_irq_a;
+                       break;
+
                case 7:
+                       irq_desc[irq].noautoenable = 1;
                        irq_desc[irq].valid    = 1;
                        irq_desc[irq].mask_ack = arc_mask_irq_ack_a;
                        irq_desc[irq].mask     = arc_mask_irq_a;
index 4962defb5a2bcb4aff83035efaab6815266eae04..1f57b97570412fa5c0af07bd2aef722786b74f75 100644 (file)
@@ -11,7 +11,6 @@
 
 #define NR_SCANCODES 128
 
-extern int a5kkbd_translate(unsigned char scancode, unsigned char *keycode_p, char *up_flag_p);
 extern void a5kkbd_leds(unsigned char leds);
 extern void a5kkbd_init_hw(void);
 extern unsigned char a5kkbd_sysrq_xlate[NR_SCANCODES];
@@ -19,11 +18,7 @@ extern unsigned char a5kkbd_sysrq_xlate[NR_SCANCODES];
 #define kbd_setkeycode(sc,kc)          (-EINVAL)
 #define kbd_getkeycode(sc)             (-EINVAL)
 
-/* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode)
- * Returns  : 0 to ignore scancode, *keycode set to keycode, *up_flag
- *            set to 0200 if scancode indicates release
- */
-#define kbd_translate(sc, kcp, ufp, rm)        a5kkbd_translate(sc, kcp, ufp)
+#define kbd_translate(sc, kcp, rm)     ({ *(kcp) = (sc); 1; })
 #define kbd_unexpected_up(kc)          (0200)
 #define kbd_leds(leds)                 a5kkbd_leds(leds)
 #define kbd_init_hw()                  a5kkbd_init_hw()
diff --git a/include/asm-arm/arch-arc/memory.h b/include/asm-arm/arch-arc/memory.h
new file mode 100644 (file)
index 0000000..8741f62
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * linux/include/asm-arm/arch-arc/memory.h
+ *
+ * Copyright (c) 1996-1999 Russell King.
+ *
+ * Changelog:
+ *  22-Nov-1996        RMK     Created
+ *  21-Mar-1999        RMK     Renamed to memory.h
+ *             RMK     Moved PAGE_OFFSET and TASK_SIZE here
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * User space: 26MB
+ */
+#define TASK_SIZE      (0x01a00000UL)
+
+/*
+ * Page offset: 32MB
+ */
+#define PAGE_OFFSET    (0x02000000UL)
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) vpage
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ppage
+
+/*
+ * Virtual view <-> DMA view memory address translations
+ * virt_to_bus: Used to translate the virtual address to an
+ *              address suitable to be passed to set_dma_addr
+ * bus_to_virt: Used to convert an address for DMA operations
+ *              to an address that the kernel can use.
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)       (x)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)       (x)
+
+#endif
diff --git a/include/asm-arm/arch-arc/mmu.h b/include/asm-arm/arch-arc/mmu.h
deleted file mode 100644 (file)
index 1e54d98..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * linux/include/asm-arm/arch-arc/mmu.h
- *
- * Copyright (c) 1996 Russell King.
- *
- * Changelog:
- *  22-11-1996 RMK     Created
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-#define __virt_to_phys__is_a_macro
-#define __virt_to_phys(vpage) vpage
-#define __phys_to_virt__is_a_macro
-#define __phys_to_virt(ppage) ppage
-
-/*
- * Virtual view <-> DMA view memory address translations
- * virt_to_bus: Used to translate the virtual address to an
- *              address suitable to be passed to set_dma_addr
- * bus_to_virt: Used to convert an address for DMA operations
- *              to an address that the kernel can use.
- */
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x)       (x)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x)       (x)
-
-#endif
index 3252e1109123fac6beaa8bc341a3e6084243b0cd..42f4c22f47ae34745e1932c8b81708c2f1af336d 100644 (file)
@@ -34,6 +34,8 @@ void oldlatch_bupdate(unsigned char mask,unsigned char newdata);
 /* newval=(oldval & mask)|newdata */
 void oldlatch_aupdate(unsigned char mask,unsigned char newdata);
 
+void oldlatch_init(void);
+
 #elif defined(CONFIG_ARCH_A5K)
 
 #ifdef __need_oldlatches
index cb63936e4e1117929424cdf308268fc55b7bb3ab..acc587961be1cb39747aa830f600efd0cf82ebde 100644 (file)
@@ -1,15 +1,18 @@
 /*
  * linux/include/asm-arm/arch-arc/processor.h
  *
- * Copyright (c) 1996 Russell King.
+ * Copyright (c) 1996-1999 Russell King.
  *
  * Changelog:
- *  10-09-1996 RMK     Created
+ *  10-Sep-1996        RMK     Created
+ *  21-Mar-1999        RMK     Added asm/arch/memory.h
  */
 
 #ifndef __ASM_ARCH_PROCESSOR_H
 #define __ASM_ARCH_PROCESSOR_H
 
+#include <asm/arch/memory.h>
+
 /*
  * Bus types
  */
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
-/*
- * User space: 26MB
- */
-#define TASK_SIZE      (0x01a00000UL)
-
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
 
-#define INIT_MMAP \
-{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
 #endif
index 6df347484bf10863f730a7bd97c9fc5f590b6a3f..c02ac8df5d65592a7332dec24993ebbbe43fdcd1 100644 (file)
@@ -8,6 +8,9 @@
  *  10-Oct-1996        RMK     Brought up to date with arch-sa110eval
  *  04-Dec-1997        RMK     Updated for new arch/arm/time.c
  */
+#include <asm/ioc.h>
+
+static long last_rtc_update = 0;       /* last time the cmos clock got updated */
 
 extern __inline__ unsigned long gettimeoffset (void)
 {
@@ -51,46 +54,140 @@ extern __inline__ unsigned long gettimeoffset (void)
        return offset;
 }
 
-/*
- * No need to reset the timer at every irq
- */
-#define reset_timer() 1
+extern int iic_control (unsigned char, int, char *, int);
 
-/*
- * Updating of the RTC.  We don't currently write the time to the
- * CMOS clock.
- */
-#define update_rtc()
+static int set_rtc_time(unsigned long nowtime)
+{
+       char buf[5], ctrl;
+
+       if (iic_control(0xa1, 0, &ctrl, 1) != 0)
+               printk("RTC: failed to read control reg\n");
+
+       /*
+        * Reset divider
+        */
+       ctrl |= 0x80;
+
+       if (iic_control(0xa0, 0, &ctrl, 1) != 0)
+               printk("RTC: failed to stop the clock\n");
+
+       /*
+        * We only set the time - we don't set the date.
+        * This means that there is the possibility once
+        * a day for the correction to disrupt the date.
+        * We really ought to write the time and date, or
+        * nothing at all.
+        */
+       buf[0] = 0;
+       buf[1] = nowtime % 60;          nowtime /= 60;
+       buf[2] = nowtime % 60;          nowtime /= 60;
+       buf[3] = nowtime % 24;
+
+       BIN_TO_BCD(buf[1]);
+       BIN_TO_BCD(buf[2]);
+       BIN_TO_BCD(buf[3]);
+
+       if (iic_control(0xa0, 1, buf, 4) != 0)
+               printk("RTC: Failed to set the time\n");
+
+       /*
+        * Re-enable divider
+        */
+       ctrl &= ~0x80;
+
+       if (iic_control(0xa0, 0, &ctrl, 1) != 0)
+               printk("RTC: failed to start the clock\n");
+
+       return 0;
+}
+
+extern __inline__ unsigned long get_rtc_time(void)
+{
+       unsigned int year, i;
+       char buf[8];
+
+       /*
+        * The year is not part of the RTC counter
+        * registers, and is stored in RAM.  This
+        * means that it will not be automatically
+        * updated.
+        */
+       if (iic_control(0xa1, 0xc0, buf, 1) != 0)
+               printk("RTC: failed to read the year\n");
+
+       /*
+        * If the year is before 1970, then the year
+        * is actually 100 in advance.  This gives us
+        * a year 2070 bug...
+        */
+       year = 1900 + buf[0];
+       if (year < 1970)
+               year += 100;
+
+       /*
+        * Read the time and date in one go - this
+        * will ensure that we don't get any effects
+        * due to carry (the RTC latches the counters
+        * during a read).
+        */
+       if (iic_control(0xa1, 2, buf, 5) != 0) {
+               printk("RTC: failed to read the time and date\n");
+               memset(buf, 0, sizeof(buf));
+       }
+
+       /*
+        * The RTC combines years with date and weekday
+        * with month.  We need to mask off this extra
+        * information before converting the date to
+        * binary.
+        */
+       buf[4] &= 0x1f;
+       buf[3] &= 0x3f;
+
+       for (i = 0; i < 5; i++)
+               BCD_TO_BIN(buf[i]);
+
+       return mktime(year, buf[4], buf[3], buf[2], buf[1], buf[0]);
+}
+
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       do_timer(regs);
+
+       /* If we have an externally synchronized linux clock, then update
+        * CMOS clock accordingly every ~11 minutes.  Set_rtc_mmss() has to be
+        * called as close as possible to 500 ms before the new second starts.
+        */
+       if ((time_status & STA_UNSYNC) == 0 &&
+           xtime.tv_sec > last_rtc_update + 660 &&
+           xtime.tv_usec >= 50000 - (tick >> 1) &&
+           xtime.tv_usec < 50000 + (tick >> 1)) {
+               if (set_rtc_time(xtime.tv_sec) == 0)
+                       last_rtc_update = xtime.tv_sec;
+               else
+                       last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+       }
+}
+
+static struct irqaction timerirq = {
+       timer_interrupt,
+       0,
+       0,
+       "timer",
+       NULL,
+       NULL
+};
 
 /*
  * Set up timer interrupt, and return the current time in seconds.
  */
-extern __inline__ unsigned long setup_timer (void)
+extern __inline__ void setup_timer(void)
 {
-       extern int iic_control (unsigned char, int, char *, int);
-       unsigned int year, mon, day, hour, min, sec;
-       char buf[8];
-
        outb(LATCH & 255, IOC_T0LTCHL);
        outb(LATCH >> 8, IOC_T0LTCHH);
        outb(0, IOC_T0GO);
 
-       iic_control (0xa0, 0xc0, buf, 1);
-       year = buf[0];
-       if ((year += 1900) < 1970)
-               year += 100;
+       xtime.tv_sec = get_rtc_time();
 
-       iic_control (0xa0, 2, buf, 5);
-       mon  = buf[4] & 0x1f;
-       day  = buf[3] & 0x3f;
-       hour = buf[2];
-       min  = buf[1];
-       sec  = buf[0];
-       BCD_TO_BIN(mon);
-       BCD_TO_BIN(day);
-       BCD_TO_BIN(hour);
-       BCD_TO_BIN(min);
-       BCD_TO_BIN(sec);
-
-       return mktime(year, mon, day, hour, min, sec);
+       setup_arm_irq(IRQ_TIMER, &timerirq);
 }
index f8c274f86a3d301f2309d82d869855c3a9aaff95..d9b46f1af2ceed1d8424449b025627529b744143 100644 (file)
@@ -5,8 +5,6 @@
  */
 #define VIDMEM ((char *)0x02000000)
  
-#include "../arch/arm/drivers/char/font.h"
-
 int video_num_columns, video_num_lines, video_size_row;
 int white, bytes_per_char_h;
 extern unsigned long con_charconvtable[256];
index 2746584c8a17089f670cf4e7c4174f7509eec337..71fcffe8e3e174ab8ed951eda7a9cf0c2354e73a 100644 (file)
@@ -1,15 +1,16 @@
 /*
  * linux/include/asm-arm/arch-ebsa110/a.out.h
  *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996-1999 Russell King
  */
-
 #ifndef __ASM_ARCH_A_OUT_H
 #define __ASM_ARCH_A_OUT_H
 
-#ifdef __KERNEL__
-#define STACK_TOP              ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#endif
+#include <asm/arch/memory.h>
+
+#define STACK_TOP \
+       ((current->personality == PER_LINUX_32BIT) ? \
+        TASK_SIZE : 0x04000000)
 
 #endif
 
index e502b0fc6691764233d5fbdffcbaf62acc32c335..5cad8350230b480af90880358d5a43ba27f89c74 100644 (file)
@@ -1,19 +1,13 @@
 /*
  * linux/include/asm-arm/arch-ebsa110/hardware.h
  *
- * Copyright (C) 1996,1997,1998 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
  *
  * This file contains the hardware definitions of the EBSA-110.
  */
-
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
-/*
- * What hardware must be present
- */
-#define HAS_PCIO
-
 #ifndef __ASSEMBLER__
 
 /*
 #define PIT_T2                 ((volatile unsigned char *)0xf2000009)
 #define PIT_T1                 ((volatile unsigned char *)0xf2000005)
 #define PIT_T0                 ((volatile unsigned char *)0xf2000001)
-#define PCIO_BASE              0xf0000000
 
 /*
  * Mapping areas
  */
 #define IO_BASE                        0xe0000000
-#define IO_SIZE                        0x20000000
-#define IO_START               0xe0000000
 
 /*
  * RAM definitions
  */
-#define MAPTOPHYS(a)           ((unsigned long)(a) - PAGE_OFFSET)
-#define KERNTOPHYS(a)          ((unsigned long)(&a))
-#define KERNEL_BASE            (0xc0008000)
 #define FLUSH_BASE_PHYS                0x40000000
 
 #else
 
-#define PCIO_BASE              0xf0000000
 #define IO_BASE                        0
 
 #endif
+
+#define IO_SIZE                        0x20000000
+#define IO_START               0xe0000000
+
+#define FLUSH_BASE             0xdf000000
+#define PCIO_BASE              0xf0000000
+
 #endif
 
index 2f8b804d541fd718fdd20d2911454e17f729ead3..d26e93c769d792c7e52d14959dbe6f215d74c7e1 100644 (file)
@@ -11,6 +11,8 @@
 #define IRQ_MSET       ((volatile unsigned char *)0xf2c00000)
 #define IRQ_MASK       ((volatile unsigned char *)0xf2c00000)
 
+#define fixup_irq(x) (x)
+
 static void ebsa110_mask_and_ack_irq(unsigned int irq)
 {
        *IRQ_MCLR = 1 << irq;
diff --git a/include/asm-arm/arch-ebsa110/memory.h b/include/asm-arm/arch-ebsa110/memory.h
new file mode 100644 (file)
index 0000000..67fa3a9
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * linux/include/asm-arm/arch-ebsa110/memory.h
+ *
+ * Copyright (c) 1996-1999 Russell King.
+ *
+ * Changelog:
+ *  20-Oct-1996        RMK     Created
+ *  31-Dec-1997        RMK     Fixed definitions to reduce warnings
+ *  21-Mar-1999        RMK     Renamed to memory.h
+ *             RMK     Moved TASK_SIZE and PAGE_OFFSET here
+ */
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE      (0xc0000000UL)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET    (0xc0000000UL)
+
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)       __virt_to_phys(x)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)       __phys_to_virt(x)
+
+#endif
diff --git a/include/asm-arm/arch-ebsa110/mm-init.h b/include/asm-arm/arch-ebsa110/mm-init.h
deleted file mode 100644 (file)
index c6937ab..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/mmap.h
- *
- * Copyright (C) 1996,1997,1998 Russell King
- */
diff --git a/include/asm-arm/arch-ebsa110/mmu.h b/include/asm-arm/arch-ebsa110/mmu.h
deleted file mode 100644 (file)
index 9777604..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/mmu.h
- *
- * Copyright (c) 1996,1997,1998 Russell King.
- *
- * Changelog:
- *  20-10-1996 RMK     Created
- *  31-12-1997 RMK     Fixed definitions to reduce warnings
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-#define __virt_to_phys__is_a_macro
-#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
-#define __phys_to_virt__is_a_macro
-#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
-
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x)       __virt_to_phys(x)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x)       __phys_to_virt(x)
-
-#endif
diff --git a/include/asm-arm/arch-ebsa110/oldlatches.h b/include/asm-arm/arch-ebsa110/oldlatches.h
deleted file mode 100644 (file)
index 8ff6ebd..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Dummy oldlatches.h
- *
- * Copyright (C) 1996 Russell King
- */
-
-#ifdef __need_oldlatches
-#error "Old latches not present in this (rpc) machine"
-#endif
index e98d1ff33f0e72390411f841bbe8ba57ace06539..bd99869afed77ba676a47905757dd2fe1832987c 100644 (file)
@@ -1,12 +1,17 @@
 /*
  * linux/include/asm-arm/arch-ebsa110/processor.h
  *
- * Copyright (C) 1996,1997,1998 Russell King
+ * Copyright (C) 1996-1999 Russell King
+ *
+ * Changelog:
+ *  21-Mar-1999        RMK     Added asm/arch/memory.h
  */
 
 #ifndef __ASM_ARCH_PROCESSOR_H
 #define __ASM_ARCH_PROCESSOR_H
 
+#include <asm/arch/memory.h>
+
 /*
  * Bus types
  */
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
-/*
- * User space: 3GB
- */
-#define TASK_SIZE      (0xc0000000UL)
-
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
 
-#define INIT_MMAP \
-{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
 #endif
index 1f21a02e6a34f7d2911c9c9ba40e692e8f3c738f..21728e4694d07042711feb5753b5879905ff4f8a 100644 (file)
@@ -38,63 +38,67 @@ extern __inline__ unsigned long gettimeoffset (void)
        return 0;
 }
 
-#ifndef DIVISOR
-extern __inline__ int reset_timer (void)
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        *PIT_T1 = (PIT1_COUNT) & 0xff;
        *PIT_T1 = (PIT1_COUNT) >> 8;
-       return 1;
-}
-#else
-extern __inline__ int reset_timer (void)
-{
-       static unsigned int divisor;
-#ifdef CONFIG_LEDS     
-       static int count = 50;
-#endif
-
-       *PIT_T1 = (PIT1_COUNT) & 0xff;
-       *PIT_T1 = (PIT1_COUNT) >> 8;
 
 #ifdef CONFIG_LEDS
-       if (--count == 0) {
-               count = 50;
-               leds_event(led_timer);
+       {
+               static int count = 50;
+               if (--count == 0) {
+                       count = 50;
+                       leds_event(led_timer);
+               }
        }
 #endif
 
-       if (divisor == 0) {
-               divisor = DIVISOR - 1;
-               return 1;
+       {
+#ifdef DIVISOR
+               static unsigned int divisor;
+
+               if (divisor-- == 0) {
+                       divisor = DIVISOR - 1;
+#else
+               {
+#endif
+                       do_timer(regs);
+               }
        }
-       divisor -= 1;
-       return 0;
 }
-#endif
 
-/*
- * We don't have a RTC to update!
- */
-#define update_rtc()
+static struct irqaction timerirq = {
+       timer_interrupt,
+       0,
+       0,
+       "timer",
+       NULL,
+       NULL
+};
 
 /*
  * Set up timer interrupt, and return the current time in seconds.
  */
-extern __inline__ unsigned long setup_timer (void)
+extern __inline__ void setup_timer(void)
 {
        /*
         * Timer 1, mode 0, 16-bit, autoreload
         */
        *PIT_CTRL = 0x70;
+
        /*
         * Refresh counter clocked at 47.8MHz/7 = 146.4ns
         * We want centi-second interrupts
         */
-       reset_timer ();
+       *PIT_T1 = (PIT1_COUNT) & 0xff;
+       *PIT_T1 = (PIT1_COUNT) >> 8;
+
        /*
         * Default the date to 1 Jan 1970 0:0:0
         * You will have to run a time daemon to set the
         * clock correctly at bootup
         */
-       return mktime(1970, 1, 1, 0, 0, 0);
+       xtime.tv_sec = mktime(1970, 1, 1, 0, 0, 0);
+
+       setup_arm_irq(IRQ_TIMER, &timerirq);
 }
index 2746584c8a17089f670cf4e7c4174f7509eec337..71fcffe8e3e174ab8ed951eda7a9cf0c2354e73a 100644 (file)
@@ -1,15 +1,16 @@
 /*
  * linux/include/asm-arm/arch-ebsa110/a.out.h
  *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996-1999 Russell King
  */
-
 #ifndef __ASM_ARCH_A_OUT_H
 #define __ASM_ARCH_A_OUT_H
 
-#ifdef __KERNEL__
-#define STACK_TOP              ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#endif
+#include <asm/arch/memory.h>
+
+#define STACK_TOP \
+       ((current->personality == PER_LINUX_32BIT) ? \
+        TASK_SIZE : 0x04000000)
 
 #endif
 
index 28c093aec3eed2a6dc892af2d28d2b4184024041..8b74a7f84436a487b8c02046cc8a1a52a84615c7 100644 (file)
@@ -3,8 +3,8 @@
  *
  * Architecture DMA routines
  *
- * Copyright (C) 1998 Russell King
- * Copyright (C) 1998 Philip Blundell
+ * Copyright (C) 1998,1999 Russell King
+ * Copyright (C) 1998,1999 Philip Blundell
  */
 #ifndef __ASM_ARCH_DMA_H
 #define __ASM_ARCH_DMA_H
 #define MAX_DMA_ADDRESS                0xffffffff
 
 /*
- * The 21285 has two internal DMA channels; we call these 0 and 1.
+ * The 21285 has two internal DMA channels; we call these 8 and 9.
  * On CATS hardware we have an additional eight ISA dma channels
- * numbered 2..9.
+ * numbered 0..7.
  */
+#define _ISA_DMA(x)            (0+(x))
+#define _DC21285_DMA(x)                (8+(x))
+
 #define MAX_DMA_CHANNELS       10
-#define DMA_ISA_BASE           2
-#define DMA_FLOPPY             (DMA_ISA_BASE + 2)
+
+#define DMA_FLOPPY             _ISA_DMA(2)
+#define DMA_ISA_CASCADE                _ISA_DMA(4)
 
 #endif /* _ASM_ARCH_DMA_H */
index e08c5b823011c06e5c605722e5b7f679703e58a1..c989e0f09ea73a93804377a90601cb7687562b80 100644 (file)
 /*
  * linux/include/asm-arm/arch-ebsa285/hardware.h
  *
- * Copyright (C) 1998 Russell King.
+ * Copyright (C) 1998-1999 Russell King.
  *
  * This file contains the hardware definitions of the EBSA-285.
  */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
 
+#include <linux/config.h>
+#include <asm/arch/memory.h>
 
-/*    Logical    Physical
+#ifdef CONFIG_HOST_FOOTBRIDGE
+/*   Virtual      Physical
  * 0xfff00000  0x40000000      X-Bus
- * 0xffe00000  0x7c000000      PCI I/O space
+ * 0xff000000  0x7c000000      PCI I/O space
  *
  * 0xfe000000  0x42000000      CSR
  * 0xfd000000  0x78000000      Outbound write flush
  * 0xfc000000  0x79000000      PCI IACK/special space
  *
- * 0xf9000000  0x7a010000      PCI Config type 1
- * 0xf8000000  0x7b010000      PCI Config type 0
+ * 0xf9000000  0x7a000000      PCI Config type 1
+ * 0xf8000000  0x7b000000      PCI Config type 0
  * 
  */
+#define XBUS_SIZE              0x00100000
+#define XBUS_BASE              0xfff00000
 
-#include <asm/dec21285.h>
-#define IO_BASE                        0xe0000000
-#define PCIO_BASE              0xffe00000
-#define PCI_IACK               0xfc000000 
+#define PCIO_SIZE              0x00100000
+#define PCIO_BASE              0xff000000
 
-#define XBUS_LEDS              ((volatile unsigned char *)0xfff12000)
+#define ARMCSR_SIZE            0x01000000
+#define ARMCSR_BASE            0xfe000000
+
+#define WFLUSH_SIZE            0x01000000
+#define WFLUSH_BASE            0xfd000000
+
+#define PCIIACK_SIZE           0x01000000
+#define PCIIACK_BASE           0xfc000000
+
+#define PCICFG1_SIZE           0x01000000
+#define PCICFG1_BASE           0xf9000000
+
+#define PCICFG0_SIZE           0x01000000
+#define PCICFG0_BASE           0xf8000000
+
+#define PCIMEM_SIZE            0x18000000
+#define PCIMEM_BASE            0xe0000000
+
+#define FLUSH_SIZE             0x00100000
+#define FLUSH_BASE             0xdf000000
+
+#define FLASH_SIZE             0x00400000
+#define FLASH_BASE             0xd8000000
+
+#elif defined(CONFIG_ARCH_CO285)
+
+#define PCIMEM_SIZE            0x80000000
+#define PCIMEM_BASE            0x80000000
+
+#define FLASH_SIZE             0x01000000
+#define FLASH_BASE             0x7f000000
+
+#define FLUSH_SIZE             0x00100000
+#define FLUSH_BASE             0x7e000000
+
+#define WFLUSH_SIZE            0x01000000
+#define WFLUSH_BASE            0x7d000000
+
+#define ARMCSR_SIZE            0x00100000
+#define ARMCSR_BASE            0x7cf00000
+
+#define XBUS_SIZE              0x00020000
+#define XBUS_BASE              0x7cee0000
+
+#define PCIO_SIZE              0x00010000
+#define PCIO_BASE              0x7ced0000
+
+#else
+
+#error Add your add-in architecture here
+
+#endif
+
+#define XBUS_LEDS              ((volatile unsigned char *)(XBUS_BASE + 0x12000))
 #define XBUS_LED_AMBER         (1 << 0)
 #define XBUS_LED_GREEN         (1 << 1)
 #define XBUS_LED_RED           (1 << 2)
 #define XBUS_LED_TOGGLE                (1 << 8)
 
-#define XBUS_SWITCH            ((volatile unsigned char *)0xfff12000)
+#define XBUS_SWITCH            ((volatile unsigned char *)(XBUS_BASE + 0x12000))
 #define XBUS_SWITCH_SWITCH     ((*XBUS_SWITCH) & 15)
 #define XBUS_SWITCH_J17_13     ((*XBUS_SWITCH) & (1 << 4))
 #define XBUS_SWITCH_J17_11     ((*XBUS_SWITCH) & (1 << 5))
 #define XBUS_SWITCH_J17_9      ((*XBUS_SWITCH) & (1 << 6))
 
-#define KERNTOPHYS(a)          ((unsigned long)(&a))
-
 #define PARAMS_OFFSET          0x0100
 #define PARAMS_BASE            (PAGE_OFFSET + PARAMS_OFFSET)
 
 #define FLUSH_BASE_PHYS                0x50000000
 
+
+/* PIC irq control */
+#define PIC_LO                 0x20
+#define PIC_MASK_LO            0x21
+#define PIC_HI                 0xA0
+#define PIC_MASK_HI            0xA1
+
+/* GPIO pins */
+#define GPIO_CCLK              0x800
+#define GPIO_DSCLK             0x400
+#define GPIO_E2CLK             0x200
+#define GPIO_IOLOAD            0x100
+#define GPIO_RED_LED           0x080
+#define GPIO_WDTIMER           0x040
+#define GPIO_DATA              0x020
+#define GPIO_IOCLK             0x010
+#define GPIO_DONE              0x008
+#define GPIO_FAN               0x004
+#define GPIO_GREEN_LED         0x002
+#define GPIO_RESET             0x001
+
+/* CPLD pins */
+#define CPLD_DSRESET           8
+#define CPLD_UNMUTE            2
+
+#ifndef __ASSEMBLY__
+extern void gpio_modify_op(int mask, int set);
+extern void gpio_modify_io(int mask, int in);
+extern int  gpio_read(void);
+extern void cpld_modify(int mask, int set);
+#endif
+
+#endif
index 1be73879d12edf4f9b28c706a9e5e41b9f99b806..b23ee68634fad2093c235cc7514d33dd738464ef 100644 (file)
  * has the constant-optimised IO
  */
 #undef ARCH_IO_DELAY
+#define ARCH_READWRITE
 
 /*
  * Dynamic IO functions - let the compiler
  * optimize the expressions
  */
-#define DECLARE_DYN_OUT(fnsuffix,instr,typ)                                    \
-extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port) \
-{                                                                              \
-       __asm__ __volatile__(                                                   \
-       "str%?" ##instr## "     %0, [%1, %2]            @ out"###fnsuffix       \
-       :                                                                       \
-       : "r" (value), "r" (PCIO_BASE), typ (port));                            \
+#define DECLARE_DYN_OUT(fnsuffix,instr,typ)                            \
+extern __inline__ void                                                 \
+__out##fnsuffix (unsigned int value, unsigned int port)                        \
+{                                                                      \
+       __asm__ __volatile__(                                           \
+       "str%?" ##instr## "     %0, [%1, %2]    @ out"###fnsuffix       \
+       :                                                               \
+       : "r" (value), "r" (PCIO_BASE), typ (port));                    \
 }
 
-#define DECLARE_DYN_IN(sz,fnsuffix,instr,typ)                                  \
-extern __inline__ unsigned sz __in##fnsuffix (unsigned int port)               \
-{                                                                              \
-       unsigned long value;                                                    \
-       __asm__ __volatile__(                                                   \
-       "ldr%?" ##instr## "     %0, [%1, %2]            @ in"###fnsuffix        \
-       : "=&r" (value)                                                         \
-       : "r" (PCIO_BASE), typ (port));                                         \
-       return (unsigned sz)value;                                              \
+#define DECLARE_DYN_IN(sz,fnsuffix,instr,typ)                          \
+extern __inline__ unsigned sz                                          \
+__in##fnsuffix (unsigned int port)                                     \
+{                                                                      \
+       unsigned long value;                                            \
+       __asm__ __volatile__(                                           \
+       "ldr%?" ##instr## "     %0, [%1, %2]    @ in"###fnsuffix        \
+       : "=&r" (value)                                                 \
+       : "r" (PCIO_BASE), typ (port));                                 \
+       return (unsigned sz)value;                                      \
 }
 
-extern __inline__ unsigned int __ioaddr (unsigned int port)                    \
-{                                                                              \
-       return (unsigned int)(PCIO_BASE + port);                                \
+extern __inline__ unsigned int __ioaddr (unsigned int port)            \
+{                                                                      \
+       return (unsigned int)(PCIO_BASE + port);                        \
 }
 
 #define DECLARE_IO(sz,fnsuffix,instr,typ)      \
@@ -64,65 +67,65 @@ DECLARE_IO(long,l,"","Jr")
  * These have to be macros for the 'J' constraint to work -
  * +/-4096 immediate operand.
  */
-#define __outbc(value,port)                                                    \
-({                                                                             \
-       __asm__ __volatile__(                                                   \
-       "str%?b %0, [%1, %2]                            @ outbc"                \
-       :                                                                       \
-       : "r" (value), "r" (PCIO_BASE), "Jr" (port));                           \
+#define __outbc(value,port)                                            \
+({                                                                     \
+       __asm__ __volatile__(                                           \
+       "str%?b %0, [%1, %2]                            @ outbc"        \
+       :                                                               \
+       : "r" (value), "r" (PCIO_BASE), "Jr" (port));                   \
 })
 
-#define __inbc(port)                                                           \
-({                                                                             \
-       unsigned char result;                                                   \
-       __asm__ __volatile__(                                                   \
-       "ldr%?b %0, [%1, %2]                            @ inbc"                 \
-       : "=r" (result)                                                         \
-       : "r" (PCIO_BASE), "Jr" (port));                                        \
-       result;                                                                 \
+#define __inbc(port)                                                   \
+({                                                                     \
+       unsigned char result;                                           \
+       __asm__ __volatile__(                                           \
+       "ldr%?b %0, [%1, %2]                            @ inbc"         \
+       : "=r" (result)                                                 \
+       : "r" (PCIO_BASE), "Jr" (port));                                \
+       result;                                                         \
 })
 
-#define __outwc(value,port)                                                    \
-({                                                                             \
-       __asm__ __volatile__(                                                   \
-       "str%?h %0, [%1, %2]                            @ outwc"                \
-       :                                                                       \
-       : "r" (value), "r" (PCIO_BASE), "r" (port));                            \
+#define __outwc(value,port)                                            \
+({                                                                     \
+       __asm__ __volatile__(                                           \
+       "str%?h %0, [%1, %2]                            @ outwc"        \
+       :                                                               \
+       : "r" (value), "r" (PCIO_BASE), "r" (port));                    \
 })
 
-#define __inwc(port)                                                           \
-({                                                                             \
-       unsigned short result;                                                  \
-       __asm__ __volatile__(                                                   \
-       "ldr%?h %0, [%1, %2]                            @ inwc"                 \
-       : "=r" (result)                                                         \
-       : "r" (PCIO_BASE), "r" (port));                                         \
-       result & 0xffff;                                                        \
+#define __inwc(port)                                                   \
+({                                                                     \
+       unsigned short result;                                          \
+       __asm__ __volatile__(                                           \
+       "ldr%?h %0, [%1, %2]                            @ inwc"         \
+       : "=r" (result)                                                 \
+       : "r" (PCIO_BASE), "r" (port));                                 \
+       result & 0xffff;                                                \
 })
 
-#define __outlc(value,port)                                                    \
-({                                                                             \
-       __asm__ __volatile__(                                                   \
-       "str%?  %0, [%1, %2]                            @ outlc"                \
-       :                                                                       \
-       : "r" (value), "r" (PCIO_BASE), "Jr" (port));                           \
+#define __outlc(value,port)                                            \
+({                                                                     \
+       __asm__ __volatile__(                                           \
+       "str%?  %0, [%1, %2]                            @ outlc"        \
+       :                                                               \
+       : "r" (value), "r" (PCIO_BASE), "Jr" (port));                   \
 })
 
-#define __inlc(port)                                                           \
-({                                                                             \
-       unsigned long result;                                                   \
-       __asm__ __volatile__(                                                   \
-       "ldr%?  %0, [%1, %2]                            @ inlc"                 \
-       : "=r" (result)                                                         \
-       : "r" (PCIO_BASE), "Jr" (port));                                        \
-       result;                                                                 \
+#define __inlc(port)                                                   \
+({                                                                     \
+       unsigned long result;                                           \
+       __asm__ __volatile__(                                           \
+       "ldr%?  %0, [%1, %2]                            @ inlc"         \
+       : "=r" (result)                                                 \
+       : "r" (PCIO_BASE), "Jr" (port));                                \
+       result;                                                         \
 })
 
-#define __ioaddrc(port)                                                                \
-({                                                                             \
-       unsigned long addr;                                                     \
-       addr = PCIO_BASE + port;                                                \
-       addr;                                                                   \
+#define __ioaddrc(port)                                                        \
+({                                                                     \
+       unsigned long addr;                                             \
+       addr = PCIO_BASE + port;                                        \
+       addr;                                                           \
 })
 
 /*
@@ -130,20 +133,22 @@ DECLARE_IO(long,l,"","Jr")
  *
  * IO address has already been translated to a virtual address
  */
-#define outb_t(v,p)                                                            \
+#define outb_t(v,p)                                                    \
        (*(volatile unsigned char *)(p) = (v))
 
-#define inb_t(p)                                                               \
+#define inb_t(p)                                                       \
        (*(volatile unsigned char *)(p))
 
-#define outl_t(v,p)                                                            \
+#define outl_t(v,p)                                                    \
        (*(volatile unsigned long *)(p) = (v))
 
-#define inl_t(p)                                                               \
+#define inl_t(p)                                                       \
        (*(volatile unsigned long *)(p))
 
 /*
- * ioremap support
+ * ioremap support - validate a PCI memory address,
+ * and convert a PCI memory address to a physical
+ * address for the page tables.
  */
 #define valid_ioaddr(iomem,size) ((iomem) < 0x80000000 && (iomem) + (size) <= 0x80000000)
 #define io_to_phys(iomem)      ((iomem) + DC21285_PCI_MEM)
@@ -153,58 +158,48 @@ DECLARE_IO(long,l,"","Jr")
  * is using read*() and so on with addresses they didn't get from ioremap
  * this can go away.
  */
-#define IO_FUDGE_FACTOR                0xe0000000
+#define IO_FUDGE_FACTOR                PCIMEM_BASE
 
-extern inline void *ioremap(unsigned long iomem_addr, unsigned long size)
-{
-       unsigned long phys_addr;
-
-       if (!valid_ioaddr(iomem_addr, size))
-               return NULL;
-
-       phys_addr = io_to_phys(iomem_addr & PAGE_MASK);
-
-       return (void *)((unsigned long)__ioremap(phys_addr, size, 0) 
-                       - IO_FUDGE_FACTOR);
-}
+/*
+ * ioremap takes a PCI memory address, as specified in
+ * linux/Documentation/IO-mapping.txt
+ */
+#define ioremap(iomem_addr,size)                                       \
+({                                                                     \
+       unsigned long _addr = (iomem_addr), _size = (size);             \
+       void *_ret = NULL;                                              \
+       if (valid_ioaddr(_addr, _size)) {                               \
+               _addr = io_to_phys(_addr);                              \
+               _ret = __ioremap(_addr, _size, 0) - IO_FUDGE_FACTOR;    \
+       }                                                               \
+       _ret; })
 
 #define ioremap_nocache(iomem_addr,size) ioremap((iomem_addr),(size))
 
 extern void iounmap(void *addr);
 
-/*
- * We'd probably be better off with these as macros rather than functions.
- * Firstly that would be more efficient and secondly we could do with the
- * ability to stop GCC whinging about type conversions.  --philb
- */
-static inline void writeb(unsigned char b, unsigned int addr)
-{
-       *(volatile unsigned char *)(IO_FUDGE_FACTOR + (addr)) = b;
-}
-
-static inline unsigned char readb(unsigned int addr)
-{
-       return *(volatile unsigned char *)(IO_FUDGE_FACTOR + (addr));
+#define DECLARE_PCI_WRITE(typ,fnsuffix)                                        \
+static inline void write##fnsuffix(unsigned typ val, unsigned int addr)        \
+{                                                                      \
+       *(volatile unsigned typ *)(IO_FUDGE_FACTOR + addr) = val;       \
 }
 
-static inline void writew(unsigned short b, unsigned int addr)
-{
-       *(volatile unsigned short *)(IO_FUDGE_FACTOR + (addr)) = b;
+#define DECLARE_PCI_READ(typ,fnsuffix)                                 \
+static inline unsigned typ read##fnsuffix (unsigned int addr)          \
+{                                                                      \
+       return *(volatile unsigned typ *)(IO_FUDGE_FACTOR + addr);      \
 }
 
-static inline unsigned short readw(unsigned int addr)
-{
-       return *(volatile unsigned short *)(IO_FUDGE_FACTOR + (addr));
-}
+#define DECLARE_PCI(typ,fnsuffix)                                      \
+       DECLARE_PCI_WRITE(typ,fnsuffix)                                 \
+       DECLARE_PCI_READ(typ,fnsuffix)
 
-static inline void writel(unsigned long b, unsigned int addr)
-{
-       *(volatile unsigned long *)(IO_FUDGE_FACTOR + (addr)) = b;
-}
+DECLARE_PCI(char,b)
+DECLARE_PCI(short,w)
+DECLARE_PCI(long,l)
 
-static inline unsigned short readl(unsigned int addr)
-{
-       return *(volatile unsigned long *)(IO_FUDGE_FACTOR + (addr));
-}
+#undef DECLARE_PCI
+#undef DECLARE_PCI_READ
+#undef DECLARE_PCI_WRITE
 
 #endif
index 74bc33c58e466277b1b825c739f9dc30db1ecba9..d8f0ab21d8a0629a2ffd67b41478141bc2c30ab1 100644 (file)
  * Copyright (C) 1996-1998 Russell King
  *
  * Changelog:
- *   22-08-1998        RMK     Restructured IRQ routines
- *   03-09-1998        PJB     Merged CATS support
+ *  22-Aug-1998        RMK     Restructured IRQ routines
+ *  03-Sep-1998        PJB     Merged CATS support
+ *  20-Jan-1998        RMK     Started merge of EBSA286, CATS and NetWinder
+ *  26-Jan-1999        PJB     Don't use IACK on CATS
+ *  16-Mar-1999        RMK     Added autodetect of ISA PICs
  */
-#include <linux/config.h>
+#include <asm/hardware.h>
+#include <asm/dec21285.h>
+#include <asm/irq.h>
 
-static void ebsa285_mask_irq(unsigned int irq)
+/*
+ * Footbridge IRQ translation table
+ *  Converts from our IRQ numbers into FootBridge masks
+ */
+static int dc21285_irq_mask[] = {
+       IRQ_MASK_UART_RX,       /*  0 */
+       IRQ_MASK_UART_TX,       /*  1 */
+       IRQ_MASK_TIMER1,        /*  2 */
+       IRQ_MASK_TIMER2,        /*  3 */
+       IRQ_MASK_TIMER3,        /*  4 */
+       IRQ_MASK_IN0,           /*  5 */
+       IRQ_MASK_IN1,           /*  6 */
+       IRQ_MASK_IN2,           /*  7 */
+       IRQ_MASK_IN3,           /*  8 */
+       IRQ_MASK_DOORBELLHOST,  /*  9 */
+       IRQ_MASK_DMA1,          /* 10 */
+       IRQ_MASK_DMA2,          /* 11 */
+       IRQ_MASK_PCI,           /* 12 */
+       IRQ_MASK_SDRAMPARITY,   /* 13 */
+       IRQ_MASK_I2OINPOST,     /* 14 */
+       IRQ_MASK_PCI_ERR        /* 15 */
+};
+
+static int isa_irq = -1;
+
+static inline int fixup_irq(unsigned int irq)
 {
-       *CSR_IRQ_DISABLE = 1 << irq;
+#ifdef CONFIG_HOST_FOOTBRIDGE
+       if (irq == isa_irq)
+               irq = *(unsigned char *)PCIIACK_BASE;
+#endif
+
+       return irq;
 }
 
-static void ebsa285_unmask_irq(unsigned int irq)
+static void dc21285_mask_irq(unsigned int irq)
 {
-       *CSR_IRQ_ENABLE = 1 << irq;
+       *CSR_IRQ_DISABLE = dc21285_irq_mask[irq & 15];
 }
 
-#ifdef CONFIG_CATS
+static void dc21285_unmask_irq(unsigned int irq)
+{
+       *CSR_IRQ_ENABLE = dc21285_irq_mask[irq & 15];
+}
 
-/*
- * This contains the irq mask for both 8259A irq controllers,
- */
-static unsigned int isa_irq_mask = 0xffff;
+static void isa_mask_pic_lo_irq(unsigned int irq)
+{
+       unsigned int mask = 1 << (irq & 7);
+
+       outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
+}
 
-#define cached_21      (isa_irq_mask & 0xff)
-#define cached_A1      ((isa_irq_mask >> 8) & 0xff)
+static void isa_mask_ack_pic_lo_irq(unsigned int irq)
+{
+       unsigned int mask = 1 << (irq & 7);
 
-#define update_8259(_irq)                      \
-       if ((_irq) & 8)                         \
-               outb(cached_A1, 0xa1);          \
-       else                                    \
-               outb(cached_21, 0x21);
+       outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
+       outb(0x20, PIC_LO);
+}
 
-static void isa_interrupt(int irq, void *h, struct pt_regs *regs)
+static void isa_unmask_pic_lo_irq(unsigned int irq)
 {
-       asmlinkage void do_IRQ(int irq, struct pt_regs * regs);
-       unsigned int irqbits = inb(0x20) | (inb(0xa0) << 8), irqnr = 0;
-       irqbits &= ~(1<<2);     /* don't try to service the cascade */
-       while (irqbits) {
-               if (irqbits & 1)
-                       do_IRQ(32 + irqnr, regs);
-               irqbits >>= 1;
-               irqnr++;
-       }
+       unsigned int mask = 1 << (irq & 7);
+
+       outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO);
 }
 
-static void no_action(int cpl, void *dev_id, struct pt_regs *regs) { }
+static void isa_mask_pic_hi_irq(unsigned int irq)
+{
+       unsigned int mask = 1 << (irq & 7);
 
-static struct irqaction irq_isa = 
-               { isa_interrupt, SA_INTERRUPT, 0, "ISA PIC", NULL, NULL };
-static struct irqaction irq_cascade = 
-               { no_action, 0, 0, "cascade", NULL, NULL };
+       outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
+}
 
-static void cats_mask_and_ack_isa_irq(unsigned int irq)
+static void isa_mask_ack_pic_hi_irq(unsigned int irq)
 {
-       isa_irq_mask |= (1 << (irq - 32));
-       update_8259(irq);
-       if (irq & 8) {
-               inb(0xA1);      /* DUMMY */
-               outb(cached_A1,0xA1);
-               outb(0x62,0x20);        /* Specific EOI to cascade */
-               outb(0x20,0xA0);
-       } else {
-               inb(0x21);      /* DUMMY */
-               outb(cached_21,0x21);
-               outb(0x20,0x20);
-       }
+       unsigned int mask = 1 << (irq & 7);
+
+       outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
+       outb(0x62, PIC_LO);
+       outb(0x20, PIC_HI);
 }
 
-static void cats_mask_isa_irq(unsigned int irq)
+static void isa_unmask_pic_hi_irq(unsigned int irq)
 {
-       isa_irq_mask |= (1 << (irq - 32));
-       update_8259(irq);
+       unsigned int mask = 1 << (irq & 7);
+
+       outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
 }
 
-static void cats_unmask_isa_irq(unsigned int irq)
+static void no_action(int cpl, void *dev_id, struct pt_regs *regs)
 {
-       isa_irq_mask &= ~(1 << (irq - 32));
-       update_8259(irq);
 }
-#endif 
+
+static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL };
 
 static __inline__ void irq_init_irq(void)
 {
        int irq;
 
+       /*
+        * setup DC21285 IRQs
+        */
        *CSR_IRQ_DISABLE = -1;
        *CSR_FIQ_DISABLE = -1;
 
-       for (irq = 0; irq < NR_IRQS; irq++) {
+       for (irq = _DC21285_IRQ(0); irq < _DC21285_IRQ(16); irq++) {
                irq_desc[irq].valid     = 1;
                irq_desc[irq].probe_ok  = 1;
-#ifdef CONFIG_CATS
-               if (machine_is_cats() && IRQ_IS_ISA(irq)) {
-                       irq_desc[irq].mask_ack  = cats_mask_and_ack_isa_irq;
-                       irq_desc[irq].mask      = cats_mask_isa_irq;
-                       irq_desc[irq].unmask    = cats_unmask_isa_irq;
+               irq_desc[irq].mask_ack  = dc21285_mask_irq;
+               irq_desc[irq].mask      = dc21285_mask_irq;
+               irq_desc[irq].unmask    = dc21285_unmask_irq;
+       }
+
+       /*
+        * Determine the ISA settings for
+        * the machine we're running on.
+        */
+       switch (machine_arch_type) {
+       default:
+               isa_irq = -1;
+               break;
+
+       case MACH_TYPE_EBSA285:
+               /* The following is dependent on which slot
+                * you plug the Southbridge card into.  We
+                * currently assume that you plug it into
+                * the right-hand most slot.
+                */
+               isa_irq = IRQ_PCI;
+               break;
+
+       case MACH_TYPE_CATS:
+               isa_irq = IRQ_IN2;
+               break;
+
+       case MACH_TYPE_NETWINDER:
+               isa_irq = IRQ_IN3;
+               break;
+       }
+
+       if (isa_irq != -1) {
+               /*
+                * Setup, and then probe for an ISA PIC
+                */
+               outb(0x11, PIC_LO);
+               outb(_ISA_IRQ(0), PIC_MASK_LO); /* IRQ number           */
+               outb(0x04, PIC_MASK_LO);        /* Slave on Ch2         */
+               outb(0x01, PIC_MASK_LO);        /* x86                  */
+               outb(0xf5, PIC_MASK_LO);        /* pattern: 11110101    */
+
+               outb(0x11, PIC_HI);
+               outb(_ISA_IRQ(8), PIC_MASK_HI); /* IRQ number           */
+               outb(0x02, PIC_MASK_HI);        /* Slave on Ch1         */
+               outb(0x01, PIC_MASK_HI);        /* x86                  */
+               outb(0xfa, PIC_MASK_HI);        /* pattern: 11111010    */
+
+//             outb(0x68, PIC_LO);             /* enable special mode  */
+//             outb(0x68, PIC_HI);             /* enable special mode  */
+               outb(0x0b, PIC_LO);
+               outb(0x0b, PIC_HI);
+
+               if (inb(PIC_MASK_LO) == 0xf5 && inb(PIC_MASK_HI) == 0xfa) {
+                       outb(0xff, PIC_MASK_LO);/* mask all IRQs        */
+                       outb(0xff, PIC_MASK_HI);/* mask all IRQs        */
                } else
-#endif
-               {
-                       irq_desc[irq].mask_ack  = ebsa285_mask_irq;
-                       irq_desc[irq].mask      = ebsa285_mask_irq;
-                       irq_desc[irq].unmask    = ebsa285_unmask_irq;
-               }
+                       isa_irq = -1;
        }
 
-#ifdef CONFIG_CATS
-       if (machine_is_cats()) {
-               request_region(0x20, 2, "pic1");
-               request_region(0xa0, 2, "pic2");
-
-               /* set up master 8259 */
-               outb(0x11, 0x20);
-               outb(0, 0x21);
-               outb(1<<2, 0x21);
-               outb(0x1, 0x21);
-               outb(0xff, 0x21);
-               outb(0x68, 0x20);
-               outb(0xa, 0x20);
-               
-               /* set up slave 8259 */
-               outb(0x11, 0xa0);
-               outb(0, 0xa1);
-               outb(2, 0xa1);
-               outb(0x1, 0xa1);
-               outb(0xff, 0xa1);
-               outb(0x68, 0xa0);
-               outb(0xa, 0xa0);
-
-               setup_arm_irq(IRQ_ISA_PIC, &irq_isa);
+       if (isa_irq != -1) {
+               for (irq = _ISA_IRQ(0); irq < _ISA_IRQ(8); irq++) {
+                       irq_desc[irq].valid     = 1;
+                       irq_desc[irq].probe_ok  = 1;
+                       irq_desc[irq].mask_ack  = isa_mask_ack_pic_lo_irq;
+                       irq_desc[irq].mask      = isa_mask_pic_lo_irq;
+                       irq_desc[irq].unmask    = isa_unmask_pic_lo_irq;
+               }
+
+               for (irq = _ISA_IRQ(8); irq < _ISA_IRQ(16); irq++) {
+                       irq_desc[irq].valid     = 1;
+                       irq_desc[irq].probe_ok  = 1;
+                       irq_desc[irq].mask_ack  = isa_mask_ack_pic_hi_irq;
+                       irq_desc[irq].mask      = isa_mask_pic_hi_irq;
+                       irq_desc[irq].unmask    = isa_unmask_pic_hi_irq;
+               }
+
+               request_region(PIC_LO, 2, "pic1");
+               request_region(PIC_HI, 2, "pic2");
                setup_arm_irq(IRQ_ISA_CASCADE, &irq_cascade);
+               setup_arm_irq(isa_irq, &irq_cascade);
        }
-#endif
 }
index 6021bee6ea1b90186748f15d7e3608c7bb128a26..afb2e379de8f0947ba842cdab2e49d65283e2ba6 100644 (file)
@@ -3,55 +3,85 @@
  *
  * Copyright (C) 1998 Russell King
  * Copyright (C) 1998 Phil Blundell
+ *
+ * Changelog:
+ *  20-Jan-1998        RMK     Started merge of EBSA286, CATS and NetWinder
+ *  01-Feb-1999        PJB     ISA IRQs start at 0 not 16
  */
 
-#define NR_IRQS                        48
+#define NR_IRQS                        32
+#define NR_DC21285_IRQS                16
+
+#define _ISA_IRQ(x)            (0 + (x))
+#define _DC21285_IRQ(x)                (16 + (x))
 
 /*
  * This is a list of all interrupts that the 21285
- * can generate
+ * can generate and we handle.
  */
-#define IRQ_RESERVED           0
-#define IRQ_SOFTIRQ            1
-#define IRQ_CONRX              2
-#define IRQ_CONTX              3
-#define IRQ_TIMER1             4
-#define IRQ_TIMER2             5
-#define IRQ_TIMER3             6
-#define IRQ_TIMER4             7
-#define IRQ_IN0                        8
-#define IRQ_IN1                        9
-#define IRQ_IN2                        10
-#define IRQ_IN3                        11
-#define IRQ_XCS0               12
-#define IRQ_XCS1               13
-#define IRQ_XCS2               14
-#define IRQ_DOORBELLHOST       15
-#define IRQ_DMA1               16
-#define IRQ_DMA2               17
-#define IRQ_PCI                        18
-#define IRQ_BIST               22
-#define IRQ_SERR               23
-#define IRQ_SDRAMPARITY                24
-#define IRQ_I2OINPOST          25
-#define IRQ_DISCARDTIMER       27
-#define IRQ_PCIDATAPARITY      28
-#define IRQ_PCIMASTERABORT     29
-#define IRQ_PCITARGETABORT     30
-#define IRQ_PCIPARITY          31
-
-/* IRQs 32-47 are the 16 ISA interrupts on a CATS board.  */
-#define IRQ_ISA_PIC    IRQ_IN2
-#define IRQ_IS_ISA(_x) (((_x) >= 32) && ((_x) <= 47))
-#define IRQ_ISA(_x)    ((_x) + 0x20)
-#define IRQ_ISA_CASCADE                IRQ_ISA(2)
+#define IRQ_CONRX              _DC21285_IRQ(0)
+#define IRQ_CONTX              _DC21285_IRQ(1)
+#define IRQ_TIMER1             _DC21285_IRQ(2)
+#define IRQ_TIMER2             _DC21285_IRQ(3)
+#define IRQ_TIMER3             _DC21285_IRQ(4)
+#define IRQ_IN0                        _DC21285_IRQ(5)
+#define IRQ_IN1                        _DC21285_IRQ(6)
+#define IRQ_IN2                        _DC21285_IRQ(7)
+#define IRQ_IN3                        _DC21285_IRQ(8)
+#define IRQ_DOORBELLHOST       _DC21285_IRQ(9)
+#define IRQ_DMA1               _DC21285_IRQ(10)
+#define IRQ_DMA2               _DC21285_IRQ(11)
+#define IRQ_PCI                        _DC21285_IRQ(12)
+#define IRQ_SDRAMPARITY                _DC21285_IRQ(13)
+#define IRQ_I2OINPOST          _DC21285_IRQ(14)
+#define IRQ_PCI_ERR            _DC21285_IRQ(15)
+
+#define IRQ_ISA_TIMER          _ISA_IRQ(0)
+#define IRQ_ISA_KEYBOARD       _ISA_IRQ(1)
+#define IRQ_ISA_CASCADE                _ISA_IRQ(2)
+#define IRQ_ISA_UART2          _ISA_IRQ(3)
+#define IRQ_ISA_UART           _ISA_IRQ(4)
+#define IRQ_ISA_FLOPPY         _ISA_IRQ(6)
+#define IRQ_ISA_PRINTER                _ISA_IRQ(7)
+#define IRQ_ISA_RTC_ALARM      _ISA_IRQ(8)
+#define IRQ_ISA_2              _ISA_IRQ(9)
+#define IRQ_ISA_PS2MOUSE       _ISA_IRQ(12)
+#define IRQ_ISA_HARDDISK1      _ISA_IRQ(14)
+#define IRQ_ISA_HARDDISK2      _ISA_IRQ(15)
+
+#define IRQ_MASK_UART_RX       (1 << 2)
+#define IRQ_MASK_UART_TX       (1 << 3)
+#define IRQ_MASK_TIMER1                (1 << 4)
+#define IRQ_MASK_TIMER2                (1 << 5)
+#define IRQ_MASK_TIMER3                (1 << 6)
+#define IRQ_MASK_IN0           (1 << 8)
+#define IRQ_MASK_IN1           (1 << 9)
+#define IRQ_MASK_IN2           (1 << 10)
+#define IRQ_MASK_IN3           (1 << 11)
+#define IRQ_MASK_DOORBELLHOST  (1 << 15)
+#define IRQ_MASK_DMA1          (1 << 16)
+#define IRQ_MASK_DMA2          (1 << 17)
+#define IRQ_MASK_PCI           (1 << 18)
+#define IRQ_MASK_SDRAMPARITY   (1 << 24)
+#define IRQ_MASK_I2OINPOST     (1 << 25)
+#define IRQ_MASK_PCI_ERR       ((1 <<23) | (1 << 27) | (1 << 28) | (1 << 29) | (1 << 30) | (1 << 31))
 
 /*
- * Now map them to the Linux interrupts
+ * Netwinder interrupt allocations
  */
-#define IRQ_TIMER              IRQ_TIMER1
-#define IRQ_FLOPPYDISK         IRQ_ISA(6)
-#define IRQ_HARDDISK           IRQ_ISA(14)
-#define IRQ_HARDDISK_SECONDARY IRQ_ISA(15)
+#define IRQ_NETWINDER_ETHER10  IRQ_IN0
+#define IRQ_NETWINDER_ETHER100 IRQ_IN1
+#define IRQ_NETWINDER_VIDCOMP  IRQ_IN2
+#define IRQ_NETWINDER_PS2MOUSE _ISA_IRQ(5)
+#define IRQ_NETWINDER_IR       _ISA_IRQ(6)
+#define IRQ_NETWINDER_BUTTON   _ISA_IRQ(10)
+#define IRQ_NETWINDER_VGA      _ISA_IRQ(11)
+#define IRQ_NETWINDER_SOUND    _ISA_IRQ(12)
+
+#undef RTC_IRQ
+#define RTC_IRQ                IRQ_ISA_RTC_ALARM
+#undef AUX_IRQ
+#define AUX_IRQ                (machine_is_netwinder() ? IRQ_NETWINDER_PS2MOUSE : IRQ_ISA_PS2MOUSE)
+#define IRQ_FLOPPYDISK IRQ_ISA_FLOPPY
 
-#define irq_cannonicalize(_i)  (((_i) == IRQ_ISA_CASCADE) ? IRQ_ISA(9) : _i)
+#define irq_cannonicalize(_i)  (((_i) == IRQ_ISA_CASCADE) ? IRQ_ISA_2 : _i)
index a5ccd590236d1f97fd89bacd28309217bb823129..dcc7b49f9eac72024bc615dd1a356e34e478539f 100644 (file)
@@ -6,16 +6,10 @@
  * (C) 1998 Russell King
  * (C) 1998 Phil Blundell
  */
-
-#include <linux/config.h>
 #include <asm/irq.h>
 #include <asm/system.h>
 
-#define NR_SCANCODES 128
-
-#ifdef CONFIG_CATS
-
-#define KEYBOARD_IRQ           IRQ_ISA(1)
+extern int have_isa_bridge;
 
 extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
 extern int pckbd_getkeycode(unsigned int scancode);
@@ -26,40 +20,52 @@ extern void pckbd_leds(unsigned char leds);
 extern void pckbd_init_hw(void);
 extern unsigned char pckbd_sysrq_xlate[128];
 
-#define kbd_setkeycode                 pckbd_setkeycode
-#define kbd_getkeycode                 pckbd_getkeycode
-#define kbd_translate(sc, kcp, ufp, rm) ({ *ufp = sc & 0200; \
-               pckbd_translate(sc & 0x7f, kcp, rm);})
+#define KEYBOARD_IRQ                   IRQ_ISA_KEYBOARD
 
-#define kbd_unexpected_up              pckbd_unexpected_up
-#define kbd_leds                       pckbd_leds
-#define kbd_init_hw()                  \
-               do { if (machine_is_cats()) pckbd_init_hw(); } while (0)
-#define kbd_sysrq_xlate                        pckbd_sysrq_xlate
-#define kbd_disable_irq()
-#define kbd_enable_irq()
+#define NR_SCANCODES 128
 
-#define SYSRQ_KEY      0x54
+#define kbd_setkeycode(sc,kc)                          \
+       ({                                              \
+               int __ret;                              \
+               if (have_isa_bridge)                    \
+                       __ret = pckbd_setkeycode(sc,kc);\
+               else                                    \
+                       __ret = -EINVAL;                \
+               __ret;                                  \
+       })
 
-#else
+#define kbd_getkeycode(sc)                             \
+       ({                                              \
+               int __ret;                              \
+               if (have_isa_bridge)                    \
+                       __ret = pckbd_getkeycode(sc);   \
+               else                                    \
+                       __ret = -EINVAL;                \
+               __ret;                                  \
+       })
 
-/* Dummy keyboard definitions */
+#define kbd_translate(sc, kcp, rm)                     \
+       ({                                              \
+               pckbd_translate(sc, kcp, rm);           \
+       })
 
-#define kbd_setkeycode(sc,kc)          (-EINVAL)
-#define kbd_getkeycode(sc)             (-EINVAL)
+#define kbd_unexpected_up              pckbd_unexpected_up
+
+#define kbd_leds(leds)                                 \
+       do {                                            \
+               if (have_isa_bridge)                    \
+                       pckbd_leds(leds);               \
+       } while (0)
+
+#define kbd_init_hw()                                  \
+       do {                                            \
+               if (have_isa_bridge)                    \
+                       pckbd_init_hw();                \
+       } while (0)
+
+#define kbd_sysrq_xlate                        pckbd_sysrq_xlate
 
-/* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode)
- * Returns  : 0 to ignore scancode, *keycode set to keycode, *up_flag
- *            set to 0200 if scancode indicates release
- */
-#define kbd_translate(sc, kcp, ufp, rm)        (1)
-#define kbd_unexpected_up(kc)          (0200)
-#define kbd_leds(leds)
-#define kbd_init_hw()
-//#define kbd_sysrq_xlate                      ps2kbd_sysrq_xlate
 #define kbd_disable_irq()
 #define kbd_enable_irq()
 
-#define SYSRQ_KEY      13
-
-#endif
+#define SYSRQ_KEY      0x54
diff --git a/include/asm-arm/arch-ebsa285/memory.h b/include/asm-arm/arch-ebsa285/memory.h
new file mode 100644 (file)
index 0000000..745750e
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * linux/include/asm-arm/arch-ebsa285/memory.h
+ *
+ * Copyright (c) 1996-1999 Russell King.
+ *
+ * Changelog:
+ *  20-Oct-1996        RMK     Created
+ *  31-Dec-1997        RMK     Fixed definitions to reduce warnings.
+ *  17-May-1998        DAG     Added __virt_to_bus and __bus_to_virt functions.
+ *  21-Nov-1998        RMK     Changed __virt_to_bus and __bus_to_virt to macros.
+ *  21-Mar-1999        RMK     Added PAGE_OFFSET for co285 architecture.
+ *                     Renamed to memory.h
+ *                     Moved PAGE_OFFSET and TASK_SIZE here
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+#if defined(CONFIG_HOST_FOOTBRIDGE)
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE              (0xc0000000UL)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET            (0xc0000000UL)
+
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x)       ((x) - 0xe0000000)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x)       ((x) + 0xe0000000)
+
+#elif defined(CONFIG_ADDIN_FOOTBRIDGE)
+
+#if defined(CONFIG_ARCH_CO285)
+
+/*
+ * Task size: 1.5GB
+ */
+#define TASK_SIZE              (0x60000000UL)
+
+/*
+ * Page offset: 1.5GB
+ */
+#define PAGE_OFFSET            (0x60000000UL)
+
+#else
+
+#error Add in your architecture here
+
+#endif
+
+#ifndef __ASSEMBLY__
+extern unsigned long __virt_to_bus(unsigned long);
+extern unsigned long __bus_to_virt(unsigned long);
+#endif
+
+#endif
+
+/*
+ * On Footbridge machines, the dram is contiguous.
+ * On Host Footbridge, these conversions are constant.
+ * On an add-in footbridge, these depend on register settings.
+ */
+#define __virt_to_phys__is_a_macro
+#define __virt_to_phys(vpage) ((unsigned long)(vpage) - PAGE_OFFSET)
+#define __phys_to_virt__is_a_macro
+#define __phys_to_virt(ppage) ((unsigned long)(ppage) + PAGE_OFFSET)
+
+#endif
diff --git a/include/asm-arm/arch-ebsa285/mm-init.h b/include/asm-arm/arch-ebsa285/mm-init.h
deleted file mode 100644 (file)
index c6937ab..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/mmap.h
- *
- * Copyright (C) 1996,1997,1998 Russell King
- */
diff --git a/include/asm-arm/arch-ebsa285/mmu.h b/include/asm-arm/arch-ebsa285/mmu.h
deleted file mode 100644 (file)
index b26aa8f..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa285/mmu.h
- *
- * Copyright (c) 1996,1997,1998 Russell King.
- *
- * Changelog:
- *  20-10-1996 RMK     Created
- *  31-12-1997 RMK     Fixed definitions to reduce warnings
- *  17-05-1998 DAG     Added __virt_to_bus and __bus_to_virt functions.
- *  21-11-1998 RMK     Changed __virt_to_bus and __bus_to_virt to macros.
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-/*
- * On ebsa285, the dram is contiguous
- */
-#define __virt_to_phys__is_a_macro
-#define __virt_to_phys(vpage) ((unsigned long)(vpage) - PAGE_OFFSET)
-#define __phys_to_virt__is_a_macro
-#define __phys_to_virt(ppage) ((unsigned long)(ppage) + PAGE_OFFSET)
-
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x)       ((x) - 0xe0000000)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x)       ((x) + 0xe0000000)
-
-#endif
diff --git a/include/asm-arm/arch-ebsa285/oldlatches.h b/include/asm-arm/arch-ebsa285/oldlatches.h
deleted file mode 100644 (file)
index 8ff6ebd..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Dummy oldlatches.h
- *
- * Copyright (C) 1996 Russell King
- */
-
-#ifdef __need_oldlatches
-#error "Old latches not present in this (rpc) machine"
-#endif
index e98d1ff33f0e72390411f841bbe8ba57ace06539..bd99869afed77ba676a47905757dd2fe1832987c 100644 (file)
@@ -1,12 +1,17 @@
 /*
  * linux/include/asm-arm/arch-ebsa110/processor.h
  *
- * Copyright (C) 1996,1997,1998 Russell King
+ * Copyright (C) 1996-1999 Russell King
+ *
+ * Changelog:
+ *  21-Mar-1999        RMK     Added asm/arch/memory.h
  */
 
 #ifndef __ASM_ARCH_PROCESSOR_H
 #define __ASM_ARCH_PROCESSOR_H
 
+#include <asm/arch/memory.h>
+
 /*
  * Bus types
  */
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
-/*
- * User space: 3GB
- */
-#define TASK_SIZE      (0xc0000000UL)
-
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
 
-#define INIT_MMAP \
-{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
 #endif
index c874f9dfa14ff87342bff360c57d728bdd42c32e..63a699e66057bbb518e6a6764b8944649f15cdc6 100644 (file)
@@ -10,8 +10,6 @@
 #ifndef __ASM_ARCH_SERIAL_H
 #define __ASM_ARCH_SERIAL_H
 
-#include <linux/config.h>
-
 #include <asm/irq.h>
 
 /*
  */
 #define BASE_BAUD (1843200 / 16)
 
-#ifdef CONFIG_CATS
-#define _SER_IRQ0      IRQ_ISA(4)
-#define _SER_IRQ1      IRQ_ISA(3)
-#else
-#define _SER_IRQ0      0
-#define _SER_IRQ1      0
-#endif
+#define _SER_IRQ0      IRQ_ISA_UART
+#define _SER_IRQ1      IRQ_ISA_UART2
 
 #define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
 
index 40d540dbae79ae2fa8f543007e8be539eb4444cb..a8f94c19803e05a41a2c08f61aec4cc2f3939bd2 100644 (file)
@@ -3,6 +3,8 @@
  *
  * Copyright (c) 1996,1997,1998 Russell King.
  */
+#include <asm/dec21285.h>
+#include <asm/io.h>
 #include <asm/hardware.h>
 #include <asm/leds.h>
 
@@ -16,14 +18,37 @@ extern __inline__ void arch_reset(char mode)
                 mov    r0, #0x130
                 mcr    p15, 0, r0, c1, c0      @ MMU off
                 mcr    p15, 0, ip, c7, c7      @ flush caches
-                mov    pc, lr");
+                mov    pc, lr" : : : "cc");
        } else {
-               /* To reboot, we set up the 21285 watchdog and enable it.
-                * We then wait for it to timeout.
-                */
-               *CSR_TIMER4_LOAD = 0x8000;
-               *CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
-               *CSR_SA110_CNTL |= 1 << 13;
+               if (machine_is_ebsa285() || machine_is_co285()) {
+                       /* To reboot, we set up the 21285 watchdog and
+                        * enable it.  We then wait for it to timeout.
+                        */
+                       *CSR_TIMER4_LOAD = 0x8000;
+                       *CSR_TIMER4_CNTL = TIMER_CNTL_ENABLE |
+                                          TIMER_CNTL_AUTORELOAD |
+                                          TIMER_CNTL_DIV16;
+                       *CSR_SA110_CNTL |= 1 << 13;
+               } else if (machine_is_netwinder()) {
+                       /* open up the SuperIO chip
+                        */
+                       outb(0x87, 0x370);
+                       outb(0x87, 0x370);
+
+                       /* aux function group 1 (logical device 7)
+                        */
+                       outb(0x07, 0x370);
+                       outb(0x07, 0x371);
+
+                       /* set GP16 for WD-TIMER output
+                        */
+                       outb(0xe6, 0x370);
+                       outb(0x00, 0x371);
+
+                       /* set a RED LED and toggle WD_TIMER for rebooting
+                        */
+                       outb(0xc4, 0x338);
+               }
        }
 }
 
index 342e9528ff1a64ae2b1fb05d855aa8081309ae03..ed70ecf25247312d4db5181807e5c9a3ec20dd5f 100644 (file)
  *  21-Mar-1998        RMK     Created
  *  27-Aug-1998        PJB     CATS support
  *  28-Dec-1998        APH     Made leds optional
+ *  20-Jan-1999        RMK     Started merge of EBSA285, CATS and NetWinder
+ *  16-Mar-1999        RMK     More support for EBSA285-like machines with RTCs in
  */
 
-#define RTC_PORT(x)            (0x72+(x))
-#define RTC_ALWAYS_BCD         1
+#define RTC_PORT(x)            (rtc_base+(x))
+#define RTC_ALWAYS_BCD         0
 
 #include <linux/config.h>
+#include <linux/mc146818rtc.h>
+
+#include <asm/dec21285.h>
 #include <asm/leds.h>
 #include <asm/system.h>
-#include <linux/mc146818rtc.h>
 
-extern __inline__ unsigned long gettimeoffset (void)
+static int rtc_base;
+static unsigned long (*gettimeoffset)(void);
+static int (*set_rtc_mmss)(unsigned long nowtime);
+static long last_rtc_update = 0;       /* last time the cmos clock got updated */
+
+#ifdef CONFIG_LEDS
+static void do_leds(void)
+{
+       static unsigned int count = 50;
+       static int last_pid;
+
+       if (current->pid != last_pid) {
+               last_pid = current->pid;
+               if (last_pid)
+                       leds_event(led_idle_end);
+               else
+                       leds_event(led_idle_start);
+       }
+               
+       if (--count == 0) {
+               count = 50;
+               leds_event(led_timer);
+       }
+}
+#else
+#define do_leds()
+#endif
+
+#define mSEC_10_from_14 ((14318180 + 100) / 200)
+
+static unsigned long isa_gettimeoffset(void)
+{
+       int count;
+
+       static int count_p = (mSEC_10_from_14/6);    /* for the first call after boot */
+       static unsigned long jiffies_p = 0;
+
+       /*
+        * cache volatile jiffies temporarily; we have IRQs turned off. 
+        */
+       unsigned long jiffies_t;
+
+       /* timer count may underflow right here */
+       outb_p(0x00, 0x43);     /* latch the count ASAP */
+
+       count = inb_p(0x40);    /* read the latched count */
+
+       /*
+        * We do this guaranteed double memory access instead of a _p 
+        * postfix in the previous port access. Wheee, hackady hack
+        */
+       jiffies_t = jiffies;
+
+       count |= inb_p(0x40) << 8;
+
+       /* Detect timer underflows.  If we haven't had a timer tick since 
+          the last time we were called, and time is apparently going
+          backwards, the counter must have wrapped during this routine. */
+       if ((jiffies_t == jiffies_p) && (count > count_p))
+               count -= (mSEC_10_from_14/6);
+       else
+               jiffies_p = jiffies_t;
+
+       count_p = count;
+
+       count = (((mSEC_10_from_14/6)-1) - count) * tick;
+       count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6);
+
+       return count;
+}
+
+static void isa_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       if (machine_is_netwinder())
+               do_leds();
+
+       do_timer(regs);
+
+       /* If we have an externally synchronized linux clock, then update
+        * CMOS clock accordingly every ~11 minutes.  Set_rtc_mmss() has to be
+        * called as close as possible to 500 ms before the new second starts.
+        */
+       if ((time_status & STA_UNSYNC) == 0 &&
+           xtime.tv_sec > last_rtc_update + 660 &&
+           xtime.tv_usec > 50000 - (tick >> 1) &&
+           xtime.tv_usec < 50000 + (tick >> 1)) {
+               if (set_rtc_mmss(xtime.tv_sec) == 0)
+                       last_rtc_update = xtime.tv_sec;
+               else
+                       last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+       }
+}
+
+static struct irqaction isa_timer_irq = {
+       isa_timer_interrupt,
+       0,
+       0,
+       "timer",
+       NULL,
+       NULL
+};
+
+__initfunc(static unsigned long
+get_isa_cmos_time(void))
+{
+       unsigned int year, mon, day, hour, min, sec;
+       int i;
+
+       // check to see if the RTC makes sense.....
+       if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0)
+               return mktime(1970, 1, 1, 0, 0, 0);
+
+       /* The Linux interpretation of the CMOS clock register contents:
+        * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
+        * RTC registers show the second which has precisely just started.
+        * Let's hope other operating systems interpret the RTC the same way.
+        */
+       /* read RTC exactly on falling edge of update flag */
+       for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
+               if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
+                       break;
+
+       for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
+               if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
+                       break;
+
+       do { /* Isn't this overkill ? UIP above should guarantee consistency */
+               sec  = CMOS_READ(RTC_SECONDS);
+               min  = CMOS_READ(RTC_MINUTES);
+               hour = CMOS_READ(RTC_HOURS);
+               day  = CMOS_READ(RTC_DAY_OF_MONTH);
+               mon  = CMOS_READ(RTC_MONTH);
+               year = CMOS_READ(RTC_YEAR);
+       } while (sec != CMOS_READ(RTC_SECONDS));
+
+       if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+               BCD_TO_BIN(sec);
+               BCD_TO_BIN(min);
+               BCD_TO_BIN(hour);
+               BCD_TO_BIN(day);
+               BCD_TO_BIN(mon);
+               BCD_TO_BIN(year);
+       }
+       if ((year += 1900) < 1970)
+               year += 100;
+       return mktime(year, mon, day, hour, min, sec);
+}
+
+static int
+set_isa_cmos_time(unsigned long nowtime)
+{
+       int retval = 0;
+       int real_seconds, real_minutes, cmos_minutes;
+       unsigned char save_control, save_freq_select;
+
+       save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
+       CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
+
+       save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
+       CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
+
+       cmos_minutes = CMOS_READ(RTC_MINUTES);
+       if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+               BCD_TO_BIN(cmos_minutes);
+
+       /*
+        * since we're only adjusting minutes and seconds,
+        * don't interfere with hour overflow. This avoids
+        * messing with unknown time zones but requires your
+        * RTC not to be off by more than 15 minutes
+        */
+       real_seconds = nowtime % 60;
+       real_minutes = nowtime / 60;
+       if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
+               real_minutes += 30;             /* correct for half hour time zone */
+       real_minutes %= 60;
+
+       if (abs(real_minutes - cmos_minutes) < 30) {
+               if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
+                       BIN_TO_BCD(real_seconds);
+                       BIN_TO_BCD(real_minutes);
+               }
+               CMOS_WRITE(real_seconds,RTC_SECONDS);
+               CMOS_WRITE(real_minutes,RTC_MINUTES);
+       } else
+               retval = -1;
+
+       /* The following flags have to be released exactly in this order,
+        * otherwise the DS12887 (popular MC146818A clone with integrated
+        * battery and quartz) will not reset the oscillator and will not
+        * update precisely 500 ms later. You won't find this mentioned in
+        * the Dallas Semiconductor data sheets, but who believes data
+        * sheets anyway ...                           -- Markus Kuhn
+        */
+       CMOS_WRITE(save_control, RTC_CONTROL);
+       CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
+
+       return retval;
+}
+
+
+
+static unsigned long __ebsa285_text timer1_gettimeoffset (void)
 {
        unsigned long value = LATCH - *CSR_TIMER1_VALUE;
 
        return (tick * value) / LATCH;
 }
 
-extern __inline__ int reset_timer (void)
+static void __ebsa285_text timer1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        *CSR_TIMER1_CLR = 0;
 
-#ifdef CONFIG_LEDS
-       /*
-        * Do the LEDs thing on EBSA-285 hardware.
+       /* Do the LEDs things on non-CATS hardware.
         */
-       if (!machine_is_cats()) {
-               static unsigned int count = 50;
-               static int last_pid;
-
-               if (current->pid != last_pid) {
-                       last_pid = current->pid;
-                       if (last_pid)
-                               leds_event(led_idle_end);
-                       else
-                               leds_event(led_idle_start);
-               }
-               
-               if (--count == 0) {
-                       count = 50;
-                       leds_event(led_timer);
-               }
+       if (!machine_is_cats())
+               do_leds();
+
+       do_timer(regs);
+
+       /* If we have an externally synchronized linux clock, then update
+        * CMOS clock accordingly every ~11 minutes.  Set_rtc_mmss() has to be
+        * called as close as possible to 500 ms before the new second starts.
+        */
+       if ((time_status & STA_UNSYNC) == 0 &&
+           xtime.tv_sec > last_rtc_update + 660 &&
+           xtime.tv_usec > 50000 - (tick >> 1) &&
+           xtime.tv_usec < 50000 + (tick >> 1)) {
+               if (set_rtc_mmss(xtime.tv_sec) == 0)
+                       last_rtc_update = xtime.tv_sec;
+               else
+                       last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
        }
-#endif
-       
-       return 1;
 }
 
-/*
- * We don't have a RTC to update!
- */
-#define update_rtc()
+static struct irqaction __ebsa285_data timer1_irq = {
+       timer1_interrupt,
+       0,
+       0,
+       "timer",
+       NULL,
+       NULL
+};
+
+static int
+set_dummy_time(unsigned long secs)
+{
+       return 1;
+}
 
 /*
  * Set up timer interrupt, and return the current time in seconds.
  */
-extern __inline__ unsigned long setup_timer (void)
+extern __inline__ void setup_timer(void)
 {
-       int year, mon, day, hour, min, sec;
+       switch(machine_arch_type) {
+       case MACH_TYPE_CO285:
+               /*
+                * Add-in 21285s shouldn't access the RTC
+                */
+               rtc_base = 0;
+               break;
 
-       /*
-        * Default the date to 1 Jan 1970 0:0:0
-        */
-       year = 1970; mon = 1; day = 1;
-       hour = 0; min = 0; sec = 0;
+       default:
+               rtc_base = 0x70;
+               break;
+       }
+
+       if (rtc_base) {
+               int reg_d, reg_b;
 
-       *CSR_TIMER1_CLR  = 0;
-       *CSR_TIMER1_LOAD = LATCH;
-       *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
+               reg_d = CMOS_READ(RTC_REG_D);
 
-       if (machine_is_cats()) 
-       {
-               int i;
                /*
-                * Read the real time from the Dallas chip.  (Code borrowed
-                * from arch/i386/kernel/time.c).
+                * make sure the divider is set
                 */
-               
-               /* The Linux interpretation of the CMOS clock register contents:
-                * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-                * RTC registers show the second which has precisely just started.
-                * Let's hope other operating systems interpret the RTC the same way.
+               CMOS_WRITE(RTC_REF_CLCK_32KHZ, RTC_REG_A);
+
+               /*
+                * Set control reg B
+                *   (24 hour mode, update enabled)
                 */
+               reg_b = CMOS_READ(RTC_REG_B) & 0x7f;
+               reg_b |= 2;
+               CMOS_WRITE(reg_b, RTC_REG_B);
 
-               /* read RTC exactly on falling edge of update flag */
-               for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
-                       if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
-                               break;
-               for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
-                       if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
-                               break;
-               do { /* Isn't this overkill ? UIP above should guarantee consistency */
-                       sec = CMOS_READ(RTC_SECONDS);
-                       min = CMOS_READ(RTC_MINUTES);
-                       hour = CMOS_READ(RTC_HOURS);
-                       day = CMOS_READ(RTC_DAY_OF_MONTH);
-                       mon = CMOS_READ(RTC_MONTH);
-                       year = CMOS_READ(RTC_YEAR);
-               } while (sec != CMOS_READ(RTC_SECONDS));
-               if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-               {
-                       BCD_TO_BIN(sec);
-                       BCD_TO_BIN(min);
-                       BCD_TO_BIN(hour);
-                       BCD_TO_BIN(day);
-                       BCD_TO_BIN(mon);
-                       BCD_TO_BIN(year);
-               }
-               if ((year += 1900) < 1970)
-                       year += 100;
+               if ((CMOS_READ(RTC_REG_A) & 0x7f) == RTC_REF_CLCK_32KHZ &&
+                   CMOS_READ(RTC_REG_B) == reg_b) {
+
+                       /*
+                        * Check the battery
+                        */
+                       if ((reg_d & 0x80) == 0)
+                               printk(KERN_WARNING "RTC: *** warning: CMOS battery bad\n");
+
+                       xtime.tv_sec = get_isa_cmos_time();
+                       set_rtc_mmss = set_isa_cmos_time;
+               } else
+                       rtc_base = 0;
        }
 
-       return mktime(year, mon, day, hour, min, sec);
+       if (!rtc_base) {
+               /*
+                * Default the date to 1 Jan 1970 0:0:0
+                */
+               xtime.tv_sec = mktime(1970, 1, 1, 0, 0, 0);
+               set_rtc_mmss = set_dummy_time;
+       }
+
+       if (machine_is_ebsa285()) {
+               gettimeoffset = timer1_gettimeoffset;
+
+               *CSR_TIMER1_CLR  = 0;
+               *CSR_TIMER1_LOAD = LATCH;
+               *CSR_TIMER1_CNTL = TIMER_CNTL_ENABLE | TIMER_CNTL_AUTORELOAD | TIMER_CNTL_DIV16;
+
+               setup_arm_irq(IRQ_TIMER1, &timer1_irq);
+       } else {
+               /* enable PIT timer */
+               /* set for periodic (4) and LSB/MSB write (0x30) */
+               outb(0x34, 0x43);
+               outb((mSEC_10_from_14/6) & 0xFF, 0x40);
+               outb((mSEC_10_from_14/6) >> 8, 0x40);
+
+               gettimeoffset = isa_gettimeoffset;
+
+               setup_arm_irq(IRQ_ISA_TIMER, &isa_timer_irq);
+       }
 }
index 0a730a70ebde674d9e434e85c7db6547c23d7cd0..de5bffba8d5409f348f224579452ef1d9f9d0fb4 100644 (file)
@@ -7,8 +7,8 @@
  */
 
 /*
- * On the EBSA, the clock ticks at weird rates.
- * This is therefore not used to calculate the
- * divisor.
+ * On EBSA285 boards, the clock runs at 50MHz and is
+ * divided by a 4-bit prescaler.  Other boards use an
+ * ISA derived timer, and this is unused.
  */
 #define CLOCK_TICK_RATE                (50000000 / 16)
index 7f655745f463c4de1624a89b641487be42f9a1e0..e72e4f362e597371d3aac1dc5c69d906a102fcb8 100644 (file)
@@ -1,9 +1,12 @@
 /*
- * linux/include/asm-arm/arch-ebsa110/uncompress.h
+ * linux/include/asm-arm/arch-ebsa285/uncompress.h
  *
  * Copyright (C) 1996,1997,1998 Russell King
  */
 
+/*
+ * Note! This could cause problems on the NetWinder
+ */
 #define BASE 0x42000160
 
 static __inline__ void putc(char c)
index 4972f5f707de35aefe8996d5d02811c5b010e81f..1cc4d571d1c16da7abc5dfc32afb111c2d21fb6d 100644 (file)
@@ -1,15 +1,16 @@
 /*
  * linux/include/asm-arm/arch-nexuspci/a.out.h
  *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996-1999 Russell King
  */
-
 #ifndef __ASM_ARCH_A_OUT_H
 #define __ASM_ARCH_A_OUT_H
 
-#ifdef __KERNEL__
-#define STACK_TOP              ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#endif
+#include <asm/arch/memory.h>
+
+#define STACK_TOP \
+       ((current->personality == PER_LINUX_32BIT) ? \
+        TASK_SIZE : 0x04000000)
 
 #endif
 
index 6141bbf4c22661eb8e8cac169fcceb1fae7f8241..2d267d89af6916c9ede004cabb0c40a9cb77c95c 100644 (file)
@@ -1,10 +1,12 @@
 /*
  * linux/include/asm-arm/arch-nexuspci/hardware.h
  *
- * Copyright (C) 1998 Philip Blundell
+ * Copyright (C) 1998-1999 Philip Blundell
  *
  * This file contains the hardware definitions of the Nexus PCI card.
  */
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
 
 /*    Logical    Physical
  * 0xfff00000  0x10000000      SCC2691 DUART
  * 0xffc00000  0x60000000      PLX registers
  * 0xfe000000  0x70000000      PCI I/O
  */
-#ifndef __ASM_ARCH_HARDWARE_H
-#define __ASM_ARCH_HARDWARE_H
-
-/*
- * What hardware must be present
- */
-
-#define HAS_PCIO
-#define PCIO_BASE              0xfe000000
 
 /*
  * Mapping areas
  */
-#define IO_BASE                        0xfe000000
+#define PCIO_BASE              0xfe000000
+#define FLUSH_BASE             0xdf000000
 
 /*
  * RAM definitions
  */
 #define RAM_BASE               0x40000000
-#define KERNTOPHYS(a)          ((unsigned long)(&a))
 #define FLUSH_BASE_PHYS                0x40000000
 
 #endif
index 7b03006dd08a4bff01076fde5788b80b64f00f70..000e6e75ff0505e05d9454110257fc0a759c2761 100644 (file)
@@ -9,6 +9,8 @@
 
 #include <asm/io.h>
 
+#define fixup_irq(x) (x)
+
 #define INTCONT                0xffe00000
 
 extern unsigned long soft_irq_mask;
diff --git a/include/asm-arm/arch-nexuspci/memory.h b/include/asm-arm/arch-nexuspci/memory.h
new file mode 100644 (file)
index 0000000..e721c04
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * linux/include/asm-arm/arch-nexuspci/memory.h
+ *
+ * Copyright (c) 1997, 1998 Philip Blundell.
+ * Copyright (c) 1999 Russell King
+ *
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE      (0xc0000000UL)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET    (0xc0000000UL)
+
+/*
+ * On NexusPCI, the DRAM is contiguous
+ */
+#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + 0x40000000)
+#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - 0x40000000)
+#define __virt_to_phys__is_a_macro
+#define __phys_to_virt__is_a_macro
+
+/*
+ * On the PCI bus the DRAM appears at address 0
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x) ((x) - PAGE_OFFSET)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x) ((x) + PAGE_OFFSET)
+
+#endif
diff --git a/include/asm-arm/arch-nexuspci/mm-init.h b/include/asm-arm/arch-nexuspci/mm-init.h
deleted file mode 100644 (file)
index 93887c9..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * linux/include/asm-arm/arch-nexuspci/mmap.h
- *
- * Copyright (C) 1998 Philip Blundell
- */
diff --git a/include/asm-arm/arch-nexuspci/mmu.h b/include/asm-arm/arch-nexuspci/mmu.h
deleted file mode 100644 (file)
index 9ecce06..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * linux/include/asm-arm/arch-nexuspci/mmu.h
- *
- * Copyright (c) 1997, 1998 Philip Blundell.
- *
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-/*
- * On NexusPCI, the DRAM is contiguous
- */
-#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET + 0x40000000)
-#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET - 0x40000000)
-#define __virt_to_phys__is_a_macro
-#define __phys_to_virt__is_a_macro
-
-/*
- * On the PCI bus the DRAM appears at address 0
- */
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x) ((x) - PAGE_OFFSET)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x) ((x) + PAGE_OFFSET)
-
-#endif
index f722be87cf11e2311a66afb7e1a88c7632f6f917..8349d6d4650c54f02a030643c6f4500c413f10ee 100644 (file)
@@ -1,13 +1,18 @@
 /*
- * linux/include/asm-arm/arch-ebsa110/processor.h
+ * linux/include/asm-arm/arch-nexuspci/processor.h
  *  from linux/include/asm-arm/arch-ebsa110/processor.h
  *
- * Copyright (C) 1996,1997,1998 Russell King
+ * Copyright (C) 1996-1999 Russell King
+ *
+ * Changelog:
+ *  21-Mar-1999        RMK     Added asm/arch/memory.h
  */
 
 #ifndef __ASM_ARCH_PROCESSOR_H
 #define __ASM_ARCH_PROCESSOR_H
 
+#include <asm/arch/memory.h>
+
 /*
  * Bus types
  */
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
-/*
- * User space: 3GB
- */
-#define TASK_SIZE      (0xc0000000UL)
-
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
 
-#define INIT_MMAP \
-{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
 #endif
index 1f3fa401f7433d8ec153d3e6a04988b705605d14..17f0ae472e84023f53462e9366eceed1c461bf21 100644 (file)
@@ -17,37 +17,53 @@ extern __inline__ unsigned long gettimeoffset (void)
        return 0;
 }
 
-extern __inline__ int reset_timer (void)
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
        static int count = 50;
+
        writeb(0x90, UART_BASE + 8);
-       if (--count == 0)
-       {
+
+       if (--count == 0) {
                static int state = 1;
                state ^= 1;
                writeb(0x1a + state, INTCONT);
                count = 50;
        }
+
        readb(UART_BASE + 0x14);
        readb(UART_BASE + 0x14);
        readb(UART_BASE + 0x14);
        readb(UART_BASE + 0x14);
        readb(UART_BASE + 0x14);
        readb(UART_BASE + 0x14);
-       return 1;
+
+       do_timer(regs); 
 }
 
-extern __inline__ unsigned long setup_timer (void)
+static struct irqaction timerirq = {
+       timer_interrupt,
+       0,
+       0,
+       "timer",
+       NULL,
+       NULL
+};
+
+extern __inline__ void setup_timer(void)
 {
        int tick = 3686400 / 16 / 2 / 100;
+
        writeb(tick & 0xff, UART_BASE + 0x1c);
        writeb(tick >> 8, UART_BASE + 0x18);
        writeb(0x80, UART_BASE + 8);
        writeb(0x10, UART_BASE + 0x14);
+
        /*
         * Default the date to 1 Jan 1970 0:0:0
         * You will have to run a time daemon to set the
         * clock correctly at bootup
         */
-       return mktime(1970, 1, 1, 0, 0, 0);
+       xtime.tv_sec = mktime(1970, 1, 1, 0, 0, 0);
+
+       setup_arm_irq(IRQ_TIMER, &timerirq);
 }
index 598614f23e56b54f020e696d16e18316c59a016f..56b2f4f7ab180e4c30468a31517ac19fea624270 100644 (file)
@@ -1,15 +1,16 @@
 /*
  * linux/include/asm-arm/arch-rpc/a.out.h
  *
- * Copyright (C) 1996 Russell King
+ * Copyright (C) 1996-1999 Russell King
  */
-
 #ifndef __ASM_ARCH_A_OUT_H
 #define __ASM_ARCH_A_OUT_H
 
-#ifdef __KERNEL__
-#define STACK_TOP              ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#endif
+#include <asm/arch/memory.h>
+
+#define STACK_TOP \
+       ((current->personality == PER_LINUX_32BIT) ? \
+        TASK_SIZE : 0x04000000)
 
 #endif
 
index 8ca6273ff711c3f7e881a8fec680664a2ee43691..0e3002f85469bb556f9229cfac9b9915e652ac41 100644 (file)
@@ -1,19 +1,19 @@
 /*
  * linux/include/asm-arm/arch-rpc/hardware.h
  *
- * Copyright (C) 1996 Russell King.
+ * Copyright (C) 1996-1999 Russell King.
  *
  * This file contains the hardware definitions of the RiscPC series machines.
  */
-
 #ifndef __ASM_ARCH_HARDWARE_H
 #define __ASM_ARCH_HARDWARE_H
 
+#include <asm/arch/memory.h>
+
 /*
  * What hardware must be present
  */
 #define HAS_IOMD
-#include <asm/iomd.h>
 #define HAS_VIDC20
 
 /* Hardware addresses of major areas.
@@ -26,7 +26,7 @@
 
 #define EASI_SIZE              0x08000000      /* EASI I/O */
 #define EASI_START             0x08000000
-#define EASI_BASE              0xe8000000
+#define EASI_BASE              0xe5000000
 
 #define IO_START               0x03000000      /* I/O */
 #define IO_SIZE                        0x01000000
@@ -38,6 +38,8 @@
 #define SCREEN1_END            0xd8000000
 #define SCREEN1_BASE           0xd0000000
 
+#define FLUSH_BASE             0xdf000000
+
 
 #ifndef __ASSEMBLER__
 
@@ -47,8 +49,9 @@
 #define IO_VIDC_AUDIO_BASE     0x80140000
 #define IO_VIDC_BASE           0x80100000
 #define IO_IOMD_BASE           0x80080000
+#define IOC_BASE               0x80080000
 
-#define IO_EC_EASI_BASE                0x82000000
+#define IO_EC_EASI_BASE                0x81400000
 #define IO_EC_IOC4_BASE                0x8009c000
 #define IO_EC_IOC_BASE         0x80090000
 #define IO_EC_MEMC8_BASE       0x8000ac00
@@ -59,7 +62,6 @@
  */
 #define EXPMASK_BASE           ((volatile unsigned char *)0xe0360000)
 #define IOEB_BASE              ((volatile unsigned char *)0xe0350050)
-#define IOC_BASE               ((volatile unsigned char *)0xe0200000)
 #define PCIO_FLOPPYDMABASE     ((volatile unsigned char *)0xe002a000)
 #define PCIO_BASE              0xe0010000
 
  * Offsets from RAM base
  */
 #define PARAMS_OFFSET          0x0100
-#define KERNEL_OFFSET          0x8000
 
 /*
  * RAM definitions
  */
-#define MAPTOPHYS(x)           (x)
-#define KERNTOPHYS(x)          ((unsigned long)(&x))
 #define GET_MEMORY_END(p)      (PAGE_OFFSET + p->u1.s.page_size * \
                                                (p->u1.s.pages_in_bank[0] + \
                                                 p->u1.s.pages_in_bank[1] + \
                                                 p->u1.s.pages_in_bank[2] + \
                                                 p->u1.s.pages_in_bank[3]))
 
-#define KERNEL_BASE            (PAGE_OFFSET + KERNEL_OFFSET)
 #define PARAMS_BASE            (PAGE_OFFSET + PARAMS_OFFSET)
 #define Z_PARAMS_BASE          (RAM_START + PARAMS_OFFSET)
-#define SAFE_ADDR              0x00000000      /* ROM */
+#define FLUSH_BASE_PHYS                0x00000000      /* ROM */
 
 #else
 
index a65f487d434d9903a3c362fc2990259a429ec98a..ea284b9a57fc506f57cb5ff0d8712a126bd8b580 100644 (file)
@@ -7,6 +7,9 @@
  *   10-10-1996        RMK     Brought up to date with arch-sa110eval
  *   22-08-1998        RMK     Restructured IRQ routines
  */
+#include <asm/iomd.h>
+
+#define fixup_irq(x) (x)
 
 static void rpc_mask_irq_ack_a(unsigned int irq)
 {
index d0d1667a68f0f706bd3bcc3af11003e1bb91aca4..c083b08bbf2f8158a1a5e1ce9d99cbe6bfc97539 100644 (file)
@@ -10,7 +10,6 @@
 
 #define NR_SCANCODES 128
 
-extern int ps2kbd_translate(unsigned char scancode, unsigned char *keycode_p, char *up_flag_p);
 extern void ps2kbd_leds(unsigned char leds);
 extern void ps2kbd_init_hw(void);
 extern unsigned char ps2kbd_sysrq_xlate[NR_SCANCODES];
@@ -18,15 +17,7 @@ extern unsigned char ps2kbd_sysrq_xlate[NR_SCANCODES];
 #define kbd_setkeycode(sc,kc)          (-EINVAL)
 #define kbd_getkeycode(sc)             (-EINVAL)
 
-/* Prototype: int kbd_translate(scancode, *keycode, *up_flag, raw_mode)
- * Returns  : 0 to ignore scancode, *keycode set to keycode, *up_flag
- *            set to 0200 if scancode indicates release
- */
-#ifdef NEW_KEYBOARD
-#define kbd_translate(sc, kcp, ufp, rm)        ps2kbd_translate(sc, kcp, ufp)
-#else
-#define kbd_translate(sc, kcp, rm) ({ unsigned int up_flag; ps2kbd_translate(sc, kcp, &up_flag); })
-#endif
+#define kbd_translate(sc, kcp, rm)     ({ *(kcp) = (sc); 1; })
 #define kbd_unexpected_up(kc)          (0200)
 #define kbd_leds(leds)                 ps2kbd_leds(leds)
 #define kbd_init_hw()                  ps2kbd_init_hw()
diff --git a/include/asm-arm/arch-rpc/memory.h b/include/asm-arm/arch-rpc/memory.h
new file mode 100644 (file)
index 0000000..6922cd0
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * linux/include/asm-arm/arch-rpc/memory.h
+ *
+ * Copyright (c) 1996,1997,1998 Russell King.
+ *
+ * Changelog:
+ *  20-Oct-1996        RMK     Created
+ *  31-Dec-1997        RMK     Fixed definitions to reduce warnings
+ *  11-Jan-1998        RMK     Uninlined to reduce hits on cache
+ *  08-Feb-1998        RMK     Added __virt_to_bus and __bus_to_virt
+ *  21-Mar-1999        RMK     Renamed to memory.h
+ *             RMK     Added TASK_SIZE and PAGE_OFFSET
+ */
+#ifndef __ASM_ARCH_MMU_H
+#define __ASM_ARCH_MMU_H
+
+/*
+ * Task size: 3GB
+ */
+#define TASK_SIZE      (0xc0000000UL)
+
+/*
+ * Page offset: 3GB
+ */
+#define PAGE_OFFSET    (0xc0000000UL)
+
+#ifndef __ASSEMBLY__
+extern unsigned long __virt_to_phys(unsigned long vpage);
+extern unsigned long __phys_to_virt(unsigned long ppage);
+#endif
+
+/*
+ * These are exactly the same on the RiscPC as the
+ * physical memory view.
+ */
+#define __virt_to_bus__is_a_macro
+#define __virt_to_bus(x) __virt_to_phys(x)
+#define __bus_to_virt__is_a_macro
+#define __bus_to_virt(x) __phys_to_virt(x)
+
+#endif
diff --git a/include/asm-arm/arch-rpc/mmu.h b/include/asm-arm/arch-rpc/mmu.h
deleted file mode 100644 (file)
index 7fca09a..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * linux/include/asm-arm/arch-rpc/mmu.h
- *
- * Copyright (c) 1996,1997,1998 Russell King.
- *
- * Changelog:
- *  20-10-1996 RMK     Created
- *  31-12-1997 RMK     Fixed definitions to reduce warnings
- *  11-01-1998 RMK     Uninlined to reduce hits on cache
- *  08-02-1998 RMK     Added __virt_to_bus and __bus_to_virt
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-extern unsigned long __virt_to_phys(unsigned long vpage);
-extern unsigned long __phys_to_virt(unsigned long ppage);
-
-/*
- * These are exactly the same on the RiscPC as the
- * physical memory view.
- */
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x) __virt_to_phys(x)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x) __phys_to_virt(x)
-
-#endif
diff --git a/include/asm-arm/arch-rpc/oldlatches.h b/include/asm-arm/arch-rpc/oldlatches.h
deleted file mode 100644 (file)
index 8ff6ebd..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Dummy oldlatches.h
- *
- * Copyright (C) 1996 Russell King
- */
-
-#ifdef __need_oldlatches
-#error "Old latches not present in this (rpc) machine"
-#endif
index 2fd9155b266a2e3adb430dd5b95b17363894c1dd..b2b6aec128f3bf13e1743ddfe821c13f18f772dd 100644 (file)
@@ -1,15 +1,18 @@
 /*
  * linux/include/asm-arm/arch-rpc/processor.h
  *
- * Copyright (c) 1996 Russell King.
+ * Copyright (c) 1996-1999 Russell King.
  *
  * Changelog:
- *  10-09-1996 RMK     Created
+ *  10-Sep-1996        RMK     Created
+ *  21-Mar-1999        RMK     Added asm/arch/memory.h
  */
 
 #ifndef __ASM_ARCH_PROCESSOR_H
 #define __ASM_ARCH_PROCESSOR_H
 
+#include <asm/arch/memory.h>
+
 /*
  * Bus types
  */
 #define MCA_bus 0
 #define MCA_bus__is_a_macro /* for versions in ksyms.c */
 
-/*
- * User space: 3GB
- */
-#define TASK_SIZE      (0xc0000000UL)
-
 /* This decides where the kernel will search for a free chunk of vm
  * space during mmap's.
  */
 #define TASK_UNMAPPED_BASE (TASK_SIZE / 3)
 
-#define INIT_MMAP \
-{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
 #endif
index e0a16f61d51f7658ff6740fc97108a6e87b56ff5..bb220ced40ee89c9ee3db9b984164e62a08339a9 100644 (file)
@@ -6,7 +6,7 @@
 #ifndef __ASM_ARCH_SYSTEM_H
 #define __ASM_ARCH_SYSTEM_H
 
-#include <asm/proc-fns.h>
+#include <asm/iomd.h>
 
 #define arch_reset(mode) {                                             \
        extern void ecard_reset (int card);                             \
index 3d0f742da2cb82189f96648d276f0bd0c8486cfc..b28666b37501d668f977fd45c333c004f11f266b 100644 (file)
@@ -8,6 +8,9 @@
  *  10-Oct-1996        RMK     Brought up to date with arch-sa110eval
  *  04-Dec-1997        RMK     Updated for new arch/arm/time.c
  */
+#include <asm/iomd.h>
+
+static long last_rtc_update = 0;       /* last time the cmos clock got updated */
 
 extern __inline__ unsigned long gettimeoffset (void)
 {
@@ -51,46 +54,148 @@ extern __inline__ unsigned long gettimeoffset (void)
        return offset;
 }
 
-/*
- * No need to reset the timer at every irq
- */
-#define reset_timer() 1
+extern int iic_control(unsigned char, int, char *, int);
 
-/*
- * Updating of the RTC.  We don't currently write the time to the
- * CMOS clock.
- */
-#define update_rtc()
+static int set_rtc_time(unsigned long nowtime)
+{
+       char buf[5], ctrl;
+
+       if (iic_control(0xa1, 0, &ctrl, 1) != 0)
+               printk("RTC: failed to read control reg\n");
+
+       /*
+        * Reset divider
+        */
+       ctrl |= 0x80;
+
+       if (iic_control(0xa0, 0, &ctrl, 1) != 0)
+               printk("RTC: failed to stop the clock\n");
+
+       /*
+        * We only set the time - we don't set the date.
+        * This means that there is the possibility once
+        * a day for the correction to disrupt the date.
+        * We really ought to write the time and date, or
+        * nothing at all.
+        */
+       buf[0] = 0;
+       buf[1] = nowtime % 60;          nowtime /= 60;
+       buf[2] = nowtime % 60;          nowtime /= 60;
+       buf[3] = nowtime % 24;
+
+       BIN_TO_BCD(buf[1]);
+       BIN_TO_BCD(buf[2]);
+       BIN_TO_BCD(buf[3]);
+
+       if (iic_control(0xa0, 1, buf, 4) != 0)
+               printk("RTC: Failed to set the time\n");
+
+       /*
+        * Re-enable divider
+        */
+       ctrl &= ~0x80;
+
+       if (iic_control(0xa0, 0, &ctrl, 1) != 0)
+               printk("RTC: failed to start the clock\n");
+
+       return 0;
+}
+
+extern __inline__ unsigned long get_rtc_time(void)
+{
+       unsigned int year, i;
+       char buf[8];
+
+       /*
+        * The year is not part of the RTC counter
+        * registers, and is stored in RAM.  This
+        * means that it will not be automatically
+        * updated.
+        */
+       if (iic_control(0xa1, 0xc0, buf, 1) != 0)
+               printk("RTC: failed to read the year\n");
+
+       /*
+        * If the year is before 1970, then the year
+        * is actually 100 in advance.  This gives us
+        * a year 2070 bug...
+        */
+       year = 1900 + buf[0];
+       if (year < 1970)
+               year += 100;
+
+       /*
+        * Read the time and date in one go - this
+        * will ensure that we don't get any effects
+        * due to carry (the RTC latches the counters
+        * during a read).
+        */
+       if (iic_control(0xa1, 2, buf, 5) != 0) {
+               printk("RTC: failed to read the time and date\n");
+               memset(buf, 0, sizeof(buf));
+       }
+
+       /*FIXME:
+        * This doesn't seem to work.  Does RISC OS
+        * actually use the RTC year?  It doesn't
+        * seem to.  In that case, how does it update
+        * the CMOS year?
+        */
+       /*year += (buf[3] >> 6) & 3;*/
+
+       /*
+        * The RTC combines years with date and weekday
+        * with month.  We need to mask off this extra
+        * information before converting the date to
+        * binary.
+        */
+       buf[4] &= 0x1f;
+       buf[3] &= 0x3f;
+printk("Year %4d mon %02X day %02X hour %02X min %02X sec %02X\n", year, buf[4], buf[3], buf[2], buf[1], buf[0]);
+       for (i = 0; i < 5; i++)
+               BCD_TO_BIN(buf[i]);
+
+       return mktime(year, buf[4], buf[3], buf[2], buf[1], buf[0]);
+}
+
+static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+       do_timer(regs);
+
+       /* If we have an externally synchronized linux clock, then update
+        * CMOS clock accordingly every ~11 minutes.  Set_rtc_mmss() has to be
+        * called as close as possible to 500 ms before the new second starts.
+        */
+       if ((time_status & STA_UNSYNC) == 0 &&
+           xtime.tv_sec > last_rtc_update + 660 &&
+           xtime.tv_usec >= 50000 - (tick >> 1) &&
+           xtime.tv_usec < 50000 + (tick >> 1)) {
+               if (set_rtc_time(xtime.tv_sec) == 0)
+                       last_rtc_update = xtime.tv_sec;
+               else
+                       last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
+       }
+}
+
+static struct irqaction timerirq = {
+       timer_interrupt,
+       0,
+       0,
+       "timer",
+       NULL,
+       NULL
+};
 
 /*
  * Set up timer interrupt, and return the current time in seconds.
  */
-extern __inline__ unsigned long setup_timer (void)
+extern __inline__ void setup_timer(void)
 {
-       extern int iic_control (unsigned char, int, char *, int);
-       unsigned int year, mon, day, hour, min, sec;
-       char buf[8];
-
        outb(LATCH & 255, IOMD_T0LTCHL);
        outb(LATCH >> 8, IOMD_T0LTCHH);
        outb(0, IOMD_T0GO);
 
-       iic_control (0xa0, 0xc0, buf, 1);
-       year = buf[0];
-       if ((year += 1900) < 1970)
-               year += 100;
+       xtime.tv_sec = get_rtc_time();
 
-       iic_control (0xa0, 2, buf, 5);
-       mon  = buf[4] & 0x1f;
-       day  = buf[3] & 0x3f;
-       hour = buf[2];
-       min  = buf[1];
-       sec  = buf[0];
-       BCD_TO_BIN(mon);
-       BCD_TO_BIN(day);
-       BCD_TO_BIN(hour);
-       BCD_TO_BIN(min);
-       BCD_TO_BIN(sec);
-
-       return mktime(year, mon, day, hour, min, sec);
+       setup_arm_irq(IRQ_TIMER, &timerirq);
 }
index 7740f0c3f09cd23f67e2802abc828d4ac4a79783..21701094aa84fcba818664c0505b7e80eb69fd14 100644 (file)
@@ -5,7 +5,6 @@
  */
 #define VIDMEM ((char *)SCREEN_START)
  
-#include "../arch/arm/drivers/char/font.h"
 #include <asm/hardware.h>
 #include <asm/io.h>
 
diff --git a/include/asm-arm/arch-vnc/a.out.h b/include/asm-arm/arch-vnc/a.out.h
deleted file mode 100644 (file)
index 011b083..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/a.out.h
- *
- * Copyright (C) 1996 Russell King
- */
-
-#ifndef __ASM_ARCH_A_OUT_H
-#define __ASM_ARCH_A_OUT_H
-
-#ifdef __KERNEL__
-#define STACK_TOP              ((current->personality==PER_LINUX_32BIT)? 0xc0000000 : 0x04000000)
-#endif
-
-#endif
diff --git a/include/asm-arm/arch-vnc/dma.h b/include/asm-arm/arch-vnc/dma.h
deleted file mode 100644 (file)
index f205f03..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/dma.h
- *
- * Architecture DMA routes
- *
- * Copyright (C) 1997.1998 Russell King
- */
-#ifndef __ASM_ARCH_DMA_H
-#define __ASM_ARCH_DMA_H
-
-/*
- * This is the maximum DMA address that can be DMAd to.
- * There should not be more than (0xd0000000 - 0xc0000000)
- * bytes of RAM.
- */
-#define MAX_DMA_ADDRESS                0xd0000000
-#define MAX_DMA_CHANNELS       8
-
-#endif /* _ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-vnc/hardware.h b/include/asm-arm/arch-vnc/hardware.h
deleted file mode 100644 (file)
index e95b1e7..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/hardware.h
- *
- * Copyright (C) 1998 Corel Computer/Russell King.
- *
- * This file contains the hardware definitions of the VNC.
- */
-
-/*    Logical    Physical
- * 0xffe00000  0x7c000000      PCI I/O space
- * 0xfe000000  0x42000000      CSR
- * 0xfd000000  0x78000000      Outbound write flush
- * 0xfc000000  0x79000000      PCI IACK/special space
- * 0xf9000000  0x7a000000      PCI Config type 1
- * 0xf8000000  0x7b000000      PCI Config type 0
- * 
- */
-
-#include <asm/dec21285.h>
-
-#define IO_BASE_ARM_CSR                0xfe000000
-#define PCI_IACK               0xfc000000
-/* LEDs */
-#define XBUS_LEDS              ((volatile unsigned char *)0xfff12000)
-#define XBUS_LED_AMBER         (1 << 0)
-#define XBUS_LED_GREEN         (1 << 1)
-#define XBUS_LED_RED           (1 << 2)
-#define XBUS_LED_TOGGLE                (1 << 8)
-
-/* PIC irq control */
-#define PIC_LO                 0x20
-#define PIC_MASK_LO            0x21
-#define PIC_HI                 0xA0
-#define PIC_MASK_HI            0xA1
-
-#define IO_END                 0xffffffff
-#define IO_BASE                        0xe0000000
-#define IO_SIZE                        (IO_END - IO_BASE)
-
-#define HAS_PCIO
-#define PCIO_BASE              0xffe00000
-
-#define KERNTOPHYS(a)          ((unsigned long)(&a))
-
-//#define PARAMS_OFFSET                0x0100
-//#define PARAMS_BASE          (PAGE_OFFSET + PARAMS_OFFSET)
-
-#define FLUSH_BASE_PHYS                0x50000000
-
-/* GPIO pins */
-#define GPIO_CCLK              0x800
-#define GPIO_DSCLK             0x400
-#define GPIO_E2CLK             0x200
-#define GPIO_IOLOAD            0x100
-#define GPIO_RED_LED           0x080
-#define GPIO_WDTIMER           0x040
-#define GPIO_DATA              0x020
-#define GPIO_IOCLK             0x010
-#define GPIO_DONE              0x008
-#define GPIO_FAN               0x004
-#define GPIO_GREEN_LED         0x002
-#define GPIO_RESET             0x001
-
-/* CPLD pins */
-#define CPLD_DSRESET           8
-#define CPLD_UNMUTE            2
-
-#ifndef __ASSEMBLY__
-extern void gpio_modify_op(int mask, int set);
-extern void gpio_modify_io(int mask, int in);
-extern int  gpio_read(void);
-extern void cpld_modify(int mask, int set);
-#endif
diff --git a/include/asm-arm/arch-vnc/ide.h b/include/asm-arm/arch-vnc/ide.h
deleted file mode 100644 (file)
index c3761ab..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/ide.h
- *
- * Copyright (c) 1998 Russell King
- *
- * Modifications:
- *  29-07-1998 RMK     Major re-work of IDE architecture specific code
- */
-#include <asm/irq.h>
-
-/*
- * Set up a hw structure for a specified data port, control port and IRQ.
- * This should follow whatever the default interface uses.
- */
-static __inline__ void
-ide_init_hwif_ports(hw_regs_t *hw, int data_port, int ctrl_port, int irq)
-{
-       ide_ioreg_t reg = (ide_ioreg_t) data_port;
-       int i;
-
-       memset(hw, 0, sizeof(*hw));
-
-       for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
-               hw->io_ports[i] = reg;
-               reg += 1;
-       }
-       hw->io_ports[IDE_CONTROL_OFFSET] = (ide_ioreg_t) ctrl_port;
-       hw->irq = irq;
-}
-
-/*
- * This registers the standard ports for this architecture with the IDE
- * driver.
- */
-static __inline__ void
-ide_init_default_hwifs(void)
-{
-       hw_regs_t hw;
-
-       ide_init_hwif_ports(&hw, 0x1f0, 0x3f6, IRQ_HARDDISK);
-       ide_register_hw(&hw, NULL);
-}
diff --git a/include/asm-arm/arch-vnc/io.h b/include/asm-arm/arch-vnc/io.h
deleted file mode 100644 (file)
index da1b485..0000000
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/io.h
- *
- * Copyright (C) 1997,1998 Russell King
- *
- * Modifications:
- *  06-Dec-1997        RMK     Created.
- */
-#ifndef __ASM_ARM_ARCH_IO_H
-#define __ASM_ARM_ARCH_IO_H
-
-/*
- * This architecture does not require any delayed IO, and
- * has the constant-optimised IO
- */
-#undef ARCH_IO_DELAY
-
-/*
- * Dynamic IO functions - let the compiler
- * optimize the expressions
- */
-#define DECLARE_DYN_OUT(fnsuffix,instr,typ)                                    \
-extern __inline__ void __out##fnsuffix (unsigned int value, unsigned int port) \
-{                                                                              \
-       __asm__ __volatile__(                                                   \
-       "str%?" ##instr## "     %0, [%1, %2]            @ out"###fnsuffix       \
-       :                                                                       \
-       : "r" (value), "r" (PCIO_BASE), typ (port));                            \
-}
-
-#define DECLARE_DYN_IN(sz,fnsuffix,instr,typ)                                  \
-extern __inline__ unsigned sz __in##fnsuffix (unsigned int port)               \
-{                                                                              \
-       unsigned long value;                                                    \
-       __asm__ __volatile__(                                                   \
-       "ldr%?" ##instr## "     %0, [%1, %2]            @ in"###fnsuffix        \
-       : "=&r" (value)                                                         \
-       : "r" (PCIO_BASE), typ (port));                                         \
-       return (unsigned sz)value;                                              \
-}
-
-extern __inline__ unsigned int __ioaddr (unsigned int port)                    \
-{                                                                              \
-       return (unsigned int)(PCIO_BASE + port);                                \
-}
-
-#define DECLARE_IO(sz,fnsuffix,instr,typ)      \
-       DECLARE_DYN_OUT(fnsuffix,instr,typ)     \
-       DECLARE_DYN_IN(sz,fnsuffix,instr,typ)
-
-DECLARE_IO(char,b,"b","Jr")
-DECLARE_IO(short,w,"h","r")
-DECLARE_IO(long,l,"","Jr")
-
-#undef DECLARE_IO
-#undef DECLARE_DYN_OUT
-#undef DECLARE_DYN_IN
-
-/*
- * Constant address IO functions
- *
- * These have to be macros for the 'J' constraint to work -
- * +/-4096 immediate operand.
- */
-#define __outbc(value,port)                                                    \
-({                                                                             \
-       __asm__ __volatile__(                                                   \
-       "strb   %0, [%1, %2]                            @ outbc"                \
-       :                                                                       \
-       : "r" (value), "r" (PCIO_BASE), "Jr" (port));                           \
-})
-
-#define __inbc(port)                                                           \
-({                                                                             \
-       unsigned char result;                                                   \
-       __asm__ __volatile__(                                                   \
-       "ldrb   %0, [%1, %2]                            @ inbc"                 \
-       : "=r" (result)                                                         \
-       : "r" (PCIO_BASE), "Jr" (port));                                        \
-       result;                                                                 \
-})
-
-#define __outwc(value,port)                                                    \
-({                                                                             \
-       __asm__ __volatile__(                                                   \
-       "strh   %0, [%1, %2]                            @ outwc"                \
-       :                                                                       \
-       : "r" (value), "r" (PCIO_BASE), "r" (port));                            \
-})
-
-#define __inwc(port)                                                           \
-({                                                                             \
-       unsigned short result;                                                  \
-       __asm__ __volatile__(                                                   \
-       "ldrh   %0, [%1, %2]                            @ inwc"                 \
-       : "=r" (result)                                                         \
-       : "r" (PCIO_BASE), "r" (port));                                         \
-       result & 0xffff;                                                        \
-})
-
-#define __outlc(value,port)                                                    \
-({                                                                             \
-       __asm__ __volatile__(                                                   \
-       "str    %0, [%1, %2]                            @ outlc"                \
-       :                                                                       \
-       : "r" (value), "r" (PCIO_BASE), "Jr" (port));                           \
-})
-
-#define __inlc(port)                                                           \
-({                                                                             \
-       unsigned long result;                                                   \
-       __asm__ __volatile__(                                                   \
-       "ldr    %0, [%1, %2]                            @ inlc"                 \
-       : "=r" (result)                                                         \
-       : "r" (PCIO_BASE), "Jr" (port));                                        \
-       result;                                                                 \
-})
-
-#define __ioaddrc(port)                                                                \
-({                                                                             \
-       unsigned long addr;                                                     \
-       addr = PCIO_BASE + port;                                                \
-       addr;                                                                   \
-})
-
-/*
- * Translated address IO functions
- *
- * IO address has already been translated to a virtual address
- */
-#define outb_t(v,p)                                                            \
-       (*(volatile unsigned char *)(p) = (v))
-
-#define inb_t(p)                                                               \
-       (*(volatile unsigned char *)(p))
-
-#define outl_t(v,p)                                                            \
-       (*(volatile unsigned long *)(p) = (v))
-
-#define inl_t(p)                                                               \
-       (*(volatile unsigned long *)(p))
-
-/*
- * This is not sufficient... (and it's a hack anyway)
- */
-static inline void writeb(unsigned char b, unsigned int addr)
-{
-       *(volatile unsigned char *)(0xe0000000 + (addr)) = b;
-}
-
-static inline unsigned char readb(unsigned int addr)
-{
-       return *(volatile unsigned char *)(0xe0000000 + (addr));
-}
-
-static inline void writew(unsigned short b, unsigned int addr)
-{
-       *(volatile unsigned short *)(0xe0000000 + (addr)) = b;
-}
-
-static inline unsigned short readw(unsigned int addr)
-{
-       return *(volatile unsigned short *)(0xe0000000 + (addr));
-}
-
-static inline void writel(unsigned long b, unsigned int addr)
-{
-       *(volatile unsigned long *)(0xe0000000 + (addr)) = b;
-}
-
-static inline unsigned long readl(unsigned int addr)
-{
-       return *(volatile unsigned long *)(0xe0000000 + (addr));
-}
-
-#endif
diff --git a/include/asm-arm/arch-vnc/irq.h b/include/asm-arm/arch-vnc/irq.h
deleted file mode 100644 (file)
index 10e4d0f..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-/*
- * include/asm-arm/arch-vnc/irq.h
- *
- * Copyright (C) 1998 Russell King
- *
- * Changelog:
- *   22-08-1998        RMK     Restructured IRQ routines
- */
-
-#include <asm/dec21285.h>
-#include <asm/irq.h>
-
-/*
- * FootBridge IRQ translation table
- *  Converts form our IRQ numbers into FootBridge masks (defined in irqs.h)
- */
-static int fb_irq_mask[16] = {
-       0,
-       IRQ_MASK_SOFTIRQ,
-       IRQ_MASK_UART_DEBUG,
-       0,
-       IRQ_MASK_TIMER0,
-       IRQ_MASK_TIMER1,
-       IRQ_MASK_TIMER2,
-       IRQ_MASK_WATCHDOG,
-       IRQ_MASK_ETHER10,
-       IRQ_MASK_ETHER100,
-       IRQ_MASK_VIDCOMP,
-       IRQ_MASK_EXTERN_IRQ,
-       IRQ_MASK_DMA1,
-       0,
-       0,
-       IRQ_MASK_PCI_ERR
-};
-
-static void vnc_mask_csr_irq(unsigned int irq)
-{
-       *CSR_IRQ_DISABLE = fb_irq_mask[irq];
-}
-
-static void vnc_unmask_csr_irq(unsigned int irq)
-{
-       *CSR_IRQ_ENABLE = fb_irq_mask[irq];
-}
-
-static void vnc_mask_pic_lo_irq(unsigned int irq)
-{
-       unsigned int mask = 1 << (irq & 7);
-
-       outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
-}
-
-static void vnc_mask_ack_pic_lo_irq(unsigned int irq)
-{
-       unsigned int mask = 1 << (irq & 7);
-
-       outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO);
-       outb(0x20, PIC_LO);
-}
-
-static void vnc_unmask_pic_lo_irq(unsigned int irq)
-{
-       unsigned int mask = ~(1 << (irq & 7));
-
-       outb(inb(PIC_MASK_LO) & mask, PIC_MASK_LO);
-}
-
-static void vnc_mask_pic_hi_irq(unsigned int irq)
-{
-       unsigned int mask = 1 << (irq & 7);
-
-       outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
-}
-
-static void vnc_mask_ack_pic_hi_irq(unsigned int irq)
-{
-       unsigned int mask = 1 << (irq & 7);
-
-       outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI);
-       outb(0x62, PIC_LO);
-       outb(0x20, PIC_HI);
-}
-
-static void vnc_unmask_pic_hi_irq(unsigned int irq)
-{
-       unsigned int mask = 1 << (irq & 7);
-
-       outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI);
-}
-
-static void no_action(int irq, void *dev_id, struct pt_regs *regs)
-{
-}
-
-static struct irqaction irq_cascade = { no_action, 0, 0, "cascade", NULL, NULL };
-
-static __inline__ void irq_init_irq(void)
-{
-       unsigned int irq;
-
-       outb(0x11, PIC_LO);
-       outb(0x10, PIC_MASK_LO);
-       outb(0x04, PIC_MASK_LO);
-       outb(1, PIC_MASK_LO);
-
-       outb(0x11, PIC_HI);
-       outb(0x18, PIC_MASK_HI);
-       outb(0x02, PIC_MASK_HI);
-       outb(1, PIC_MASK_HI);
-
-       *CSR_IRQ_DISABLE = ~IRQ_MASK_EXTERN_IRQ;
-       *CSR_IRQ_ENABLE  = IRQ_MASK_EXTERN_IRQ;
-       *CSR_FIQ_DISABLE = -1;
-
-       for (irq = 0; irq < NR_IRQS; irq++) {
-               irq_desc[irq].valid     = 1;
-               irq_desc[irq].probe_ok  = 1;
-
-               if (irq < 16) {
-                       irq_desc[irq].mask_ack  = vnc_mask_csr_irq;
-                       irq_desc[irq].mask      = vnc_mask_csr_irq;
-                       irq_desc[irq].unmask    = vnc_unmask_csr_irq;
-               } else if (irq < 24) {
-irq_desc[irq].probe_ok = 0;
-                       irq_desc[irq].mask_ack  = vnc_mask_ack_pic_lo_irq;
-                       irq_desc[irq].mask      = vnc_mask_pic_lo_irq;
-                       irq_desc[irq].unmask    = vnc_unmask_pic_lo_irq;
-               } else {
-irq_desc[irq].probe_ok = 0;
-                       irq_desc[irq].mask_ack  = vnc_mask_ack_pic_hi_irq;
-                       irq_desc[irq].mask      = vnc_mask_pic_hi_irq;
-                       irq_desc[irq].unmask    = vnc_unmask_pic_hi_irq;
-               }
-       }
-
-       irq_desc[0].probe_ok = 0;
-       irq_desc[IRQ_SOFTIRQ].probe_ok = 0;
-       irq_desc[IRQ_CONRX].probe_ok = 0;
-       irq_desc[IRQ_CONTX].probe_ok = 0;
-       irq_desc[IRQ_TIMER0].probe_ok = 0;
-       irq_desc[IRQ_TIMER1].probe_ok = 0;
-       irq_desc[IRQ_TIMER2].probe_ok = 0;
-       irq_desc[IRQ_WATCHDOG].probe_ok = 0;
-       irq_desc[IRQ_DMA1].probe_ok = 0;
-       irq_desc[13].probe_ok = 0;
-       irq_desc[14].probe_ok = 0;
-       irq_desc[IRQ_PCI_ERR].probe_ok = 0;
-       irq_desc[IRQ_PIC_HI].probe_ok = 0;
-       irq_desc[29].probe_ok = 0;
-       irq_desc[31].probe_ok = 0;
-
-       outb(0xff, PIC_MASK_LO);
-       outb(0xff, PIC_MASK_HI);
-
-       setup_arm_irq(IRQ_PIC_HI, &irq_cascade);
-}
diff --git a/include/asm-arm/arch-vnc/irqs.h b/include/asm-arm/arch-vnc/irqs.h
deleted file mode 100644 (file)
index e9df93f..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/irqs.h
- *
- * Copyright (C) 1998 Russell King
- */
-
-#define NR_IRQS                        32
-
-/*
- * This is a list of all interrupts that the 21285
- * can generate
- */
-#define IRQ_SOFTIRQ            1       /* from FB.1 */
-#define IRQ_CONRX              2       /* from FB.2 */
-#define IRQ_CONTX              3       /* from FB.3 */
-#define IRQ_TIMER0             4       /* from FB.4 */
-#define IRQ_TIMER1             5       /* from FB.5 */
-#define IRQ_TIMER2             6       /* from FB.6 */
-#define IRQ_WATCHDOG           7       /* from FB.7 */
-#define IRQ_ETHER10            8       /* from FB.8 */
-#define IRQ_ETHER100           9       /* from FB.9 */
-#define IRQ_VIDCOMP            10      /* from FB.10 */
-#define IRQ_EXTERN_IRQ         11      /* from FB.11: chain to IDE irq's */
-#define IRQ_DMA1               12      /* from future */
-#define IRQ_PCI_ERR            15      /* from FB.[28:31] */
-
-#define IRQ_TIMER4             16      /* from 553.0 */
-#define IRQ_KEYBOARD           17      /* from 553.1 */
-#define IRQ_PIC_HI             18      /* from 533.2: chained to 553.[8:15] */
-#define IRQ_UART2              19      /* from 553.3 */
-#define IRQ_UART               20      /* from 553.4 */
-#define IRQ_MOUSE              21      /* from 553.5 */
-#define IRQ_UART_IR            22      /* from 553.6 */
-#define IRQ_PRINTER            23      /* from 553.7 */
-#define IRQ_RTC_ALARM          24      /* from 553.8 */
-#define IRQ_POWERLOW           26      /* from 553.10 */
-#define IRQ_VGA                        27      /* from 553.11 */
-#define IRQ_SOUND              28      /* from 553.12 */
-#define IRQ_HARDDISK           30      /* from 553.14 */
-
-/* These defines handle the translation from the above FB #defines
- * into physical bits for the FootBridge IRQ registers
- */
-#define IRQ_MASK_SOFTIRQ       0x00000002
-#define IRQ_MASK_UART_DEBUG    0x0000000C
-#define IRQ_MASK_TIMER0                0x00000010
-#define IRQ_MASK_TIMER1                0x00000020
-#define IRQ_MASK_TIMER2                0x00000040
-#define IRQ_MASK_WATCHDOG      0x00000080
-#define IRQ_MASK_ETHER10       0x00000100
-#define IRQ_MASK_ETHER100      0x00000200
-#define IRQ_MASK_VIDCOMP       0x00000400
-#define IRQ_MASK_EXTERN_IRQ    0x00000800
-#define IRQ_MASK_DMA1          0x00030000
-#define IRQ_MASK_PCI_ERR       0xf8800000
-
-/*
- * Now map them to the Linux interrupts
- */
-#undef IRQ_TIMER
-#define IRQ_TIMER              IRQ_TIMER0
-#undef RTC_IRQ
-#define RTC_IRQ                        IRQ_RTC_ALARM
-#undef AUX_IRQ
-#define AUX_IRQ                        IRQ_MOUSE
-
-#define irq_cannonicalize(i)   (i)
diff --git a/include/asm-arm/arch-vnc/keyboard.h b/include/asm-arm/arch-vnc/keyboard.h
deleted file mode 100644 (file)
index ad2007d..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/keyboard.h
- *
- * Keyboard driver definitions for VNC architecture
- *
- * (C) 1998 Russell King
- */
-
-#include <asm/irq.h>
-
-#define NR_SCANCODES 128
-
-#define KEYBOARD_IRQ                   IRQ_KEYBOARD
-
-extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
-extern int pckbd_getkeycode(unsigned int scancode);
-extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
-                          char raw_mode);
-extern char pckbd_unexpected_up(unsigned char keycode);
-extern void pckbd_leds(unsigned char leds);
-extern void pckbd_init_hw(void);
-extern unsigned char pckbd_sysrq_xlate[128];
-
-#define kbd_setkeycode                 pckbd_setkeycode
-#define kbd_getkeycode                 pckbd_getkeycode
-#define kbd_translate(sc, kcp, ufp, rm) ({ *ufp = sc & 0200; \
-               pckbd_translate(sc & 0x7f, kcp, rm);})
-
-#define kbd_unexpected_up              pckbd_unexpected_up
-#define kbd_leds                       pckbd_leds
-#define kbd_init_hw()                  pckbd_init_hw()
-#define kbd_sysrq_xlate                        pckbd_sysrq_xlate
-#define kbd_disable_irq()
-#define kbd_enable_irq()
-
-#define SYSRQ_KEY 0x54
diff --git a/include/asm-arm/arch-vnc/mm-init.h b/include/asm-arm/arch-vnc/mm-init.h
deleted file mode 100644 (file)
index c6937ab..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/mmap.h
- *
- * Copyright (C) 1996,1997,1998 Russell King
- */
diff --git a/include/asm-arm/arch-vnc/mmu.h b/include/asm-arm/arch-vnc/mmu.h
deleted file mode 100644 (file)
index 64e3342..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/mmu.h
- *
- * Copyright (c) 1996,1997,1998 Russell King.
- *
- * Changelog:
- *  20-10-1996 RMK     Created
- *  31-12-1997 RMK     Fixed definitions to reduce warnings
- */
-#ifndef __ASM_ARCH_MMU_H
-#define __ASM_ARCH_MMU_H
-
-/*
- * On ebsa, the dram is contiguous
- */
-#define __virt_to_phys__is_a_macro
-#define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET)
-#define __phys_to_virt__is_a_macro
-#define __phys_to_virt(ppage) ((ppage) + PAGE_OFFSET)
-
-#define __virt_to_bus__is_a_macro
-#define __virt_to_bus(x)       (x - 0xe0000000)
-#define __bus_to_virt__is_a_macro
-#define __bus_to_virt(x)       (x + 0xe0000000)
-
-#endif
diff --git a/include/asm-arm/arch-vnc/oldlatches.h b/include/asm-arm/arch-vnc/oldlatches.h
deleted file mode 100644 (file)
index 8ff6ebd..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
- * Dummy oldlatches.h
- *
- * Copyright (C) 1996 Russell King
- */
-
-#ifdef __need_oldlatches
-#error "Old latches not present in this (rpc) machine"
-#endif
diff --git a/include/asm-arm/arch-vnc/param.h b/include/asm-arm/arch-vnc/param.h
deleted file mode 100644 (file)
index c860001..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/param.h
- *
- * Copyright (C) 1996 Russell King
- * Copyright (C) 1998 Philip Blundell
- */
-
-#define HZ 100
diff --git a/include/asm-arm/arch-vnc/processor.h b/include/asm-arm/arch-vnc/processor.h
deleted file mode 100644 (file)
index 5d84ad4..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/processor.h
- *
- * Copyright (C) 1996,1997,1998 Russell King
- */
-
-#ifndef __ASM_ARCH_PROCESSOR_H
-#define __ASM_ARCH_PROCESSOR_H
-
-/*
- * Bus types
- */
-#define EISA_bus 0
-#define EISA_bus__is_a_macro /* for versions in ksyms.c */
-#define MCA_bus 0
-#define MCA_bus__is_a_macro /* for versions in ksyms.c */
-
-/*
- * User space: 3GB
- */
-#define TASK_SIZE      (0xc0000000UL)
-
-/* This decides where the kernel will search for a free chunk of vm
- * space during mmap's.
- */
-#define TASK_UNMAPPED_BASE     (TASK_SIZE / 3)
-
-#define INIT_MMAP \
-{ &init_mm, 0, 0, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap }
-
-#endif
diff --git a/include/asm-arm/arch-vnc/serial.h b/include/asm-arm/arch-vnc/serial.h
deleted file mode 100644 (file)
index 74fea49..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/serial.h
- *
- * Copyright (c) 1996 Russell King.
- *
- * Changelog:
- *  15-10-1996 RMK     Created
- *  03-05-1998 RMK     Modified for Corel Video NC
- */
-#ifndef __ASM_ARCH_SERIAL_H
-#define __ASM_ARCH_SERIAL_H
-
-#include <asm/irq.h>
-
-/*
- * This assumes you have a 1.8432 MHz clock for your UART.
- *
- * It'd be nice if someone built a serial card with a 24.576 MHz
- * clock, since the 16550A is capable of handling a top speed of 1.5
- * megabits/second; but this requires the faster clock.
- */
-#define BASE_BAUD (1843200 / 16)
-
-#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
-
-     /* UART CLK        PORT  IRQ     FLAGS        */
-#define SERIAL_PORT_DFNS \
-       { 0, BASE_BAUD, 0x3F8, IRQ_UART , STD_COM_FLAGS },      /* ttyS0 */     \
-       { 0, BASE_BAUD, 0x2F8, IRQ_UART2, STD_COM_FLAGS },      /* ttyS1 */     \
-       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS2 */     \
-       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS3 */     \
-       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS4 */     \
-       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS5 */     \
-       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS6 */     \
-       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS7 */     \
-       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS8 */     \
-       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS9 */     \
-       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS10 */    \
-       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS11 */    \
-       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS12 */    \
-       { 0, BASE_BAUD, 0    , 0        , STD_COM_FLAGS },      /* ttyS13 */
-
-#endif
diff --git a/include/asm-arm/arch-vnc/shmparam.h b/include/asm-arm/arch-vnc/shmparam.h
deleted file mode 100644 (file)
index 9c36489..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/shmparam.h
- *
- * Copyright (c) 1996 Russell King.
- */
diff --git a/include/asm-arm/arch-vnc/system.h b/include/asm-arm/arch-vnc/system.h
deleted file mode 100644 (file)
index dc21f08..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/system.h
- *
- * Copyright (c) 1996,1997,1998 Russell King.
- * Copyright (c) 1998 Corel Computer Corp.
- */
-#include <asm/hardware.h>
-#include <asm/dec21285.h>
-#include <asm/leds.h>
-#include <asm/io.h>
-
-extern __inline__ void arch_reset(char mode)
-{
-       cli();
-
-       /* open up the SuperIO chip
-        */
-       outb(0x87, 0x370);
-       outb(0x87, 0x370);
-
-       /* aux function group 1 (Logical Device 7)
-        */
-       outb(0x07, 0x370);
-       outb(0x07, 0x371);
-
-       /* set GP16 for WD-TIMER output
-        */
-       outb(0xE6, 0x370);
-       outb(0x00, 0x371);
-
-       /* set a RED LED and toggle WD_TIMER for rebooting...
-        */
-       outb(0xC4, 0x338);
-}
-
-#define arch_start_idle()      leds_event(led_idle_start)
-#define arch_end_idle()                leds_event(led_idle_end)
diff --git a/include/asm-arm/arch-vnc/time.h b/include/asm-arm/arch-vnc/time.h
deleted file mode 100644 (file)
index c55000b..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/time.h
- *
- * Copyright (c) 1997 Corel Computer Corp.
- * Slight modifications to bring in line with ebsa285 port.
- *  -- Russell King.
- *  Added LED driver (based on the ebsa285 code) - Alex Holden 28/12/98.
- */
-
-#include <linux/config.h>
-#include <linux/mc146818rtc.h>
-
-#include <asm/leds.h>
-#include <asm/system.h>
-
-#undef IRQ_TIMER
-#define IRQ_TIMER              IRQ_TIMER4
-
-#define mSEC_10_from_14 ((14318180 + 100) / 200)
-
-extern __inline__ unsigned long gettimeoffset (void)
-{
-       int count;
-
-       static int count_p = (mSEC_10_from_14/6);    /* for the first call after boot */
-       static unsigned long jiffies_p = 0;
-
-       /*
-        * cache volatile jiffies temporarily; we have IRQs turned off. 
-        */
-       unsigned long jiffies_t;
-
-       /* timer count may underflow right here */
-       outb_p(0x00, 0x43);     /* latch the count ASAP */
-
-       count = inb_p(0x40);    /* read the latched count */
-
-       /*
-        * We do this guaranteed double memory access instead of a _p 
-        * postfix in the previous port access. Wheee, hackady hack
-        */
-       jiffies_t = jiffies;
-
-       count |= inb_p(0x40) << 8;
-
-       /* Detect timer underflows.  If we haven't had a timer tick since 
-          the last time we were called, and time is apparently going
-          backwards, the counter must have wrapped during this routine. */
-       if ((jiffies_t == jiffies_p) && (count > count_p))
-               count -= (mSEC_10_from_14/6);
-       else
-               jiffies_p = jiffies_t;
-
-       count_p = count;
-
-       count = (((mSEC_10_from_14/6)-1) - count) * tick;
-       count = (count + (mSEC_10_from_14/6)/2) / (mSEC_10_from_14/6);
-
-       return count;
-}
-
-extern __inline__ int reset_timer (void)
-{
-#ifdef CONFIG_LEDS
-       static unsigned int count = 50;
-       static int last_pid;
-
-       if (current->pid != last_pid) {
-               last_pid = current->pid;
-               if (last_pid)
-                       leds_event(led_idle_end);
-               else
-                       leds_event(led_idle_start);
-       }
-
-       if (--count == 0) {
-               count = 50;
-               leds_event(led_timer);
-       }
-#endif
-       return 1;
-}
-
-unsigned long set_rtc_mmss(unsigned long nowtime)
-{
-       int retval = 0;
-       int real_seconds, real_minutes, cmos_minutes;
-       unsigned char save_control, save_freq_select;
-
-       save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
-       CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
-
-       save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
-       CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
-
-       cmos_minutes = CMOS_READ(RTC_MINUTES);
-       if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
-               BCD_TO_BIN(cmos_minutes);
-
-       /*
-        * since we're only adjusting minutes and seconds,
-        * don't interfere with hour overflow. This avoids
-        * messing with unknown time zones but requires your
-        * RTC not to be off by more than 15 minutes
-        */
-       real_seconds = nowtime % 60;
-       real_minutes = nowtime / 60;
-       if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
-               real_minutes += 30;             /* correct for half hour time zone */
-       real_minutes %= 60;
-
-       if (abs(real_minutes - cmos_minutes) < 30) {
-               if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-                       BIN_TO_BCD(real_seconds);
-                       BIN_TO_BCD(real_minutes);
-               }
-               CMOS_WRITE(real_seconds,RTC_SECONDS);
-               CMOS_WRITE(real_minutes,RTC_MINUTES);
-       } else
-               retval = -1;
-
-       /* The following flags have to be released exactly in this order,
-        * otherwise the DS12887 (popular MC146818A clone with integrated
-        * battery and quartz) will not reset the oscillator and will not
-        * update precisely 500 ms later. You won't find this mentioned in
-        * the Dallas Semiconductor data sheets, but who believes data
-        * sheets anyway ...                           -- Markus Kuhn
-        */
-       CMOS_WRITE(save_control, RTC_CONTROL);
-       CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
-
-       return retval;
-}
-
-/*
- * We don't have a RTC to update!
- */
-extern __inline__ void update_rtc(void)
-{
-       static long last_rtc_update = 0;        /* last time the cmos clock got updated */
-
-       /* If we have an externally synchronized linux clock, then update
-        * CMOS clock accordingly every ~11 minutes.  Set_rtc_mmss() has to be
-        * called as close as possible to 500 ms before the new second starts.
-        */
-       if (time_state != TIME_BAD && xtime.tv_sec > last_rtc_update + 660 &&
-           xtime.tv_usec > 50000 - (tick >> 1) &&
-           xtime.tv_usec < 50000 + (tick >> 1)) {
-               if (set_rtc_mmss(xtime.tv_sec) == 0)
-                       last_rtc_update = xtime.tv_sec;
-               else
-                       last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
-       }
-}
-
-extern __inline__ unsigned long get_cmos_time(void)
-{
-       unsigned int year, mon, day, hour, min, sec;
-       int i;
-
-       // check to see if the RTC makes sense.....
-       if ((CMOS_READ(RTC_VALID) & RTC_VRT) == 0)
-               return mktime(1970, 1, 1, 0, 0, 0);
-
-       /* The Linux interpretation of the CMOS clock register contents:
-        * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
-        * RTC registers show the second which has precisely just started.
-        * Let's hope other operating systems interpret the RTC the same way.
-        */
-       /* read RTC exactly on falling edge of update flag */
-       for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
-               if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
-                       break;
-
-       for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
-               if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
-                       break;
-
-       do { /* Isn't this overkill ? UIP above should guarantee consistency */
-               sec = CMOS_READ(RTC_SECONDS);
-               min = CMOS_READ(RTC_MINUTES);
-               hour = CMOS_READ(RTC_HOURS);
-               day = CMOS_READ(RTC_DAY_OF_MONTH);
-               mon = CMOS_READ(RTC_MONTH);
-               year = CMOS_READ(RTC_YEAR);
-       } while (sec != CMOS_READ(RTC_SECONDS));
-
-       if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-               BCD_TO_BIN(sec);
-               BCD_TO_BIN(min);
-               BCD_TO_BIN(hour);
-               BCD_TO_BIN(day);
-               BCD_TO_BIN(mon);
-               BCD_TO_BIN(year);
-       }
-       if ((year += 1900) < 1970)
-               year += 100;
-       return mktime(year, mon, day, hour, min, sec);
-}
-
-/*
- * Set up timer interrupt, and return the current time in seconds.
- */
-extern __inline__ unsigned long setup_timer (void)
-{
-       unsigned int c;
-
-       /* Turn on the RTC */
-       outb(13, 0x70);
-       if ((inb(0x71) & 0x80) == 0)
-               printk("RTC: *** warning: CMOS battery bad\n");
-
-       outb(10, 0x70);         /* select control reg */
-       outb(32, 0x71);         /* make sure the divider is set */
-       outb(11, 0x70);         /* select other control reg */
-       c = inb(0x71) & 0xfb;   /* read it */
-       outb(11, 0x70);
-       outb(c | 2, 0x71);      /* turn on BCD counting and 24 hour clock mode */
-       
-       /* enable PIT timer */
-       /* set for periodic (4) and LSB/MSB write (0x30) */
-       outb(0x34, 0x43);
-       outb((mSEC_10_from_14/6) & 0xFF, 0x40);
-       outb((mSEC_10_from_14/6) >> 8, 0x40);
-
-       /*
-        * Default the date to 1 Jan 1970 00:00:00
-        * You will have to run a time daemon to set the
-        * clock correctly at bootup
-        */
-       return get_cmos_time();
-}
diff --git a/include/asm-arm/arch-vnc/timex.h b/include/asm-arm/arch-vnc/timex.h
deleted file mode 100644 (file)
index c50f118..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
- * linux/include/asm-arm/arch-vnc/timex.h
- *
- * Corel Video NC architecture timex specifications
- *
- * Copyright (C) 1998 Corel Computer/Russell King
- */
-
-/*
- * On the VNC, the clock runs at 66MHz and is divided
- * by a 4-bit prescaler.
- */
-#define CLOCK_TICK_RATE                (66000000 / 16)
diff --git a/include/asm-arm/arch-vnc/uncompress.h b/include/asm-arm/arch-vnc/uncompress.h
deleted file mode 100644 (file)
index d6097d4..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * linux/include/asm-arm/arch-ebsa110/uncompress.h
- *
- * Copyright (C) 1996,1997,1998 Russell King
- */
-
-/*
- * This does not append a newline
- */
-static void puts(const char *s)
-{
-       __asm__ __volatile__("
-       ldrb    %0, [%2], #1
-       teq     %0, #0
-       beq     3f
-1:     strb    %0, [%3]
-2:     ldrb    %1, [%3, #0x14]
-       and     %1, %1, #0x60
-       teq     %1, #0x60
-       bne     2b
-       teq     %0, #'\n'
-       moveq   %0, #'\r'
-       beq     1b
-       ldrb    %0, [%2], #1
-       teq     %0, #0
-       bne     1b
-3:     " : : "r" (0), "r" (0), "r" (s), "r" (0xf0000be0) : "cc");
-}
-
-/*
- * nothing to do
- */
-#define arch_decomp_setup()
-#define arch_decomp_wdog()
index 0facd0b7cfd5c6c670beb894f60e68151c573669..e7bfa21c42b06c694b7589a8a14e5894fb611b24 100644 (file)
 #define DC21285_PCI_MEM                        0x80000000
 
 #ifndef __ASSEMBLY__
-#define DC21285_IO(x)          ((volatile unsigned long *)(0xfe000000+(x)))
+#include <asm/arch/hardware.h>
+#define DC21285_IO(x)          ((volatile unsigned long *)(ARMCSR_BASE+(x)))
 #else
 #define DC21285_IO(x)          (x)
 #endif
 
 #define CSR_PCICMD             DC21285_IO(0x0004)
+#define CSR_CLASSREV           DC21285_IO(0x0008)
 #define CSR_PCICACHELINESIZE   DC21285_IO(0x000c)
 #define CSR_PCICSRBASE         DC21285_IO(0x0010)
 #define CSR_PCICSRIOBASE       DC21285_IO(0x0014)
 #define CSR_PCISDRAMBASE       DC21285_IO(0x0018)
 #define CSR_PCIROMBASE         DC21285_IO(0x0030)
+#define CSR_ROMWRITEREG                DC21285_IO(0x0068)
 #define CSR_CSRBASEMASK                DC21285_IO(0x00f8)
 #define CSR_CSRBASEOFFSET      DC21285_IO(0x00fc)
 #define CSR_SDRAMBASEMASK      DC21285_IO(0x0100)
 #define CSR_I2O_OUTPOSTCOUNT   DC21285_IO(0x0134)
 #define CSR_I2O_INPOSTCOUNT    DC21285_IO(0x0138)
 #define CSR_SA110_CNTL         DC21285_IO(0x013c)
+#define SA110_CNTL_INITCMPLETE         (1 << 0)
+#define SA110_CNTL_ASSERTSERR          (1 << 1)
+#define SA110_CNTL_RXSERR              (1 << 3)
+#define SA110_CNTL_SA110DRAMPARITY     (1 << 4)
+#define SA110_CNTL_PCISDRAMPARITY      (1 << 5)
+#define SA110_CNTL_DMASDRAMPARITY      (1 << 6)
+#define SA110_CNTL_DISCARDTIMER                (1 << 8)
+#define SA110_CNTL_PCINRESET           (1 << 9)
+#define SA110_CNTL_I2O_256             (0 << 10)
+#define SA110_CNTL_I20_512             (1 << 10)
+#define SA110_CNTL_I2O_1024            (2 << 10)
+#define SA110_CNTL_I2O_2048            (3 << 10)
+#define SA110_CNTL_I2O_4096            (4 << 10)
+#define SA110_CNTL_I2O_8192            (5 << 10)
+#define SA110_CNTL_I2O_16384           (6 << 10)
+#define SA110_CNTL_I2O_32768           (7 << 10)
+#define SA110_CNTL_WATCHDOG            (1 << 13)
+#define SA110_CNTL_ROMWIDTH_UNDEF      (0 << 14)
+#define SA110_CNTL_ROMWIDTH_16         (1 << 14)
+#define SA110_CNTL_ROMWIDTH_32         (2 << 14)
+#define SA110_CNTL_ROMWIDTH_8          (3 << 14)
+#define SA110_CNTL_ROMACCESSTIME(x)    ((x)<<16)
+#define SA110_CNTL_ROMBURSTTIME(x)     ((x)<<20)
+#define SA110_CNTL_ROMTRISTATETIME(x)  ((x)<<24)
+#define SA110_CNTL_XCSDIR(x)           ((x)<<28)
+#define SA110_CNTL_PCICFN              (1 << 31)
+
 #define CSR_PCIADDR_EXTN       DC21285_IO(0x0140)
 #define CSR_PREFETCHMEMRANGE   DC21285_IO(0x0144)
 #define CSR_XBUS_CYCLE         DC21285_IO(0x0148)
index 9fb7a0242aceddb7eb08f0d86321dc0ab4cbbc04..46d7cab0589d0d3dc844787017f452427d8fdec4 100644 (file)
@@ -6,20 +6,20 @@ typedef unsigned int dmach_t;
 #include <linux/config.h>
 #include <linux/kernel.h>
 #include <asm/irq.h>
-#include <asm/system.h>
 #include <asm/spinlock.h>
 #include <asm/arch/dma.h>
 
 /*
- * DMA modes - we have two, IN and OUT
+ * DMA modes
  */
 typedef unsigned int dmamode_t;
 
-#define DMA_MODE_MASK  1
+#define DMA_MODE_MASK  3
 
-#define DMA_MODE_READ  0
-#define DMA_MODE_WRITE 1
-#define DMA_AUTOINIT   2
+#define DMA_MODE_READ   0
+#define DMA_MODE_WRITE  1
+#define DMA_MODE_CASCADE 2
+#define DMA_AUTOINIT    4
 
 typedef struct {
        unsigned long address;
index 0f60505f95591b3f2d79887c2d4793ef5998a9b1..56ae7ab35d1c548c5d2bf9cb4ee7bbc71698b20c 100644 (file)
@@ -47,6 +47,9 @@
 #define MANU_ICS               0x003c
 #define PROD_ICS_IDE                   0x00ae
 
+#define MANU_ICS2              0x003d
+#define PROD_ICS2_IDE                  0x00ae
+
 #define MANU_SERPORT           0x003f
 #define PROD_SERPORT_DSPORT            0x00b9
 
@@ -76,7 +79,7 @@
 #define CONST const
 #endif
 
-#define MAX_ECARDS     8
+#define MAX_ECARDS     9
 
 typedef enum {                         /* Cards address space          */
        ECARD_IOC,
@@ -116,14 +119,18 @@ typedef unsigned long *loader_t;
 typedef struct {                       /* Card handler routines        */
        void (*irqenable)(ecard_t *ec, int irqnr);
        void (*irqdisable)(ecard_t *ec, int irqnr);
+       int  (*irqpending)(ecard_t *ec);
        void (*fiqenable)(ecard_t *ec, int fiqnr);
        void (*fiqdisable)(ecard_t *ec, int fiqnr);
+       int  (*fiqpending)(ecard_t *ec);
 } expansioncard_ops_t;
 
 /*
  * This contains all the info needed on an expansion card
  */
 struct expansion_card {
+       struct expansion_card  *next;
+
        /* Public data */
        volatile unsigned char *irqaddr;        /* address of IRQ register      */
        volatile unsigned char *fiqaddr;        /* address of FIQ register      */
@@ -135,10 +142,10 @@ struct expansion_card {
        void                    *fiq_data;      /* Data for use for FIQ by card */
        expansioncard_ops_t     *ops;           /* Enable/Disable Ops for card  */
 
-       CONST unsigned char     slot_no;        /* Slot number                  */
-       CONST unsigned char     dma;            /* DMA number (for request_dma) */
-       CONST unsigned char     irq;            /* IRQ number (for request_irq) */
-       CONST unsigned char     fiq;            /* FIQ number (for request_irq) */
+       CONST unsigned int      slot_no;        /* Slot number                  */
+       CONST unsigned int      dma;            /* DMA number (for request_dma) */
+       CONST unsigned int      irq;            /* IRQ number (for request_irq) */
+       CONST unsigned int      fiq;            /* FIQ number (for request_irq) */
        CONST card_type_t       type;           /* Type of card                 */
        CONST struct in_ecid    cid;            /* Card Identification          */
 
index 0516d115a672c8c04fa6dad41019173973b7c3cd..0e00841df351642a7d61fd585424994ea67ef046 100644 (file)
@@ -30,5 +30,6 @@ extern int claim_fiq(struct fiq_handler *f);
 extern void release_fiq(struct fiq_handler *f);
 extern void set_fiq_handler(void *start, unsigned int length);
 extern void set_fiq_regs(struct pt_regs *regs);
+extern void get_fiq_regs(struct pt_regs *regs);
 
 #endif
index 090ec21a95e3947ded060f900ed9d82fe7b25c07..9d98486440b831fd5c189362a5348e09cc4c3e4e 100644 (file)
@@ -120,5 +120,20 @@ static int FDC2 = -1;
 #define FLOPPY_MOTOR_MASK 0xf0
 
 #define CROSS_64KB(a,s) (0)
+
+/*
+ * This allows people to reverse the order of
+ * fd0 and fd1, in case their hardware is
+ * strangely connected (as some RiscPCs
+ * and A5000s seem to be).
+ */
+static void driveswap(int *ints, int dummy, int dummy2)
+{
+       floppy_selects[0][0] ^= floppy_selects[0][1];
+       floppy_selects[0][1] ^= floppy_selects[0][0];
+       floppy_selects[0][0] ^= floppy_selects[0][1];
+}
+
+#define EXTRA_FLOPPY_PARAMS ,{ "driveswap", &driveswap, NULL, 0, 0 }
        
 #endif
index cd4528235518e62fe37802c3e8884fc6a6a1dfb7..bc785422144f0ecd82e629d8dba111186ac3d4e1 100644 (file)
 
 #include <asm/arch/hardware.h>
 
-#ifndef FLUSH_BASE
-#define FLUSH_BASE     0xdf000000
-#endif
-
 #ifdef HAS_EXPMASK
 #ifndef __ASSEMBLER__
 #define __EXPMASK(offset)      (((volatile unsigned char *)EXPMASK_BASE)[offset])
index c0aa97f7fe0143087c1c5049cf1e7812300e2a36..66ccbecd32330f35531cf2925f7a38eba731a972 100644 (file)
@@ -5,7 +5,7 @@
 
 /* C routines */
 
-#ifdef CONFIG_TEXT_INIT_SECTION
+#ifdef CONFIG_TEXT_SECTIONS
 
 #define __init __attribute__ ((__section__ (".text.init")))
 #define __initfunc(__arginit) \
index e87744b7163147f891924d3a5bb190a80c7f69f5..35db8e667f056eb5247f096b20d32f97e783cc2d 100644 (file)
@@ -8,12 +8,35 @@
  *                     constant addresses and variable addresses.
  *  04-Dec-1997        RMK     Moved a lot of this stuff to the new architecture
  *                     specific IO header files.
+ *  27-Mar-1999        PJB     Second parameter of memcpy_toio is const..
+ *  04-Apr-1999        PJB     Added check_signature.
  */
 #ifndef __ASM_ARM_IO_H
 #define __ASM_ARM_IO_H
 
+#ifdef __KERNEL__
+
+#ifndef NULL
+#define NULL   ((void *) 0)
+#endif
+
+extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+
+/*
+ * String version of IO memory access ops:
+ */
+extern void _memcpy_fromio(void *, unsigned long, unsigned long);
+extern void _memcpy_toio(unsigned long, const void *, unsigned long);
+extern void _memset_io(unsigned long, int, unsigned long);
+
+#define memcpy_fromio(to,from,len)     _memcpy_fromio((to),(unsigned long)(from),(len))
+#define memcpy_toio(to,from,len)       _memcpy_toio((unsigned long)(to),(from),(len))
+#define memset_io(addr,c,len)          _memset_io((unsigned long)(addr),(c),(len))
+
+#endif
+
 #include <asm/hardware.h>
-#include <asm/arch/mmu.h>
+#include <asm/arch/memory.h>
 #include <asm/arch/io.h>
 #include <asm/proc/io.h>
 
@@ -168,25 +191,43 @@ __IO(l,"",long)
 
 #endif
 
-#undef ARCH_IO_DELAY
-#undef ARCH_IO_CONSTANT
+#ifndef ARCH_READWRITE
 
-#ifdef __KERNEL__
+/* for panic */
+#include <linux/kernel.h>
 
-extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
+#define readb(p)       (panic("readb called, but not implemented"),0)
+#define readw(p)       (panic("readw called, but not implemented"),0)
+#define readl(p)       (panic("readl called, but not implemented"),0)
+#define writeb(v,p)    panic("writeb called, but not implemented")
+#define writew(v,p)    panic("writew called, but not implemented")
+#define writel(v,p)    panic("writel called, but not implemented")
+
+#endif
 
 /*
- * String version of IO memory access ops:
+ * This isn't especially architecture dependent so it seems like it
+ * might as well go here as anywhere.
  */
-extern void _memcpy_fromio(void *, unsigned long, unsigned long);
-extern void _memcpy_toio(unsigned long, void *, unsigned long);
-extern void _memset_io(unsigned long, int, unsigned long);
-
-#define memcpy_fromio(to,from,len)     _memcpy_fromio((to),(unsigned long)(from),(len))
-#define memcpy_toio(to,from,len)       _memcpy_toio((unsigned long)(to),(from),(len))
-#define memset_io(addr,c,len)          _memset_io((unsigned long)(addr),(c),(len))
-
-#endif
+static inline int check_signature(unsigned long io_addr,
+                                  const unsigned char *signature, int length)
+{
+       int retval = 0;
+       do {
+               if (readb(io_addr) != *signature)
+                       goto out;
+               io_addr++;
+               signature++;
+               length--;
+       } while (length);
+       retval = 1;
+out:
+       return retval;
+}
+
+#undef ARCH_READWRITE
+#undef ARCH_IO_DELAY
+#undef ARCH_IO_CONSTANT
 
 #endif
 
index 2b3d6062aad128d73ff87adb39a6e5db9e230250..950046048e3066f4ee1dd52bd213c2525e99fcb5 100644 (file)
@@ -3,6 +3,8 @@
  * read/write.
  */
 
+#ifndef IOC_CONTROL
+
 #ifndef __ASSEMBLER__
 #define __IOC(offset)  (IOC_BASE + (offset >> 2))
 #else
@@ -54,3 +56,4 @@
 #define IOC_T3GO       __IOC(0x78)
 #define IOC_T3LATCH    __IOC(0x7c)
 
+#endif
index 375c6fdf1d2a6dc374d60a09a746da3f9b7d7441..31be445dade064dd80389e6d41d421255ad92e72 100644 (file)
 #define DMA_ST_OFL     4
 #define DMA_ST_INT     2
 #define DMA_ST_AB      1
+
+#ifndef IOC_CONTROL
 /*
  * IOC compatability
  */
 #define IOC_T1LTCHH    IOMD_T1LTCHH
 #define IOC_T1GO       IOMD_T1GO
 #define IOC_T1LATCH    IOMD_T1LATCH
+#endif
 
 /*
  * DMA (MEMC) compatability
index 0e8c4ad27bc979b4769c3aeb539e232efeccc0fd..9bdd7e00e6ed8e61cd262e6311fcd2ecdb8d0ffd 100644 (file)
  * capability
  */
 #ifndef NO_IRQ
-#define NO_IRQ 255
+#define NO_IRQ ((unsigned int)(-1))
 #endif
 
+#define disable_irq_nosync(i) disable_irq(i)
+
 extern void disable_irq(unsigned int);
 extern void enable_irq(unsigned int);
 
index f69aa7fce222e5d9595a4d3484f4ec1ede21240c..84a67f7679b95856156b74f0e8cc703e8a148f9a 100644 (file)
 #ifndef ASM_ARM_LEDS_H
 #define ASM_ARM_LEDS_H
 
+#include <linux/config.h>
+
 typedef enum {
        led_idle_start,
        led_idle_end,
        led_timer,
        led_start,
-       led_stop
+       led_stop,
+       led_claim,              /* override idle & timer leds */
+       led_release,            /* restore idle & timer leds */
+       led_green_on,
+       led_green_off,
+       led_amber_on,
+       led_amber_off,
+       led_red_on,
+       led_red_off
 } led_event_t;
 
 /* Use this routine to handle LEDs */
-extern void leds_event(led_event_t);
+
+#ifdef CONFIG_LEDS
+extern void (*leds_event)(led_event_t);
+#define set_leds_event(r)      leds_event = r
+#else
+#define leds_event(e)
+#define set_leds_event(r)
+#endif
 
 #endif
index 820738a29ee7b5c9533bb8a3e573fc055ac6ca06..8eea08635c732c0b54108ddc23451eecd9811512 100644 (file)
@@ -4,6 +4,9 @@
 #define VDMA_START     1
 #define VDMA_END       2
 
+#ifndef __ASSEMBLER__
+extern void memc_write(unsigned int reg, unsigned long val);
+
 #define video_set_dma(start,end,offset)                                \
 do {                                                           \
        memc_write (VDMA_START, (start >> 2));                  \
@@ -11,3 +14,4 @@ do {                                                          \
        memc_write (VDMA_INIT, (offset >> 2));                  \
 } while (0)
 
+#endif
diff --git a/include/asm-arm/mm-init.h b/include/asm-arm/mm-init.h
deleted file mode 100644 (file)
index 863e662..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * linux/include/asm-arm/mm-init.h
- *
- * Copyright (C) 1997,1998 Russell King
- *
- * Contained within are structures to describe how to set up the
- * initial memory map.  It includes both a processor-specific header
- * for parsing these structures, and an architecture-specific header
- * to fill out the structures.
- */
-#ifndef __ASM_MM_INIT_H
-#define __ASM_MM_INIT_H
-
-typedef enum {
-       // physical address is absolute
-       init_mem_map_absolute,
-       /* physical address is relative to start_mem
-        *  as passed in paging_init
-        */
-       init_mem_map_relative_start_mem
-} init_memmap_type_t;
-
-typedef struct {
-       init_memmap_type_t type;
-       unsigned long physical_address;
-       unsigned long virtual_address;
-       unsigned long size;
-} init_memmap_t;
-
-#define INIT_MEM_MAP_SENTINEL { init_mem_map_absolute, 0, 0, 0 }
-#define INIT_MEM_MAP_ABSOLUTE(p,l,s) { init_mem_map_absolute,p,l,s }
-#define INIT_MEM_MAP_RELATIVE(o,l,s) { init_mem_map_relative_start_mem,o,l,s }
-
-/*
- * Within this file, initialise an array of init_mem_map_t's
- * to describe your initial memory mapping structure.
- */
-#include <asm/arch/mm-init.h>
-
-/*
- * Contained within this file is code to read the array
- * of init_mem_map_t's created above.
- */
-#include <asm/proc/mm-init.h>
-
-#endif
index 810aa479ead50390ba6bf55a21eee1c6d8b7014b..704b99b05cda2b42692d296ca57a4dac8000e0f7 100644 (file)
@@ -1,15 +1,15 @@
 #ifndef _ASMARM_PAGE_H
 #define _ASMARM_PAGE_H
 
-#include <asm/arch/mmu.h>
+#include <asm/arch/memory.h>
 #include <asm/proc/page.h>
 
 #ifdef __KERNEL__
 
 #define get_user_page(vaddr)           __get_free_page(GFP_KERNEL)
 #define free_user_page(page, addr)     free_page(addr)
-#define clear_page(page)       memzero((void *)(page), PAGE_SIZE)
-#define copy_page(to,from)     memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+#define clear_page(page)               memzero((void *)(page), PAGE_SIZE)
+#define copy_page(to,from)             memcpy((void *)(to), (void *)(from), PAGE_SIZE)
 
 #endif
 
index 4c02ac5feab61494f4489d4387f1477a41e1a391..102be60dfc3cc39d787a1d8ff5b56bfbc2e388ee 100644 (file)
@@ -45,6 +45,8 @@ typedef struct {
 #endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
 } __kernel_fsid_t;
 
+#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+
 #undef __FD_SET
 #define __FD_SET(fd, fdsetp) \
                (((fd_set *)fdsetp)->fds_bits[fd >> 5] |= (1<<(fd & 31)))
@@ -62,3 +64,5 @@ typedef struct {
                (memset (fdsetp, 0, sizeof (*(fd_set *)fdsetp)))
 
 #endif
+
+#endif
diff --git a/include/asm-arm/proc-armo/mm-init-flat.h b/include/asm-arm/proc-armo/mm-init-flat.h
deleted file mode 100644 (file)
index 919ef59..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/mmap.h
- *
- * Copyright (C) 1996 Russell King
- *
- * This contains the code to setup the memory map on an ARM2/ARM250/ARM3
- * machine. This is both processor & architecture specific, and requires
- * some more work to get it to fit into our separate processor and
- * architecture structure.
- */
-
-static unsigned long phys_screen_end;
-int page_nr;
-
-#define setup_processor_functions()
-
-/*
- * This routine needs more work to make it dynamically release/allocate mem!
- */
-unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update)
-{
-       static int updated = 0;
-       unsigned long address = SCREEN_START, i;
-       pgd_t *pg_dir;
-       pmd_t *pm_dir;
-       pte_t *pt_entry;
-
-       if (updated)
-               return 0;
-       updated = update;
-
-       pg_dir = swapper_pg_dir + (SCREEN1_BASE >> PGDIR_SHIFT);
-       pm_dir = pmd_offset(pg_dir, SCREEN1_BASE);
-       pt_entry = pte_offset(pm_dir, SCREEN1_BASE);
-
-       for (i = SCREEN1_BASE; i < SCREEN1_END; i += PAGE_SIZE) {
-               if (i >= log_start) {
-                       *pt_entry = mk_pte(address, __pgprot(_PAGE_PRESENT));
-                       address += PAGE_SIZE;
-               } else
-                       *pt_entry = mk_pte(0, __pgprot(0));
-               pt_entry++;
-       }
-       phys_screen_end = address;
-       if (update)
-               flush_tlb_all ();
-       return kmem;
-}
-
-static inline unsigned long setup_pagetables(unsigned long start_mem, unsigned long end_mem)
-{
-       unsigned long address;
-       unsigned int spi;
-
-       page_nr = MAP_NR(end_mem);
-
-       /* Allocate zero page */
-       address = PAGE_OFFSET + 480*1024;
-       for (spi = 0; spi < 32768 >> PAGE_SHIFT; spi++) {
-               pgd_val(swapper_pg_dir[spi]) = pte_val(mk_pte(address, PAGE_READONLY));
-               address += PAGE_SIZE;
-       }
-
-       while (spi < (PAGE_OFFSET >> PGDIR_SHIFT))
-               pgd_val(swapper_pg_dir[spi++]) = 0;
-
-       map_screen_mem (SCREEN1_END - 480*1024, 0, 0);
-       return start_mem;
-}
-
-static inline void mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem)
-{
-       unsigned long smem = PAGE_ALIGN(*start_mem);
-
-       while (smem < end_mem) {
-               clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
-               smem += PAGE_SIZE;
-       }
-
-       for (smem = phys_screen_end; smem < SCREEN2_END; smem += PAGE_SIZE)
-               clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
-}
index ba4db9e82b029025a9e3d7ccb7e1b4fb6f2f7baa..ce0fd84e656c1faa78aec9c5030c6333c57e069d 100644 (file)
@@ -8,8 +8,8 @@
  * some more work to get it to fit into our separate processor and
  * architecture structure.
  */
-extern unsigned long phys_screen_end;
-extern unsigned long map_screen_mem(unsigned long log_start, unsigned long kmem, int update);
+#include <asm/arch/memory.h>
+
 int page_nr;
 
 #define setup_processor_functions()
@@ -20,10 +20,11 @@ static inline void setup_swapper_dir (int index, pte_t *ptep)
        set_pmd (pmd_offset (swapper_pg_dir + index, 0), mk_pmd (ptep));
 }
 
-static inline unsigned long setup_pagetables(unsigned long start_mem, unsigned long end_mem)
+static inline unsigned long
+setup_pagetables(unsigned long start_mem, unsigned long end_mem)
 {
        unsigned int i;
-       union {unsigned long l; pte_t *pte; } u;
+       union { unsigned long l; pte_t *pte; } u;
 
        page_nr = MAP_NR(end_mem);
 
@@ -37,14 +38,11 @@ static inline unsigned long setup_pagetables(unsigned long start_mem, unsigned l
        for (i = 1; i < PTRS_PER_PGD; i++)
                pgd_val(swapper_pg_dir[i]) = 0;
 
-       /* now map screen mem in */
-       phys_screen_end = SCREEN2_END;
-       map_screen_mem (SCREEN1_END - 480*1024, 0, 0);
-
        return start_mem;
 }
 
-static inline void mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem)
+static inline void
+mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem)
 {
        unsigned long smem;
 
@@ -54,7 +52,4 @@ static inline void mark_usable_memory_areas(unsigned long *start_mem, unsigned l
                clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
                smem += PAGE_SIZE;
        }
-
-       for (smem = phys_screen_end; smem < SCREEN2_END; smem += PAGE_SIZE)
-               clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
 }
index 0e2b4501ccbae1e54b52cc9390a6111bb58ee98a..3768284a291980433661916bbfe3ae476d89f2ea 100644 (file)
@@ -68,7 +68,6 @@ typedef unsigned long pgprot_t;
 #define PAGE_ALIGN(addr)       (((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
 /* This handles the memory map.. */
-#define PAGE_OFFSET            0x02000000
 #define MAP_NR(addr)           (((unsigned long)(addr) - PAGE_OFFSET) >> PAGE_SHIFT)
 
 #endif /* __KERNEL__ */
diff --git a/include/asm-arm/proc-armo/pgtable-flat.h b/include/asm-arm/proc-armo/pgtable-flat.h
deleted file mode 100644 (file)
index 994fa9f..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * linux/include/asm-arm/proc-armo/pgtable.h
- *
- * Copyright (C) 1995, 1996 Russell King
- */
-#ifndef __ASM_PROC_PGTABLE_H
-#define __ASM_PROC_PGTABLE_H
-
-#include <asm/arch/mmu.h>
-
-#define LIBRARY_TEXT_START 0x0c000000
-
-/*
- * Cache flushing...
- */
-#define flush_cache_all()                      do { } while (0)
-#define flush_cache_mm(mm)                     do { } while (0)
-#define flush_cache_range(mm,start,end)                do { } while (0)
-#define flush_cache_page(vma,vmaddr)           do { } while (0)
-#define flush_page_to_ram(page)                        do { } while (0)
-
-/*
- * TLB flushing:
- *
- *  - flush_tlb() flushes the current mm struct TLBs
- *  - flush_tlb_all() flushes all processes TLBs
- *  - flush_tlb_mm(mm) flushes the specified mm context TLB's
- *  - flush_tlb_page(vma, vmaddr) flushes one page
- *  - flush_tlb_range(mm, start, end) flushes a range of pages
- */
-
-#define flush_tlb() flush_tlb_mm(current->mm)
-
-extern __inline__ void flush_tlb_all(void)
-{
-       struct task_struct *p;
-
-       p = &init_task;
-       do {
-               processor.u.armv2._update_map(p);
-               p = p->next_task;
-       } while (p != &init_task);
-
-       processor.u.armv2._remap_memc (current);
-}
-
-extern __inline__ void flush_tlb_mm(struct mm_struct *mm)
-{
-       struct task_struct *p;
-
-       p = &init_task;
-       do {
-               if (p->mm == mm)
-                       processor.u.armv2._update_map(p);
-               p = p->next_task;
-       } while (p != &init_task);
-
-       if (current->mm == mm)
-               processor.u.armv2._remap_memc (current);
-}
-
-#define flush_tlb_range(mm, start, end) flush_tlb_mm(mm)
-#define flush_tlb_page(vma, vmaddr) flush_tlb_mm(vma->vm_mm)
-
-#define __flush_entry_to_ram(entry)
-
-/* Certain architectures need to do special things when pte's
- * within a page table are directly modified.  Thus, the following
- * hook is made available.
- */
-#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
-
-/* PMD_SHIFT determines the size of the area a second-level page table can map */
-#define PMD_SHIFT       PAGE_SHIFT
-#define PMD_SIZE        (1UL << PMD_SHIFT)
-#define PMD_MASK        (~(PMD_SIZE-1))
-
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
-#define PGDIR_SHIFT     PAGE_SHIFT
-#define PGDIR_SIZE      (1UL << PGDIR_SHIFT)
-#define PGDIR_MASK      (~(PGDIR_SIZE-1))
-
-/*
- * entries per page directory level: the arm3 is one-level, so
- * we don't really have any PMD or PTE directory physically.
- */
-#define PTRS_PER_PTE    1
-#define PTRS_PER_PMD    1
-#define PTRS_PER_PGD    1024
-
-/* Just any arbitrary offset to the start of the vmalloc VM area: the
- * current 8MB value just means that there will be a 8MB "hole" after the
- * physical memory until the kernel virtual memory starts.  That means that
- * any out-of-bounds memory accesses will hopefully be caught.
- * The vmalloc() routines leaves a hole of 4kB between each vmalloced
- * area for the same reason. ;)
- */
-#define VMALLOC_START  0x01a00000
-#define VMALLOC_VMADDR(x) ((unsigned long)(x))
-
-#define _PAGE_PRESENT   0x001
-#define _PAGE_RW        0x002
-#define _PAGE_USER      0x004
-#define _PAGE_PCD       0x010
-#define _PAGE_ACCESSED  0x020
-#define _PAGE_DIRTY     0x040
-
-#define _PAGE_TABLE     (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
-#define _PAGE_CHG_MASK  (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
-
-#define PAGE_NONE       __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
-#define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_COPY       __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_READONLY   __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
-#define PAGE_KERNEL     __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
-
-/*
- * The arm can't do page protection for execute, and considers that the same are read.
- * Also, write permissions imply read permissions. This is the closest we can get..
- */
-#define __P000  PAGE_NONE
-#define __P001  PAGE_READONLY
-#define __P010  PAGE_COPY
-#define __P011  PAGE_COPY
-#define __P100  PAGE_READONLY
-#define __P101  PAGE_READONLY
-#define __P110  PAGE_COPY
-#define __P111  PAGE_COPY
-
-#define __S000  PAGE_NONE
-#define __S001  PAGE_READONLY
-#define __S010  PAGE_SHARED
-#define __S011  PAGE_SHARED
-#define __S100  PAGE_READONLY
-#define __S101  PAGE_READONLY
-#define __S110  PAGE_SHARED
-#define __S111  PAGE_SHARED
-
-#undef TEST_VERIFY_AREA
-
-/*
- * BAD_PAGE is used for a bogus page.
- *
- * ZERO_PAGE is a global shared page that is always zero: used
- * for zero-mapped memory areas etc..
- */
-extern pte_t __bad_page(void);
-extern unsigned long *empty_zero_page;
-
-#define BAD_PAGE __bad_page()
-#define ZERO_PAGE ((unsigned long) empty_zero_page)
-
-/* number of bits that fit into a memory pointer */
-#define BYTES_PER_PTR                  (sizeof(unsigned long))
-#define BITS_PER_PTR                    (8*BYTES_PER_PTR)
-
-/* to align the pointer to a pointer address */
-#define PTR_MASK                        (~(sizeof(void*)-1))
-
-/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
-#define SIZEOF_PTR_LOG2                 2
-
-/* to find an entry in a page-table */
-#define PAGE_PTR(address) \
-((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
-
-/* to set the page-dir */
-#define SET_PAGE_DIR(tsk,pgdir)                                                \
-do {                                                                   \
-       tsk->tss.memmap = (unsigned long)pgdir;                         \
-       processor.u.armv2._update_map(tsk);                             \
-       if ((tsk) == current)                                           \
-               processor.u.armv2._remap_memc (current);                \
-} while (0)
-
-extern unsigned long physical_start;
-extern unsigned long physical_end;
-
-extern inline int pte_none(pte_t pte)           { return !pte_val(pte); }
-extern inline int pte_present(pte_t pte)        { return pte_val(pte) & _PAGE_PRESENT; }
-extern inline void pte_clear(pte_t *ptep)       { pte_val(*ptep) = 0; }
-
-extern inline int pmd_none(pmd_t pmd)           { return 0; }
-extern inline int pmd_bad(pmd_t pmd)            { return 0; }
-extern inline int pmd_present(pmd_t pmd)        { return 1; }
-extern inline void pmd_clear(pmd_t * pmdp)      { }
-
-/*
- * The "pgd_xxx()" functions here are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
- */
-extern inline int pgd_none(pgd_t pgd)           { return 0; }
-extern inline int pgd_bad(pgd_t pgd)            { return 0; }
-extern inline int pgd_present(pgd_t pgd)        { return 1; }
-extern inline void pgd_clear(pgd_t * pgdp)      { }
-
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-extern inline int pte_read(pte_t pte)           { return pte_val(pte) & _PAGE_USER; }
-extern inline int pte_write(pte_t pte)          { return pte_val(pte) & _PAGE_RW; }
-extern inline int pte_exec(pte_t pte)           { return pte_val(pte) & _PAGE_USER; }
-extern inline int pte_dirty(pte_t pte)          { return pte_val(pte) & _PAGE_DIRTY; }
-extern inline int pte_young(pte_t pte)          { return pte_val(pte) & _PAGE_ACCESSED; }
-#define pte_cacheable(pte) 1
-
-extern inline pte_t pte_nocache(pte_t pte)     { return pte; }
-extern inline pte_t pte_wrprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_RW; return pte; }
-extern inline pte_t pte_rdprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_USER; return pte; }
-extern inline pte_t pte_exprotect(pte_t pte)    { pte_val(pte) &= ~_PAGE_USER; return pte; }
-extern inline pte_t pte_mkclean(pte_t pte)      { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkold(pte_t pte)        { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
-extern inline pte_t pte_mkwrite(pte_t pte)      { pte_val(pte) |= _PAGE_RW; return pte; }
-extern inline pte_t pte_mkread(pte_t pte)       { pte_val(pte) |= _PAGE_USER; return pte; }
-extern inline pte_t pte_mkexec(pte_t pte)       { pte_val(pte) |= _PAGE_USER; return pte; }
-extern inline pte_t pte_mkdirty(pte_t pte)      { pte_val(pte) |= _PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkyoung(pte_t pte)      { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
-
-/*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
- */
-extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
-{ pte_t pte; pte_val(pte) = virt_to_phys(page) | pgprot_val(pgprot); return pte; }
-
-extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; }
-
-extern inline unsigned long pte_page(pte_t pte)
-{ return phys_to_virt(pte_val(pte) & PAGE_MASK); }
-
-extern inline unsigned long pmd_page(pmd_t pmd)
-{ return phys_to_virt(pmd_val(pmd) & PAGE_MASK); }
-
-/* to find an entry in a page-table-directory */
-extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
-{
-        return mm->pgd + (address >> PGDIR_SHIFT);
-}
-
-/* Find an entry in the second-level page table.. */
-#define pmd_offset(dir, address) ((pmd_t *)(dir))
-
-/* Find an entry in the third-level page table.. */
-#define pte_offset(dir, address) ((pte_t *)(dir))
-
-/*
- * Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any.
- */
-extern inline void pte_free_kernel(pte_t * pte)
-{
-       pte_val(*pte) = 0;
-}
-
-extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address)
-{
-       return (pte_t *) pmd;
-}
-
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-#define pmd_free_kernel(pmdp)
-#define pmd_alloc_kernel(pgd,address) ((pmd_t *)(pgd))
-
-#define pte_free(ptep)
-#define pte_alloc(pmd,address) ((pte_t *)(pmd))
-
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-#define pmd_free(pmd)
-#define pmd_alloc(pgd,address) ((pmd_t *)(pgd))
-
-extern inline void pgd_free(pgd_t * pgd)
-{
-       extern void kfree(void *);
-       kfree((void *)pgd);
-}
-
-extern inline pgd_t * pgd_alloc(void)
-{
-       pgd_t *pgd;
-       extern void *kmalloc(unsigned int, int);
-       
-       pgd = (pgd_t *) kmalloc(PTRS_PER_PGD * BYTES_PER_PTR, GFP_KERNEL);
-       if (pgd)
-               memset(pgd, 0, PTRS_PER_PGD * BYTES_PER_PTR);
-       return pgd;
-}
-
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-
-#define update_mmu_cache(vma,address,pte) processor.u.armv2._update_mmu_cache(vma,address,pte)
-
-#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
-#define SWP_OFFSET(entry) ((entry) >> 8)
-#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) <<  8))
-
-#endif /* __ASM_PROC_PAGE_H */
-
index 934902052a5d406785e366fbc1bd13779fb84d6f..04516e7296faf78e56b0bd5740454075eb3d5050 100644 (file)
@@ -7,9 +7,9 @@
 #ifndef __ASM_PROC_PGTABLE_H
 #define __ASM_PROC_PGTABLE_H
 
-#include <asm/arch/mmu.h>
+#include <linux/config.h>
 #include <linux/slab.h>
-#include <asm/arch/processor.h>                /* For TASK_SIZE */
+#include <asm/arch/memory.h>           /* For TASK_SIZE */
 
 #define LIBRARY_TEXT_START 0x0c000000
 
@@ -280,13 +280,17 @@ extern __inline__ unsigned long pte_page(pte_t pte)
        return __phys_to_virt(pte_val(pte) & PAGE_MASK);
 }
 
-extern __inline__ pmd_t mk_pmd (pte_t *ptep)
+extern __inline__ pmd_t mk_pmd(pte_t *ptep)
 {
        pmd_t pmd;
        pmd_val(pmd) = __virt_to_phys((unsigned long)ptep) | _PAGE_TABLE;
        return pmd;
 }
 
+/* these are aliases for the above function */
+#define mk_user_pmd(ptep)   mk_pmd(ptep)
+#define mk_kernel_pmd(ptep) mk_pmd(ptep)
+
 #define set_pmd(pmdp,pmd) ((*(pmdp)) = (pmd))
 
 extern __inline__ unsigned long pmd_page(pmd_t pmd)
@@ -319,6 +323,7 @@ extern __inline__ pte_t * pte_offset(pmd_t *dir, unsigned long address)
  */
 
 #ifndef __SMP__
+#ifndef CONFIG_NO_PGT_CACHE
 extern struct pgtable_cache_struct {
        unsigned long *pgd_cache;
        unsigned long *pte_cache;
@@ -329,13 +334,16 @@ extern struct pgtable_cache_struct {
 #define pte_quicklist (quicklists.pte_cache)
 #define pgd_quicklist (quicklists.pgd_cache)
 #define pgtable_cache_size (quicklists.pgtable_cache_sz)
+#endif
 
 #else
 #error Pgtable caches have to be per-CPU, so that no locking is needed.
 #endif
 
 extern pgd_t *get_pgd_slow(void);
+extern void free_table(void *table);
 
+#ifndef CONFIG_NO_PGT_CACHE
 extern __inline__ pgd_t *get_pgd_fast(void)
 {
        unsigned long *ret;
@@ -355,14 +363,17 @@ extern __inline__ void free_pgd_fast(pgd_t *pgd)
        pgd_quicklist = (unsigned long *) pgd;
        pgtable_cache_size++;
 }
+#endif
 
+/* keep this as an inline so we get type checking */
 extern __inline__ void free_pgd_slow(pgd_t *pgd)
 {
-       kfree(pgd);
+       free_table((void *)pgd);
 }
 
 extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
 
+#ifndef CONFIG_NO_PGT_CACHE
 extern __inline__ pte_t *get_pte_fast(void)
 {
        unsigned long *ret;
@@ -381,10 +392,12 @@ extern __inline__ void free_pte_fast(pte_t *pte)
        pte_quicklist = (unsigned long *) pte;
        pgtable_cache_size++;
 }
+#endif
 
+/* keep this as an inline so we get type checking */
 extern __inline__ void free_pte_slow(pte_t *pte)
 {
-       kfree(pte);
+       free_table((void *)pte);
 }
 
 /* We don't use pmd cache, so this is a dummy routine */
@@ -404,6 +417,26 @@ extern __inline__ void free_pmd_slow(pmd_t *pmd)
 extern void __bad_pmd(pmd_t *pmd);
 extern void __bad_pmd_kernel(pmd_t *pmd);
 
+#ifdef CONFIG_NO_PGT_CACHE
+#define pte_free_kernel(pte)    free_pte_slow(pte)
+#define pte_free(pte)           free_pte_slow(pte)
+#define pgd_free(pgd)           free_pgd_slow(pgd)
+#define pgd_alloc()             get_pgd_slow()
+
+extern __inline__ pte_t *pte_alloc(pmd_t * pmd, unsigned long address)
+{
+       address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+
+       if (pmd_none (*pmd)) {
+               return get_pte_slow(pmd, address);
+       }
+       if (pmd_bad (*pmd)) {
+               __bad_pmd(pmd);
+               return NULL;
+       }
+       return (pte_t *) pmd_page(*pmd) + address;
+}
+#else
 #define pte_free_kernel(pte)    free_pte_fast(pte)
 #define pte_free(pte)           free_pte_fast(pte)
 #define pgd_free(pgd)           free_pgd_fast(pgd)
@@ -427,6 +460,7 @@ extern __inline__ pte_t *pte_alloc(pmd_t * pmd, unsigned long address)
        }
        return (pte_t *) pmd_page(*pmd) + address;
 }
+#endif
 
 /*
  * allocating and freeing a pmd is trivial: the 1-entry pmd is
@@ -448,7 +482,6 @@ extern __inline__ pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
 extern __inline__ void set_pgdir(unsigned long address, pgd_t entry)
 {
        struct task_struct * p;
-       pgd_t *pgd;
 
        read_lock(&tasklist_lock);
        for_each_task(p) {
@@ -457,8 +490,14 @@ extern __inline__ void set_pgdir(unsigned long address, pgd_t entry)
                *pgd_offset(p->mm,address) = entry;
        }
        read_unlock(&tasklist_lock);
-       for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
-               pgd[address >> PGDIR_SHIFT] = entry;
+#ifndef CONFIG_NO_PGT_CACHE
+       {
+               pgd_t *pgd;
+               for (pgd = (pgd_t *)pgd_quicklist; pgd;
+                    pgd = (pgd_t *)*(unsigned long *)pgd)
+                       pgd[address >> PGDIR_SHIFT] = entry;
+       }
+#endif
 }
 
 extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
index 4a8b60d104501fd7da714bf1f13632383ddc974d..4cfd77955d04c5ca14a2af73a55e2dd63b0ab8b5 100644 (file)
@@ -14,8 +14,6 @@
 #ifndef __ASM_PROC_PROCESSOR_H
 #define __ASM_PROC_PROCESSOR_H
 
-#ifdef __KERNEL__
-
 #include <asm/assembler.h>
 #include <linux/string.h>
 
@@ -32,6 +30,8 @@ struct context_save_struct {
        unsigned long pc;
 };
 
+#define INIT_CSS (struct context_save_struct){ 0, 0, 0, 0, 0, 0, 0, SVC26_MODE }
+
 typedef struct {
        void (*put_byte)(void);                 /* Special calling convention */
        void (*get_byte)(void);                 /* Special calling convention */
@@ -50,50 +50,13 @@ extern uaccess_t uaccess_user, uaccess_kernel;
 
 #define EXTRA_THREAD_STRUCT                                                    \
        uaccess_t       *uaccess;               /* User access functions*/      \
-       struct context_save_struct *save;                                       \
-       unsigned long   memmap;                                                 \
        unsigned long   memcmap[256];
 
 #define EXTRA_THREAD_STRUCT_INIT               \
-       &uaccess_kernel,                        \
-       0,                                      \
-       (unsigned long) swapper_pg_dir,         \
+       ,&uaccess_kernel,                       \
        { 0, }
 
-DECLARE_THREAD_STRUCT;
-
-/*
- * Return saved PC of a blocked thread.
- */
-extern __inline__ unsigned long thread_saved_pc (struct thread_struct *t)
-{
-       if (t->save)
-               return t->save->pc & ~PCMASK;
-       else
-               return 0;
-}
-
-extern __inline__ unsigned long get_css_fp (struct thread_struct *t)
-{
-       if (t->save)
-               return t->save->fp;
-       else
-               return 0;
-}
-
-asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
-
-extern __inline__ void copy_thread_css (struct context_save_struct *save)
-{
-       save->r4 =
-       save->r5 =
-       save->r6 =
-       save->r7 =
-       save->r8 =
-       save->r9 =
-       save->fp = 0;
-       save->pc = ((unsigned long)ret_from_sys_call) | SVC26_MODE;
-}
+#define SWAPPER_PG_DIR ((unsigned long)swapper_pg_dir)
 
 #define start_thread(regs,pc,sp)                                       \
 ({                                                                     \
@@ -105,18 +68,16 @@ extern __inline__ void copy_thread_css (struct context_save_struct *save)
        regs->ARM_r2 = stack[2];        /* r2 (envp) */                 \
        regs->ARM_r1 = stack[1];        /* r1 (argv) */                 \
        regs->ARM_r0 = stack[0];        /* r0 (argc) */                 \
-       flush_tlb_mm(current->mm);                                      \
 })
 
 /* Allocation and freeing of basic task resources. */
 /*
  * NOTE! The task struct and the stack go together
  */
-#define alloc_task_struct() \
-       ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
-#define free_task_struct(p)    free_pages((unsigned long)(p),1)
+extern unsigned long get_page_8k(int priority);
+extern void free_page_8k(unsigned long page);
 
-
-#endif
+#define ll_alloc_task_struct() ((struct task_struct *)get_page_8k(GFP_KERNEL))
+#define ll_free_task_struct(p)  free_page_8k((unsigned long)(p))
 
 #endif
index 30a05ecdcc9ad02b55c83881f900d035886726b1..f53aa229d65421f75b28b28d407ec6b520e7ac6e 100644 (file)
@@ -68,8 +68,13 @@ struct pt_regs {
 /* Are the current registers suitable for user mode?
  * (used to maintain security in signal handlers)
  */
-#define valid_user_regs(regs) \
-       (user_mode(regs) && ((regs)->ARM_sp & 3) == 0)
+static inline int valid_user_regs(struct pt_regs *regs)
+{
+       if (!user_mode(regs) || regs->ARM_pc & (F_BIT | I_BIT))
+               return 1;
+
+       return 0;
+}
 
 #endif
 
index 48380321736441597d6f9778835477bd7ecdf7cd..9cd99cf50dc09e360033411158bf7de26fe382d8 100644 (file)
@@ -13,17 +13,19 @@ extern inline void down(struct semaphore * sem)
        __asm__ __volatile__ ("
        @ atomic down operation
        mov     r0, pc
-       orr     r1, r0, #0x08000000
+       orr     lr, r0, #0x08000000
        and     r0, r0, #0x0c000003
-       teqp    r1, #0
-       ldr     r1, [%0]
-       subs    r1, r1, #1
-       str     r1, [%0]
-       mov     r1, pc, lsr #28
-       teqp    r0, r1, lsl #28
+       teqp    lr, #0
+       ldr     lr, [%0]
+       subs    lr, lr, #1
+       str     lr, [%0]
+       mov     lr, pc, lsr #28
+       teqp    r0, lr, lsl #28
        movmi   r0, %0
-       blmi    " SYMBOL_NAME_STR(__down)
-               : : "r" (sem) : "r0", "r1", "r2", "r3", "ip", "lr", "cc");
+       blmi    " SYMBOL_NAME_STR(__down_failed)
+               :
+               : "r" (sem)
+               : "r0", "lr", "cc");
 }
 
 /*
@@ -36,22 +38,47 @@ extern inline int down_interruptible (struct semaphore * sem)
        __asm__ __volatile__ ("
        @ atomic down operation
        mov     r0, pc
-       orr     r1, r0, #0x08000000
+       orr     lr, r0, #0x08000000
        and     r0, r0, #0x0c000003
-       teqp    r1, #0
-       ldr     r1, [%1]
-       subs    r1, r1, #1
-       str     r1, [%1]
-       mov     r1, pc, lsr #28
+       teqp    lr, #0
+       ldr     lr, [%1]
+       subs    lr, lr, #1
+       str     lr, [%1]
+       mov     lr, pc, lsr #28
        orrmi   r0, r0, #0x80000000     @ set N
-       teqp    r0, r1, lsl #28
+       teqp    r0, lr, lsl #28
        movmi   r0, %1
        movpl   r0, #0
-       blmi    " SYMBOL_NAME_STR(__down_interruptible) "
+       blmi    " SYMBOL_NAME_STR(__down_interruptible_failed) "
        mov     %0, r0"
                : "=r" (result)
                : "r" (sem)
-               : "r0", "r1", "r2", "r3", "ip", "lr", "cc");
+               : "r0", "lr", "cc");
+       return result;
+}
+
+extern inline int down_trylock(struct semaphore * sem)
+{
+       int result;
+       __asm__ __volatile__ ("
+       @ atomic down operation
+       mov     r0, pc
+       orr     lr, r0, #0x08000000
+       and     r0, r0, #0x0c000003
+       teqp    lr, #0
+       ldr     lr, [%1]
+       subs    lr, lr, #1
+       str     lr, [%1]
+       mov     lr, pc, lsr #28
+       orrmi   r0, r0, #0x80000000     @ set N
+       teqp    r0, lr, lsl #28
+       movmi   r0, %1
+       movpl   r0, #0
+       blmi    " SYMBOL_NAME_STR(__down_trylock_failed) "
+       mov     %0, r0"
+               : "=r" (result)
+               : "r" (sem)
+               : "r0", "lr", "cc");
        return result;
 }
 
@@ -66,18 +93,20 @@ extern inline void up(struct semaphore * sem)
        __asm__ __volatile__ ("
        @ atomic up operation
        mov     r0, pc
-       orr     r1, r0, #0x08000000
+       orr     lr, r0, #0x08000000
        and     r0, r0, #0x0c000003
-       teqp    r1, #0
-       ldr     r1, [%0]
-       adds    r1, r1, #1
-       str     r1, [%0]
-       mov     r1, pc, lsr #28
+       teqp    lr, #0
+       ldr     lr, [%0]
+       adds    lr, lr, #1
+       str     lr, [%0]
+       mov     lr, pc, lsr #28
        orrls   r0, r0, #0x80000000     @ set N
-       teqp    r0, r1, lsl #28
+       teqp    r0, lr, lsl #28
        movmi   r0, %0
-       blmi    " SYMBOL_NAME_STR(__up)
-               : : "r" (sem) : "r0", "r1", "r2", "r3", "ip", "lr", "cc");
+       blmi    " SYMBOL_NAME_STR(__up_wakeup)
+               :
+               : "r" (sem)
+               : "r0", "lr", "cc");
 }
 
 #endif
index 461da303f73e1b8d6945464780a4c8814a48af2e..8afecd2a5037614277a0a5f9fc6f63fbfcab7699 100644 (file)
 
 #include <asm/proc-fns.h>
 
-extern inline void dma_cache_inv(unsigned long start, unsigned long size)
-{
-       processor.u.armv3v4._cache_purge_area(start, start + size);
-}
+#define dma_cache_inv(start, size)                                         \
+       do { processor.u.armv3v4._cache_purge_area((unsigned long)(start),  \
+               ((unsigned long)(start)+(size))); } while (0)
 
-extern inline void dma_cache_wback(unsigned long start, unsigned long size)
-{
-       processor.u.armv3v4._cache_wback_area(start, start + size);
-}
+#define dma_cache_wback(start, size)                                       \
+       do { processor.u.armv3v4._cache_wback_area((unsigned long)(start),  \
+               ((unsigned long)(start)+(size))); } while (0)
 
-extern inline void dma_cache_wback_inv(unsigned long start, unsigned long size)
-{
-       processor.u.armv3v4._flush_cache_area(start, start + size, 0);
-}
+#define dma_cache_wback_inv(start, size)                                   \
+       do { processor.u.armv3v4._flush_cache_area((unsigned long)(start),  \
+               ((unsigned long)(start)+(size)), 0); } while (0)
index a3f5c327f13b4780902bc14a8966b2ebd8e2be74..a07e9a50e8ac6ae1e8ce816fb1199d2933ceddc0 100644 (file)
@@ -37,7 +37,7 @@
  */
 #include <asm/pgtable.h>
  
-#define PTE_SIZE (PTRS_PER_PTE * 4)
+#define PTE_SIZE (PTRS_PER_PTE * BYTES_PER_PTR)
 
 extern unsigned long setup_io_pagetables(unsigned long start_mem);
 
@@ -79,7 +79,7 @@ static inline void
 alloc_init_page(unsigned long *mem, unsigned long virt, unsigned long phys, int domain, int prot)
 {
        pgd_t *pgdp;
-       pmd_t *pmdp, pmd;
+       pmd_t *pmdp;
        pte_t *ptep;
 
        pgdp = pgd_offset_k(virt);
@@ -92,46 +92,41 @@ alloc_init_page(unsigned long *mem, unsigned long virt, unsigned long phys, int
 
                ptep = (pte_t *)memory;
                memzero(ptep, PTE_SIZE);
+               memory += PTE_SIZE;
 
-               pmd_val(pmd) = __virt_to_phys(memory) | PMD_TYPE_TABLE | PMD_DOMAIN(domain);
-               set_pmd(pmdp, pmd);
+               ptep = (pte_t *)memory;
+               memzero(ptep, PTE_SIZE);
+
+               set_pmd(pmdp, __mk_pmd(ptep, PMD_TYPE_TABLE | PMD_DOMAIN(domain)));
 
                *mem = memory + PTE_SIZE;
        }
 
        ptep = pte_offset(pmdp, virt);
 
-       pte_val(*ptep) = phys | prot | PTE_TYPE_SMALL;
+       set_pte(ptep, mk_pte_phys(phys, __pgprot(prot)));
 }
 
 static inline unsigned long
 setup_pagetables(unsigned long start_mem, unsigned long end_mem)
 {
-       unsigned long address;
-
-       /*
-        * map in zero page
-        */
-       alloc_init_page(&start_mem, 0, __virt_to_phys(PAGE_OFFSET), DOMAIN_USER, PTE_CACHEABLE);
-
-       /*
-        * ensure no mappings in user space
-        */
-       for (address = PGDIR_SIZE; address < PAGE_OFFSET; address += PGDIR_SIZE)
-               free_init_section(address);
-
-       /*
-        * map in physical ram & kernel
-        */
-       for (address = PAGE_OFFSET; address < end_mem; address += PGDIR_SIZE)
-               alloc_init_section(&start_mem, address, __virt_to_phys(address), DOMAIN_KERNEL,
-                                  PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE | PMD_SECT_AP_WRITE);
-
-       /*
-        * unmap everything else
-        */
-       for (address = end_mem; address; address += PGDIR_SIZE)
-               free_init_section(address);
+       unsigned long address = 0;
+
+       do {
+               if (address >= PAGE_OFFSET && address < end_mem)
+                       /*
+                        * map in physical ram & kernel
+                        */
+                       alloc_init_section(&start_mem, address, __virt_to_phys(address), DOMAIN_KERNEL,
+                                          PMD_SECT_CACHEABLE | PMD_SECT_BUFFERABLE | PMD_SECT_AP_WRITE);
+               else
+                       /*
+                        * unmap everything else
+                        */
+                       free_init_section(address);
+
+               address += PGDIR_SIZE;
+       } while (address != 0);
 
        /*
         * An area to invalidate the cache
@@ -144,6 +139,12 @@ setup_pagetables(unsigned long start_mem, unsigned long end_mem)
         */
        start_mem = setup_io_pagetables(start_mem);
 
+       /*
+        * map in zero page
+        */
+       alloc_init_page(&start_mem, 0, __virt_to_phys(PAGE_OFFSET),
+                       DOMAIN_USER, L_PTE_CACHEABLE | L_PTE_YOUNG | L_PTE_PRESENT);
+
        flush_cache_all();
 
        return start_mem;
@@ -156,9 +157,21 @@ void mark_usable_memory_areas(unsigned long *start_mem, unsigned long end_mem)
 
        *start_mem = smem = PAGE_ALIGN(*start_mem);
 
+       /*
+        * Mark all of memory from the end of kernel to end of memory
+        */
        while (smem < end_mem) {
-               clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
-               smem += PAGE_SIZE;
+               clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
+               smem += PAGE_SIZE;
+       }
+
+       /*
+        * Mark memory from page 1 to start of the swapper page directory
+        */
+       smem = PAGE_OFFSET + PAGE_SIZE;
+       while (smem < (unsigned long)&swapper_pg_dir) {
+               clear_bit(PG_reserved, &mem_map[MAP_NR(smem)].flags);
+               smem += PAGE_SIZE;
        }
 }      
 
index f3f740373100bf2e3845e470d5dedfd06626495e..fd93bdd29416ee08d17295104b890b5369fd3840 100644 (file)
@@ -3,14 +3,15 @@
  *
  * Copyright (C) 1995, 1996, 1997 Russell King
  *
- * 12-01-1997  RMK     Altered flushing routines to use function pointers
+ * 12-Jan-1997 RMK     Altered flushing routines to use function pointers
  *                     now possible to combine ARM6, ARM7 and StrongARM versions.
+ * 17-Apr-1999 RMK     Now pass an area size to clean_cache_area and
+ *                     flush_icache_area.
  */
 #ifndef __ASM_PROC_PGTABLE_H
 #define __ASM_PROC_PGTABLE_H
 
-#include <asm/arch/mmu.h>
-#include <asm/arch/processor.h>                /* For TASK_SIZE */
+#include <asm/arch/memory.h>           /* For TASK_SIZE */
 
 #define LIBRARY_TEXT_START 0x0c000000
 
                                 ((_vma)->vm_flags & VM_EXEC) ? 1 : 0); \
        } while (0)
 
+#define clean_cache_range(_start,_end)                                 \
+       do {                                                            \
+               unsigned long _s, _sz;                                  \
+               _s = (unsigned long)_start;                             \
+               _sz = (unsigned long)_end - _s;                         \
+               processor.u.armv3v4._clean_cache_area(_s, _sz);         \
+       } while (0)
+
+#define clean_cache_area(_start,_size)                                 \
+       do {                                                            \
+               unsigned long _s;                                       \
+               _s = (unsigned long)_start;                             \
+               processor.u.armv3v4._clean_cache_area(_s, _size);       \
+       } while (0)
+
 #define flush_icache_range(_start,_end)                                        \
-       processor.u.armv3v4._flush_icache_area((_start), (_end))
+       processor.u.armv3v4._flush_icache_area((_start), (_end) - (_start))
 
 /*
  * We don't have a MEMC chip...
 #define flush_page_to_ram(_page)                                       \
        processor.u.armv3v4._flush_ram_page ((_page) & PAGE_MASK);
 
-/*
- * Make the page uncacheable (must flush page beforehand).
- */
-#define uncache_page(_page)                                            \
-       processor.u.armv3v4._flush_ram_page ((_page) & PAGE_MASK);
-
 /*
  * TLB flushing:
  *
        } while (0)
 
 /*
- * Since the page tables are in cached memory, we need to flush the dirty
- * data cached entries back before we flush the tlb...  This is also useful
- * to flush out the SWI instruction for signal handlers...
+ * PMD_SHIFT determines the size of the area a second-level page table can map
  */
-#define __flush_entry_to_ram(entry)                                            \
-       processor.u.armv3v4._flush_cache_entry((unsigned long)(entry))
-
-#define __flush_pte_to_ram(entry)                                              \
-       processor.u.armv3v4._flush_cache_pte((unsigned long)(entry))
-
-/* PMD_SHIFT determines the size of the area a second-level page table can map */
 #define PMD_SHIFT       20
 #define PMD_SIZE        (1UL << PMD_SHIFT)
 #define PMD_MASK        (~(PMD_SIZE-1))
 
-/* PGDIR_SHIFT determines what a third-level page table entry can map */
+/*
+ * PGDIR_SHIFT determines what a third-level page table entry can map
+ */
 #define PGDIR_SHIFT     20
 #define PGDIR_SIZE      (1UL << PGDIR_SHIFT)
 #define PGDIR_MASK      (~(PGDIR_SIZE-1))
 #define PTRS_PER_PGD    4096
 #define USER_PTRS_PER_PGD      (TASK_SIZE/PGDIR_SIZE)
 
+
 /* Just any arbitrary offset to the start of the vmalloc VM area: the
  * current 8MB value just means that there will be a 8MB "hole" after the
  * physical memory until the kernel virtual memory starts.  That means that
 #define VMALLOC_VMADDR(x) ((unsigned long)(x))
 #define VMALLOC_END       (PAGE_OFFSET + 0x10000000)
 
-/* PMD types (actually level 1 descriptor) */
-#define PMD_TYPE_MASK          0x0003
-#define PMD_TYPE_FAULT         0x0000
-#define PMD_TYPE_TABLE         0x0001
-#define PMD_TYPE_SECT          0x0002
-#define PMD_UPDATABLE          0x0010
-#define PMD_SECT_CACHEABLE     0x0008
-#define PMD_SECT_BUFFERABLE    0x0004
-#define PMD_SECT_AP_WRITE      0x0400
-#define PMD_SECT_AP_READ       0x0800
-#define PMD_DOMAIN(x)          ((x) << 5)
 
-/* PTE types (actially level 2 descriptor) */
-#define PTE_TYPE_MASK  0x0003
-#define PTE_TYPE_FAULT 0x0000
-#define PTE_TYPE_LARGE 0x0001
-#define PTE_TYPE_SMALL 0x0002
-#define PTE_AP_READ    0x0aa0
-#define PTE_AP_WRITE   0x0550
-#define PTE_CACHEABLE  0x0008
-#define PTE_BUFFERABLE 0x0004
-
-/* Domains */
+/*
+ * Domains
+ */
 #define DOMAIN_USER    0
 #define DOMAIN_KERNEL  1
 #define DOMAIN_TABLE   1
 #define DOMAIN_IO      2
 
-#define _PAGE_CHG_MASK  (0xfffff00c | PTE_TYPE_MASK)
 
-/*
- * We define the bits in the page tables as follows:
- *  PTE_BUFFERABLE     page is dirty
- *  PTE_AP_WRITE       page is writable
- *  PTE_AP_READ                page is a young (unsetting this causes faults for any access)
- *  PTE_CACHEABLE       page is readable
- *
- * A page will not be made writable without the dirty bit set.
- * It is not legal to have a writable non-dirty page though (it breaks).
- *
- * A readable page is marked as being cacheable.
- * Youngness is indicated by hardware read.  If the page is old,
- * then we will fault and make the page young again.
- */
-#define _PTE_YOUNG     PTE_AP_READ
-#define _PTE_DIRTY     PTE_BUFFERABLE
-#define _PTE_READ      PTE_CACHEABLE
-#define _PTE_WRITE     PTE_AP_WRITE
 
-#define PAGE_NONE       __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG)
-#define PAGE_SHARED     __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ | _PTE_WRITE)
-#define PAGE_COPY       __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ)
-#define PAGE_READONLY   __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ)
-#define PAGE_KERNEL     __pgprot(PTE_TYPE_SMALL | _PTE_READ  | _PTE_DIRTY | _PTE_WRITE)
-
-#define _PAGE_USER_TABLE       (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER))
-#define _PAGE_KERNEL_TABLE     (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL))
+#undef TEST_VERIFY_AREA
 
 /*
- * The arm can't do page protection for execute, and considers that the same are read.
- * Also, write permissions imply read permissions. This is the closest we can get..
+ * The sa110 doesn't have any external MMU info: the kernel page
+ * tables contain all the necessary information.
  */
-#define __P000  PAGE_NONE
-#define __P001  PAGE_READONLY
-#define __P010  PAGE_COPY
-#define __P011  PAGE_COPY
-#define __P100  PAGE_READONLY
-#define __P101  PAGE_READONLY
-#define __P110  PAGE_COPY
-#define __P111  PAGE_COPY
-
-#define __S000  PAGE_NONE
-#define __S001  PAGE_READONLY
-#define __S010  PAGE_SHARED
-#define __S011  PAGE_SHARED
-#define __S100  PAGE_READONLY
-#define __S101  PAGE_READONLY
-#define __S110  PAGE_SHARED
-#define __S111  PAGE_SHARED
+extern __inline__ void update_mmu_cache(struct vm_area_struct * vma,
+       unsigned long address, pte_t pte)
+{
+}
 
-#undef TEST_VERIFY_AREA
 
 /*
  * BAD_PAGETABLE is used when we need a bogus page-table, while
@@ -240,97 +185,40 @@ extern pte_t __bad_page(void);
 extern pte_t * __bad_pagetable(void);
 extern unsigned long *empty_zero_page;
 
-#define BAD_PAGETABLE __bad_pagetable()
-#define BAD_PAGE __bad_page()
-#define ZERO_PAGE ((unsigned long) empty_zero_page)
+#define BAD_PAGETABLE  __bad_pagetable()
+#define BAD_PAGE       __bad_page()
+#define ZERO_PAGE      ((unsigned long) empty_zero_page)
 
 /* number of bits that fit into a memory pointer */
-#define BYTES_PER_PTR                  (sizeof(unsigned long))
-#define BITS_PER_PTR                    (8*BYTES_PER_PTR)
+#define BYTES_PER_PTR  (sizeof(unsigned long))
+#define BITS_PER_PTR   (8*BYTES_PER_PTR)
 
 /* to align the pointer to a pointer address */
-#define PTR_MASK                        (~(sizeof(void*)-1))
+#define PTR_MASK       (~(sizeof(void*)-1))
 
 /* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
-#define SIZEOF_PTR_LOG2                 2
+#define SIZEOF_PTR_LOG2        2
 
 /* to find an entry in a page-table */
 #define PAGE_PTR(address) \
 ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
 
-/* to set the page-dir */
+/* to set the page-dir
+ * Note that we need to flush the cache and TLBs
+ * if we are affecting the current task.
+ */
 #define SET_PAGE_DIR(tsk,pgdir)                                        \
 do {                                                           \
        tsk->tss.memmap = __virt_to_phys((unsigned long)pgdir); \
-       if ((tsk) == current)                                   \
+       if ((tsk) == current) {                                 \
+               flush_cache_all();                              \
                __asm__ __volatile__(                           \
                "mcr%?  p15, 0, %0, c2, c0, 0\n"                \
                : : "r" (tsk->tss.memmap));                     \
+               flush_tlb_all();                                \
+       }                                                       \
 } while (0)
 
-extern __inline__ int pte_none(pte_t pte)
-{
-       return !pte_val(pte);
-}
-
-#define pte_clear(ptep)        set_pte(ptep, __pte(0))
-
-extern __inline__ int pte_present(pte_t pte)
-{
-#if 0
-       /* This is what it really does, the else
-          part is just to make it easier for the compiler */
-       switch (pte_val(pte) & PTE_TYPE_MASK) {
-       case PTE_TYPE_LARGE:
-       case PTE_TYPE_SMALL:
-               return 1;
-       default:
-               return 0;
-       }
-#else
-       return ((pte_val(pte) + 1) & 2);
-#endif
-}
-
-extern __inline__ int pmd_none(pmd_t pmd)
-{
-       return !pmd_val(pmd);
-}
-
-#define pmd_clear(pmdp) set_pmd(pmdp, __pmd(0))
-
-extern __inline__ int pmd_bad(pmd_t pmd)
-{
-#if 0
-       /* This is what it really does, the else
-          part is just to make it easier for the compiler */
-       switch (pmd_val(pmd) & PMD_TYPE_MASK) {
-       case PMD_TYPE_FAULT:
-       case PMD_TYPE_TABLE:
-               return 0;
-       default:
-               return 1;
-       }
-#else
-       return pmd_val(pmd) & 2;
-#endif
-}
-
-extern __inline__ int pmd_present(pmd_t pmd)
-{
-#if 0
-       /* This is what it really does, the else
-          part is just to make it easier for the compiler */
-       switch (pmd_val(pmd) & PMD_TYPE_MASK) {
-       case PMD_TYPE_TABLE:
-               return 1;
-       default:
-               return 0;
-       }
-#else
-       return ((pmd_val(pmd) + 1) & 2);
-#endif
-}
 
 /*
  * The "pgd_xxx()" functions here are trivial for a folded two-level
@@ -342,231 +230,224 @@ extern __inline__ int pmd_present(pmd_t pmd)
 #define pgd_present(pgd)       (1)
 #define pgd_clear(pgdp)
 
-/*
- * The following only work if pte_present() is true.
- * Undefined behaviour if not..
- */
-#define pte_read(pte)          (1)
-#define pte_exec(pte)          (1)
+/* to find an entry in a kernel page-table-directory */
+#define pgd_offset_k(address) pgd_offset(&init_mm, address)
 
-extern __inline__ int pte_write(pte_t pte)
+/* to find an entry in a page-table-directory */
+extern __inline__ pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
 {
-       return pte_val(pte) & _PTE_WRITE;
+       return mm->pgd + (address >> PGDIR_SHIFT);
 }
 
-extern __inline__ int pte_dirty(pte_t pte)
-{
-       return pte_val(pte) & _PTE_DIRTY;
-}
+extern unsigned long get_page_2k(int priority);
+extern void free_page_2k(unsigned long page);
 
-extern __inline__ int pte_young(pte_t pte)
-{
-       return pte_val(pte) & _PTE_YOUNG;
-}
+/*
+ * Allocate and free page tables. The xxx_kernel() versions are
+ * used to allocate a kernel page table - this turns on ASN bits
+ * if any.
+ */
 
-extern __inline__ pte_t pte_wrprotect(pte_t pte)
-{
-       pte_val(pte) &= ~_PTE_WRITE;
-       return pte;
-}
+#ifndef __SMP__
+extern struct pgtable_cache_struct {
+       unsigned long *pgd_cache;
+       unsigned long *pte_cache;
+       unsigned long pgtable_cache_sz;
+} quicklists;
 
-extern __inline__ pte_t pte_nocache(pte_t pte)
-{
-       pte_val(pte) &= ~PTE_CACHEABLE;
-       return pte;
-}
+#define pgd_quicklist (quicklists.pgd_cache)
+#define pmd_quicklist ((unsigned long *)0)
+#define pte_quicklist (quicklists.pte_cache)
+#define pgtable_cache_size (quicklists.pgtable_cache_sz)
+#else
+#error Pgtable caches have to be per-CPU, so that no locking is needed.
+#endif
 
-extern __inline__ pte_t pte_mkclean(pte_t pte)
-{
-       pte_val(pte) &= ~_PTE_DIRTY;
-       return pte;
-}
+extern pgd_t *get_pgd_slow(void);
 
-extern __inline__ pte_t pte_mkold(pte_t pte)
+extern __inline__ pgd_t *get_pgd_fast(void)
 {
-       pte_val(pte) &= ~_PTE_YOUNG;
-       return pte;
+       unsigned long *ret;
+
+       if((ret = pgd_quicklist) != NULL) {
+               pgd_quicklist = (unsigned long *)(*ret);
+               ret[0] = ret[1];
+               clean_cache_area(ret, 4);
+               pgtable_cache_size--;
+       } else
+               ret = (unsigned long *)get_pgd_slow();
+       return (pgd_t *)ret;
 }
 
-extern __inline__ pte_t pte_mkwrite(pte_t pte)
+extern __inline__ void free_pgd_fast(pgd_t *pgd)
 {
-       pte_val(pte) |= _PTE_WRITE;
-       return pte;
+       *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
+       pgd_quicklist = (unsigned long *) pgd;
+       pgtable_cache_size++;
 }
 
-extern __inline__ pte_t pte_mkdirty(pte_t pte)
+extern __inline__ void free_pgd_slow(pgd_t *pgd)
 {
-       pte_val(pte) |= _PTE_DIRTY;
-       return pte;
+       free_pages((unsigned long) pgd, 2);
 }
 
-extern __inline__ pte_t pte_mkyoung(pte_t pte)
+#define pgd_free(pgd)          free_pgd_fast(pgd)
+#define pgd_alloc()            get_pgd_fast()
+
+extern __inline__ void set_pgdir(unsigned long address, pgd_t entry)
 {
-       pte_val(pte) |= _PTE_YOUNG;
-       return pte;
+       struct task_struct * p;
+       pgd_t *pgd;
+
+       read_lock(&tasklist_lock);
+       for_each_task(p) {
+               if (!p->mm)
+                       continue;
+               *pgd_offset(p->mm,address) = entry;
+       }
+       read_unlock(&tasklist_lock);
+       for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
+               pgd[address >> PGDIR_SHIFT] = entry;
 }
 
-/*
- * The following are unable to be implemented on this MMU
- */
-#if 0
-extern __inline__ pte_t pte_rdprotect(pte_t pte)
+extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+
+/****************
+* PMD functions *
+****************/
+
+/* PMD types (actually level 1 descriptor) */
+#define PMD_TYPE_MASK          0x0003
+#define PMD_TYPE_FAULT         0x0000
+#define PMD_TYPE_TABLE         0x0001
+#define PMD_TYPE_SECT          0x0002
+#define PMD_UPDATABLE          0x0010
+#define PMD_SECT_CACHEABLE     0x0008
+#define PMD_SECT_BUFFERABLE    0x0004
+#define PMD_SECT_AP_WRITE      0x0400
+#define PMD_SECT_AP_READ       0x0800
+#define PMD_DOMAIN(x)          ((x) << 5)
+
+#define _PAGE_USER_TABLE       (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER))
+#define _PAGE_KERNEL_TABLE     (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL))
+
+#define pmd_none(pmd)          (!pmd_val(pmd))
+#define pmd_clear(pmdp)                set_pmd(pmdp, __pmd(0))
+#define pmd_bad(pmd)           (pmd_val(pmd) & 2)
+#define mk_user_pmd(ptep)      __mk_pmd(ptep, _PAGE_USER_TABLE)
+#define mk_kernel_pmd(ptep)    __mk_pmd(ptep, _PAGE_KERNEL_TABLE)
+#define set_pmd(pmdp,pmd)      processor.u.armv3v4._set_pmd(pmdp,pmd)
+
+/* Find an entry in the second-level page table.. */
+#define pmd_offset(dir, address) ((pmd_t *)(dir))
+
+extern __inline__ int pmd_present(pmd_t pmd)
 {
-       pte_val(pte) &= ~(PTE_CACHEABLE|PTE_AP_READ);
-       return pte;
+       return ((pmd_val(pmd) + 1) & 2);
 }
 
-extern __inline__ pte_t pte_exprotect(pte_t pte)
+/* We don't use pmd cache, so this is a dummy routine */
+extern __inline__ pmd_t *get_pmd_fast(void)
 {
-       pte_val(pte) &= ~(PTE_CACHEABLE|PTE_AP_READ);
-       return pte;
+       return (pmd_t *)0;
 }
 
-extern __inline__ pte_t pte_mkread(pte_t pte)
+extern __inline__ void free_pmd_fast(pmd_t *pmd)
 {
-       pte_val(pte) |= PTE_CACHEABLE;
-       return pte;
 }
 
-extern __inline__ pte_t pte_mkexec(pte_t pte)
+extern __inline__ void free_pmd_slow(pmd_t *pmd)
 {
-       pte_val(pte) |= PTE_CACHEABLE;
-       return pte;
 }
-#endif
+
+extern void __bad_pmd(pmd_t *pmd);
+extern void __bad_pmd_kernel(pmd_t *pmd);
 
 /*
- * Conversion functions: convert a page and protection to a page entry,
- * and a page entry and page directory to the page they refer to.
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
  */
-extern __inline__ pte_t mk_pte(unsigned long page, pgprot_t pgprot)
+extern __inline__ void pmd_free(pmd_t *pmd)
 {
-       pte_t pte;
-       pte_val(pte) = __virt_to_phys(page) | pgprot_val(pgprot);
-       return pte;
 }
 
-/* This takes a physical page address that is used by the remapping functions */
-extern __inline__ pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
+extern __inline__ pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
 {
-       pte_t pte;
-       pte_val(pte) = physpage + pgprot_val(pgprot);
-       return pte;
+       return (pmd_t *) pgd;
 }
 
-extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot)
-{
-       pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
-       return pte;
-}
+#define pmd_free_kernel                pmd_free
+#define pmd_alloc_kernel       pmd_alloc
 
-extern __inline__ void set_pte(pte_t *pteptr, pte_t pteval)
+extern __inline__ pmd_t __mk_pmd(pte_t *ptep, unsigned long prot)
 {
-       *pteptr = pteval;
-       __flush_pte_to_ram(pteptr);
-}
+       unsigned long pte_ptr = (unsigned long)ptep;
+       pmd_t pmd;
 
-extern __inline__ unsigned long pte_page(pte_t pte)
-{
-       return __phys_to_virt(pte_val(pte) & PAGE_MASK);
-}
+       pte_ptr -= PTRS_PER_PTE * BYTES_PER_PTR;
 
-extern __inline__ pmd_t mk_user_pmd(pte_t *ptep)
-{
-       pmd_t pmd;
-       pmd_val(pmd) = __virt_to_phys((unsigned long)ptep) | _PAGE_USER_TABLE;
-       return pmd;
-}
+       /*
+        * The pmd must be loaded with the physical
+        * address of the PTE table
+        */
+       pmd_val(pmd) = __virt_to_phys(pte_ptr) | prot;
 
-extern __inline__ pmd_t mk_kernel_pmd(pte_t *ptep)
-{
-       pmd_t pmd;
-       pmd_val(pmd) = __virt_to_phys((unsigned long)ptep) | _PAGE_KERNEL_TABLE;
        return pmd;
 }
 
-#if 1
-#define set_pmd(pmdp,pmd) processor.u.armv3v4._set_pmd(pmdp,pmd)
-#else
-extern __inline__ void set_pmd(pmd_t *pmdp, pmd_t pmd)
-{
-       *pmdp = pmd;
-       __flush_pte_to_ram(pmdp);
-}
-#endif
-
 extern __inline__ unsigned long pmd_page(pmd_t pmd)
 {
-       return __phys_to_virt(pmd_val(pmd) & 0xfffffc00);
-}
+       unsigned long ptr;
 
-/* to find an entry in a kernel page-table-directory */
-#define pgd_offset_k(address) pgd_offset(&init_mm, address)
+       ptr = pmd_val(pmd) & ~(PTRS_PER_PTE * BYTES_PER_PTR - 1);
 
-/* to find an entry in a page-table-directory */
-extern __inline__ pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
-{
-       return mm->pgd + (address >> PGDIR_SHIFT);
+       ptr += PTRS_PER_PTE * BYTES_PER_PTR;
+
+       return __phys_to_virt(ptr);
 }
 
-/* Find an entry in the second-level page table.. */
-#define pmd_offset(dir, address) ((pmd_t *)(dir))
 
-/* Find an entry in the third-level page table.. */
-extern __inline__ pte_t * pte_offset(pmd_t * dir, unsigned long address)
-{
-       return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
-}
+/****************
+* PTE functions *
+****************/
 
-extern unsigned long get_small_page(int priority);
-extern void free_small_page(unsigned long page);
+/* PTE types (actially level 2 descriptor) */
+#define PTE_TYPE_MASK          0x0003
+#define PTE_TYPE_FAULT         0x0000
+#define PTE_TYPE_LARGE         0x0001
+#define PTE_TYPE_SMALL         0x0002
+#define PTE_AP_READ            0x0aa0
+#define PTE_AP_WRITE           0x0550
+#define PTE_CACHEABLE          0x0008
+#define PTE_BUFFERABLE         0x0004
+
+#define pte_none(pte)          (!pte_val(pte))
+#define pte_clear(ptep)                set_pte(ptep, __pte(0))
 
 /*
- * Allocate and free page tables. The xxx_kernel() versions are
- * used to allocate a kernel page table - this turns on ASN bits
- * if any.
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
  */
-
-#ifndef __SMP__
-extern struct pgtable_cache_struct {
-       unsigned long *pgd_cache;
-       unsigned long *pte_cache;
-       unsigned long pgtable_cache_sz;
-} quicklists;
-
-#define pgd_quicklist (quicklists.pgd_cache)
-#define pmd_quicklist ((unsigned long *)0)
-#define pte_quicklist (quicklists.pte_cache)
-#define pgtable_cache_size (quicklists.pgtable_cache_sz)
-#else
-#error Pgtable caches have to be per-CPU, so that no locking is needed.
-#endif
-
-extern pgd_t *get_pgd_slow(void);
-
-extern __inline__ pgd_t *get_pgd_fast(void)
+extern __inline__ pte_t mk_pte(unsigned long page, pgprot_t pgprot)
 {
-       unsigned long *ret;
-
-       if((ret = pgd_quicklist) != NULL) {
-               pgd_quicklist = (unsigned long *)(*ret);
-               ret[0] = ret[1];
-               pgtable_cache_size--;
-       } else
-               ret = (unsigned long *)get_pgd_slow();
-       return (pgd_t *)ret;
+       pte_t pte;
+       pte_val(pte) = __virt_to_phys(page) | pgprot_val(pgprot);
+       return pte;
 }
 
-extern __inline__ void free_pgd_fast(pgd_t *pgd)
+/* This takes a physical page address that is used by the remapping functions */
+extern __inline__ pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot)
 {
-       *(unsigned long *)pgd = (unsigned long) pgd_quicklist;
-       pgd_quicklist = (unsigned long *) pgd;
-       pgtable_cache_size++;
+       pte_t pte;
+       pte_val(pte) = physpage + pgprot_val(pgprot);
+       return pte;
 }
 
-extern __inline__ void free_pgd_slow(pgd_t *pgd)
+#define set_pte(ptep, pte)     processor.u.armv3v4._set_pte(ptep,pte)
+
+extern __inline__ unsigned long pte_page(pte_t pte)
 {
-       free_pages((unsigned long) pgd, 2);
+       return __phys_to_virt(pte_val(pte) & PAGE_MASK);
 }
 
 extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long address_preadjusted);
@@ -579,6 +460,7 @@ extern __inline__ pte_t *get_pte_fast(void)
        if((ret = (unsigned long *)pte_quicklist) != NULL) {
                pte_quicklist = (unsigned long *)(*ret);
                ret[0] = ret[1];
+               clean_cache_area(ret, 4);
                pgtable_cache_size--;
        }
        return (pte_t *)ret;
@@ -593,31 +475,124 @@ extern __inline__ void free_pte_fast(pte_t *pte)
 
 extern __inline__ void free_pte_slow(pte_t *pte)
 {
-       free_small_page((unsigned long)pte);
+       free_page_2k((unsigned long)(pte - PTRS_PER_PTE));
 }
 
-/* We don't use pmd cache, so this is a dummy routine */
-extern __inline__ pmd_t *get_pmd_fast(void)
-{
-       return (pmd_t *)0;
-}
+#define pte_free_kernel(pte)   free_pte_fast(pte)
+#define pte_free(pte)          free_pte_fast(pte)
 
-extern __inline__ void free_pmd_fast(pmd_t *pmd)
+/*###############################################################################
+ * New PageTableEntry stuff...
+ */
+/* We now keep two sets of ptes - the physical and the linux version.
+ * This gives us many advantages, and allows us greater flexibility.
+ *
+ * The Linux pte's contain:
+ *  bit   meaning
+ *   0    page present
+ *   1    young
+ *   2    bufferable   - matches physical pte
+ *   3    cacheable    - matches physical pte
+ *   4    user
+ *   5    write
+ *   6    execute
+ *   7    dirty
+ *  8-11  unused
+ *  12-31 virtual page address
+ *
+ * These are stored at the pte pointer; the physical PTE is at -1024bytes
+ */
+#define L_PTE_PRESENT          (1 << 0)
+#define L_PTE_YOUNG            (1 << 1)
+#define L_PTE_BUFFERABLE       (1 << 2)
+#define L_PTE_CACHEABLE                (1 << 3)
+#define L_PTE_USER             (1 << 4)
+#define L_PTE_WRITE            (1 << 5)
+#define L_PTE_EXEC             (1 << 6)
+#define L_PTE_DIRTY            (1 << 7)
+
+/*
+ * The following macros handle the cache and bufferable bits...
+ */
+#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG
+#define _L_PTE_READ    L_PTE_USER | L_PTE_CACHEABLE
+#define _L_PTE_EXEC    _L_PTE_READ | L_PTE_EXEC
+
+#define PAGE_NONE       __pgprot(_L_PTE_DEFAULT)
+#define PAGE_COPY       __pgprot(_L_PTE_DEFAULT | _L_PTE_READ  | L_PTE_BUFFERABLE)
+#define PAGE_SHARED     __pgprot(_L_PTE_DEFAULT | _L_PTE_READ  | L_PTE_BUFFERABLE | L_PTE_WRITE)
+#define PAGE_READONLY   __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
+#define PAGE_KERNEL     __pgprot(_L_PTE_DEFAULT | L_PTE_CACHEABLE | L_PTE_BUFFERABLE | L_PTE_DIRTY | L_PTE_WRITE)
+
+#define _PAGE_CHG_MASK         (PAGE_MASK | L_PTE_DIRTY | L_PTE_YOUNG)
+
+/*
+ * The table below defines the page protection levels that we insert into our
+ * Linux page table version.  These get translated into the best that the
+ * architecture can perform.  Note that on most ARM hardware:
+ *  1) We cannot do execute protection
+ *  2) If we could do execute protection, then read is implied
+ *  3) write implies read permissions
+ */
+#define __P000  PAGE_NONE
+#define __P001  PAGE_READONLY
+#define __P010  PAGE_COPY
+#define __P011  PAGE_COPY
+#define __P100  PAGE_READONLY
+#define __P101  PAGE_READONLY
+#define __P110  PAGE_COPY
+#define __P111  PAGE_COPY
+
+#define __S000  PAGE_NONE
+#define __S001  PAGE_READONLY
+#define __S010  PAGE_SHARED
+#define __S011  PAGE_SHARED
+#define __S100  PAGE_READONLY
+#define __S101  PAGE_READONLY
+#define __S110  PAGE_SHARED
+#define __S111  PAGE_SHARED
+
+
+
+#define pte_present(pte)       (pte_val(pte) & L_PTE_PRESENT)
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+#define pte_read(pte)                  (pte_val(pte) & L_PTE_USER)
+#define pte_write(pte)                 (pte_val(pte) & L_PTE_WRITE)
+#define pte_exec(pte)                  (pte_val(pte) & L_PTE_EXEC)
+#define pte_dirty(pte)                 (pte_val(pte) & L_PTE_DIRTY)
+#define pte_young(pte)                 (pte_val(pte) & L_PTE_YOUNG)
+
+#define PTE_BIT_FUNC(fn,op)                    \
+extern inline pte_t fn##(pte_t pte) { pte_val(pte) op##; return pte; }
+
+//PTE_BIT_FUNC(pte_rdprotect, &= ~L_PTE_USER);
+PTE_BIT_FUNC(pte_wrprotect, &= ~L_PTE_WRITE);
+PTE_BIT_FUNC(pte_exprotect, &= ~L_PTE_EXEC);
+PTE_BIT_FUNC(pte_mkclean,   &= ~L_PTE_DIRTY);
+PTE_BIT_FUNC(pte_mkold,     &= ~L_PTE_YOUNG);
+//PTE_BIT_FUNC(pte_mkread,    |= L_PTE_USER);
+PTE_BIT_FUNC(pte_mkwrite,   |= L_PTE_WRITE);
+PTE_BIT_FUNC(pte_mkexec,    |= L_PTE_EXEC);
+PTE_BIT_FUNC(pte_mkdirty,   |= L_PTE_DIRTY);
+PTE_BIT_FUNC(pte_mkyoung,   |= L_PTE_YOUNG);
+PTE_BIT_FUNC(pte_nocache,   &= ~L_PTE_CACHEABLE);
+
+extern __inline__ pte_t pte_modify(pte_t pte, pgprot_t newprot)
 {
+       pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot);
+       return pte;
 }
 
-extern __inline__ void free_pmd_slow(pmd_t *pmd)
+/* Find an entry in the third-level page table.. */
+extern __inline__ pte_t * pte_offset(pmd_t * dir, unsigned long address)
 {
+       return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
 }
 
-extern void __bad_pmd(pmd_t *pmd);
-extern void __bad_pmd_kernel(pmd_t *pmd);
-
-#define pte_free_kernel(pte)   free_pte_fast(pte)
-#define pte_free(pte)          free_pte_fast(pte)
-#define pgd_free(pgd)          free_pgd_fast(pgd)
-#define pgd_alloc()            get_pgd_fast()
-
 extern __inline__ pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address)
 {
        address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
@@ -655,49 +630,6 @@ extern __inline__ pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
        return (pte_t *) pmd_page(*pmd) + address;
 }
 
-/*
- * allocating and freeing a pmd is trivial: the 1-entry pmd is
- * inside the pgd, so has no extra memory associated with it.
- */
-extern __inline__ void pmd_free(pmd_t *pmd)
-{
-}
-
-extern __inline__ pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address)
-{
-       return (pmd_t *) pgd;
-}
-
-#define pmd_free_kernel                pmd_free
-#define pmd_alloc_kernel       pmd_alloc
-
-extern __inline__ void set_pgdir(unsigned long address, pgd_t entry)
-{
-       struct task_struct * p;
-       pgd_t *pgd;
-
-       read_lock(&tasklist_lock);
-       for_each_task(p) {
-               if (!p->mm)
-                       continue;
-               *pgd_offset(p->mm,address) = entry;
-       }
-       read_unlock(&tasklist_lock);
-       for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd)
-               pgd[address >> PGDIR_SHIFT] = entry;
-}
-
-extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
-
-/*
- * The sa110 doesn't have any external MMU info: the kernel page
- * tables contain all the necessary information.
- */
-extern __inline__ void update_mmu_cache(struct vm_area_struct * vma,
-       unsigned long address, pte_t pte)
-{
-}
-
 #define SWP_TYPE(entry) (((entry) >> 2) & 0x7f)
 #define SWP_OFFSET(entry) ((entry) >> 9)
 #define SWP_ENTRY(type,offset) (((type) << 2) | ((offset) << 9))
index 88b277ea75aa048017029cf3ce3bf2a4c8b84587..7186039f9a69525fed16ab9c8ebca96b7c31e895 100644 (file)
@@ -12,8 +12,6 @@
 #ifndef __ASM_PROC_PROCESSOR_H
 #define __ASM_PROC_PROCESSOR_H
 
-#ifdef __KERNEL__
 #define KERNEL_STACK_SIZE      PAGE_SIZE
 
 struct context_save_struct {
@@ -28,56 +26,18 @@ struct context_save_struct {
        unsigned long pc;
 };
 
-#define EXTRA_THREAD_STRUCT                            \
-       struct context_save_struct *save;               \
-       unsigned long memmap;
+#define INIT_CSS (struct context_save_struct){ SVC_MODE, 0, 0, 0, 0, 0, 0, 0, 0 }
 
-#define EXTRA_THREAD_STRUCT_INIT                       \
-       0,                                              \
-       ((unsigned long) swapper_pg_dir) - PAGE_OFFSET
-
-DECLARE_THREAD_STRUCT;
-
-/*
- * Return saved PC of a blocked thread.
- */
-extern __inline__ unsigned long thread_saved_pc (struct thread_struct *t)
-{
-       if (t->save)
-               return t->save->pc;
-       else
-               return 0;
-}
-
-extern __inline__ unsigned long get_css_fp (struct thread_struct *t)
-{
-       if (t->save)
-               return t->save->fp;
-       else
-               return 0;
-}
-
-asmlinkage void ret_from_sys_call(void) __asm__ ("ret_from_sys_call");
-
-extern __inline__ void copy_thread_css (struct context_save_struct *save)
-{
-       save->cpsr = SVC_MODE;
-       save->r4 =
-       save->r5 =
-       save->r6 =
-       save->r7 =
-       save->r8 =
-       save->r9 =
-       save->fp = 0;
-       save->pc = (unsigned long) ret_from_sys_call;
-}
+#define EXTRA_THREAD_STRUCT
+#define EXTRA_THREAD_STRUCT_INIT
+#define SWAPPER_PG_DIR (((unsigned long)swapper_pg_dir) - PAGE_OFFSET)
 
 #define start_thread(regs,pc,sp)                                       \
 ({                                                                     \
        unsigned long *stack = (unsigned long *)sp;                     \
        set_fs(USER_DS);                                                \
        memzero(regs->uregs, sizeof(regs->uregs));                      \
-       if (current->personality == PER_LINUX_32BIT)                    \
+       if (current->personality & ADDR_LIMIT_32BIT)                    \
                regs->ARM_cpsr = USR_MODE;                              \
        else                                                            \
                regs->ARM_cpsr = USR26_MODE;                            \
@@ -92,10 +52,7 @@ extern __inline__ void copy_thread_css (struct context_save_struct *save)
 /*
  * NOTE! The task struct and the stack go together
  */
-#define alloc_task_struct() \
-       ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
-#define free_task_struct(p)    free_pages((unsigned long)(p),1)
-
-#endif
+#define ll_alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1))
+#define ll_free_task_struct(p) free_pages((unsigned long)(p),1)
 
 #endif
index 213c17ce708e6bf02953b9a7219601370249e414..b24305bd420031d101da128e37cd1d52bbe19028 100644 (file)
@@ -52,9 +52,14 @@ struct pt_regs {
 #define CC_Z_BIT       (1 << 30)
 #define CC_N_BIT       (1 << 31)
 
+#if 0 /* GCC/egcs should be able to optimise this, IMHO */
 #define user_mode(regs)        \
        ((((regs)->ARM_cpsr & MODE_MASK) == USR_MODE) || \
         (((regs)->ARM_cpsr & MODE_MASK) == USR26_MODE))
+#else
+#define user_mode(regs)        \
+       (((regs)->ARM_cpsr & 0xf) == 0)
+#endif
 
 #define processor_mode(regs) \
        ((regs)->ARM_cpsr & MODE_MASK)
@@ -74,8 +79,19 @@ struct pt_regs {
 /* Are the current registers suitable for user mode?
  * (used to maintain security in signal handlers)
  */
-#define valid_user_regs(regs) \
-       (user_mode(regs) && ((regs)->ARM_sp & 3) == 0)
+static inline int valid_user_regs(struct pt_regs *regs)
+{
+       if ((regs->ARM_cpsr & 0xf) == 0 ||
+           (regs->ARM_cpsr & (F_BIT|I_BIT)))
+               return 1;
+
+       /*
+        * Force CPSR to something logical...
+        */
+       regs->ARM_cpsr &= (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT|0x10);
+
+       return 0;
+}
 
 #endif
 
index 3da31f536bb9937d6e5b31dc3ff33f2d10756ad5..52098bc5c07c587b85b90deefd9569a64ed57ecd 100644 (file)
@@ -60,6 +60,32 @@ extern inline int down_interruptible (struct semaphore * sem)
        return temp;
 }
 
+extern inline int down_trylock(struct semaphore *sem)
+{
+       unsigned int cpsr, temp;
+
+       __asm__ __volatile__ ("
+       @ atomic down try lock operation
+       mrs     %0, cpsr
+       orr     %1, %0, #128            @ disable IRQs
+       bic     %0, %0, #0x80000000     @ clear N
+       msr     cpsr, %1
+       ldr     %1, [%2]
+       subs    %1, %1, #1
+       orrmi   %0, %0, #0x80000000     @ set N
+       str     %1, [%2]
+       msr     cpsr, %0
+       movmi   r0, %2
+       movpl   r0, #0
+       blmi    " SYMBOL_NAME_STR(__down_trylock_failed) "
+       mov     %1, r0"
+               : "=&r" (cpsr), "=&r" (temp)
+               : "r" (sem)
+               : "r0", "lr", "cc");
+
+       return temp;
+}
+
 /*
  * Note! This is subtle. We jump to wake people up only if
  * the semaphore was negative (== somebody was waiting on it).
index a8dce67397c2320798016ca389b5f470f043c507..a015a07380f13695c238bf4217756f415f3cc457 100644 (file)
@@ -133,6 +133,7 @@ extern __inline__ void set_fs (mm_segment_t fs)
        "       .section .fixup,\"ax\"\n"                       \
        "       .align  2\n"                                    \
        "3:     mvn     %0, %3\n"                               \
+       "       mov     %1, #0\n"                               \
        "       b       2b\n"                                   \
        "       .previous\n"                                    \
        "       .section __ex_table,\"a\"\n"                    \
@@ -153,6 +154,7 @@ extern __inline__ void set_fs (mm_segment_t fs)
        "       .section .fixup,\"ax\"\n"                       \
        "       .align  2\n"                                    \
        "4:     mvn     %0, %5\n"                               \
+       "       mov     %1, #0\n"                               \
        "       b       3b\n"                                   \
        "       .previous\n"                                    \
        "       .section __ex_table,\"a\"\n"                    \
@@ -173,6 +175,7 @@ extern __inline__ void set_fs (mm_segment_t fs)
        "       .section .fixup,\"ax\"\n"                       \
        "       .align  2\n"                                    \
        "3:     mvn     %0, %3\n"                               \
+       "       mov     %1, #0\n"                               \
        "       b       2b\n"                                   \
        "       .previous\n"                                    \
        "       .section __ex_table,\"a\"\n"                    \
index e3b35c9f283b45db223e367c8ca3965195fbdc8e..81873a58c3107584f79b8b00bf270abb688ab6af 100644 (file)
@@ -9,6 +9,10 @@
 #include <asm/page.h>
 
 #ifdef __KERNEL__
+
+/* forward-decare task_struct */
+struct task_struct;
+
 /*
  * Don't change this structure
  */
@@ -18,7 +22,7 @@ extern struct processor {
         *
         * flush caches for task switch
         */
-       void (*_switch_to)(void *prev, void *next);
+       struct task_struct *(*_switch_to)(struct task_struct *prev, struct task_struct *next);
        /*
         * get data abort address/flags
         */
@@ -54,10 +58,10 @@ extern struct processor {
                         */
                        void (*_flush_cache_entry)(unsigned long address);
                        /*
-                        * flush a virtual address used for a page table
-                        * note D-cache only!
+                        * clean a virtual address range from the
+                        * D-cache without flushing the cache.
                         */
-                       void (*_flush_cache_pte)(unsigned long address);
+                       void (*_clean_cache_area)(unsigned long start, unsigned long size);
                        /*
                         * flush a page to RAM
                         */
@@ -75,6 +79,10 @@ extern struct processor {
                         * Set a PMD (handling IMP bit 4)
                         */
                        void (*_set_pmd)(pmd_t *pmdp, pmd_t pmd);
+                       /*
+                        * Set a PTE
+                        */
+                       void (*_set_pte)(pte_t *ptep, pte_t pte);
                        /*
                         * Special stuff for a reset
                         */
@@ -82,7 +90,7 @@ extern struct processor {
                        /*
                         * flush an icached page
                         */
-                       void (*_flush_icache_area)(unsigned long start, unsigned long end);
+                       void (*_flush_icache_area)(unsigned long start, unsigned long size);
                        /*
                         * write back dirty cached data
                         */
index f4c68708940e8892c47236ca5b64edcac107d674..a59e441a14de94427fc582ceb5388f162f77b2a0 100644 (file)
@@ -7,12 +7,14 @@
 #ifndef __ASM_ARM_PROCESSOR_H
 #define __ASM_ARM_PROCESSOR_H
 
+#define FP_SIZE 35
+
 struct fp_hard_struct {
-       unsigned int save[140/4];               /* as yet undefined */
+       unsigned int save[FP_SIZE];             /* as yet undefined */
 };
 
 struct fp_soft_struct {
-       unsigned int save[140/4];               /* undefined information */
+       unsigned int save[FP_SIZE];             /* undefined information */
 };
 
 union fp_state {
@@ -22,28 +24,59 @@ union fp_state {
 
 typedef unsigned long mm_segment_t;            /* domain register      */
 
-#define NR_DEBUGS      5
+#ifdef __KERNEL__
 
-#define DECLARE_THREAD_STRUCT                                                  \
-struct thread_struct {                                                         \
-       unsigned long   address;                /* Address of fault     */      \
-       unsigned long   trap_no;                /* Trap number          */      \
-       unsigned long   error_code;             /* Error code of trap   */      \
-       union fp_state  fpstate;                /* FPE save state       */      \
-       unsigned long   debug[NR_DEBUGS];       /* Debug/ptrace         */      \
-       EXTRA_THREAD_STRUCT                                                     \
-}
+#include <asm/assembler.h> 
+
+#define NR_DEBUGS      5
 
 #include <asm/arch/processor.h>
 #include <asm/proc/processor.h>
 
-#define INIT_TSS  {                    \
-       0,                              \
-       0,                              \
-       0,                              \
-       { { { 0, }, }, },               \
-       { 0, },                         \
-       EXTRA_THREAD_STRUCT_INIT        \
+struct thread_struct {
+       unsigned long                   address;          /* Address of fault   */
+       unsigned long                   trap_no;          /* Trap number        */
+       unsigned long                   error_code;       /* Error code of trap */
+       union fp_state                  fpstate;          /* FPE save state     */
+       unsigned long                   debug[NR_DEBUGS]; /* Debug/ptrace       */
+       struct context_save_struct      *save;            /* context save       */
+       unsigned long                   memmap;           /* page tables        */
+       EXTRA_THREAD_STRUCT
+};
+
+#define INIT_MMAP \
+{ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, NULL, NULL }
+
+#define INIT_TSS  {                            \
+       0,                                      \
+       0,                                      \
+       0,                                      \
+       { { { 0, }, }, },                       \
+       { 0, },                                 \
+       (struct context_save_struct *)0,        \
+       SWAPPER_PG_DIR                          \
+       EXTRA_THREAD_STRUCT_INIT                \
+}
+
+/*
+ * Return saved PC of a blocked thread.
+ */
+extern __inline__ unsigned long thread_saved_pc(struct thread_struct *t)
+{
+       return t->save ? t->save->pc & ~PCMASK : 0;
+}
+
+extern __inline__ unsigned long get_css_fp(struct thread_struct *t)
+{
+       return t->save ? t->save->fp : 0;
+}
+
+asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
+
+extern __inline__ void init_thread_css(struct context_save_struct *save)
+{
+       *save = INIT_CSS;
+       save->pc |= (unsigned long)ret_from_sys_call;
 }
 
 /* Forward declaration, a strange C thing */
@@ -57,7 +90,12 @@ extern void release_thread(struct task_struct *);
 #define release_segments(mm)           do { } while (0)
 #define forget_segments()              do { } while (0)
 
+extern struct task_struct *alloc_task_struct(void);
+extern void free_task_struct(struct task_struct *);
+
 #define init_task      (init_task_union.task)
 #define init_stack     (init_task_union.stack)
 
+#endif
+
 #endif /* __ASM_ARM_PROCESSOR_H */
diff --git a/include/asm-arm/semaphore-helper.h b/include/asm-arm/semaphore-helper.h
new file mode 100644 (file)
index 0000000..1d7f198
--- /dev/null
@@ -0,0 +1,84 @@
+#ifndef ASMARM_SEMAPHORE_HELPER_H
+#define ASMARM_SEMAPHORE_HELPER_H
+
+/*
+ * These two _must_ execute atomically wrt each other.
+ */
+static inline void wake_one_more(struct semaphore * sem)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&semaphore_wake_lock, flags);
+       if (atomic_read(&sem->count) <= 0)
+               sem->waking++;
+       spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+}
+
+static inline int waking_non_zero(struct semaphore *sem)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&semaphore_wake_lock, flags);
+       if (sem->waking > 0) {
+               sem->waking--;
+               ret = 1;
+       }
+       spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+       return ret;
+}
+
+/*
+ * waking non zero interruptible
+ *     1       got the lock
+ *     0       go to sleep
+ *     -EINTR  interrupted
+ *
+ * We must undo the sem->count down_interruptible() increment while we are
+ * protected by the spinlock in order to make this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+static inline int waking_non_zero_interruptible(struct semaphore *sem,
+                                               struct task_struct *tsk)
+{
+       unsigned long flags;
+       int ret = 0;
+
+       spin_lock_irqsave(&semaphore_wake_lock, flags);
+       if (sem->waking > 0) {
+               sem->waking--;
+               ret = 1;
+       } else if (signal_pending(tsk)) {
+               atomic_inc(&sem->count);
+               ret = -EINTR;
+       }
+       spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+       return ret;     
+}
+
+/*
+ * waking_non_zero_try_lock:
+ *     1       failed to lock
+ *     0       got the lock
+ *
+ * We must undo the sem->count down_interruptible() increment while we are
+ * protected by the spinlock in order to make this atomic_inc() with the
+ * atomic_read() in wake_one_more(), otherwise we can race. -arca
+ */
+static inline int waking_non_zero_trylock(struct semaphore *sem)
+{
+       unsigned long flags;
+       int ret = 1;
+
+       spin_lock_irqsave(&semaphore_wake_lock, flags);
+       if (sem->waking <= 0)
+               atomic_inc(&sem->count);
+       else {
+               sem->waking--;
+               ret = 0;
+       }
+       spin_unlock_irqrestore(&semaphore_wake_lock, flags);
+       return ret;
+}
+
+#endif
index 287d8c263312d3c2b99d6fb5a91930cea7c5d5dd..a51b6f96eb0298d720da0eaf8f93ea32e1d5a470 100644 (file)
@@ -19,50 +19,16 @@ struct semaphore {
 
 asmlinkage void __down_failed (void /* special register calling convention */);
 asmlinkage int  __down_interruptible_failed (void /* special register calling convention */);
+asmlinkage int  __down_failed_trylock(void  /* params in registers */);
 asmlinkage void __up_wakeup (void /* special register calling convention */);
 
 extern void __down(struct semaphore * sem);
 extern int  __down_interruptible(struct semaphore * sem);
+extern int  __down_trylock(struct semaphore * sem);
 extern void __up(struct semaphore * sem);
 
 #define sema_init(sem, val)    atomic_set(&((sem)->count), (val))
 
-/*
- * These two _must_ execute atomically wrt each other.
- *
- * This is trivially done with load_locked/store_cond,
- * but on the x86 we need an external synchronizer.
- * Currently this is just the global interrupt lock,
- * bah. Go for a smaller spinlock some day.
- *
- * (On the other hand this shouldn't be in any critical
- * path, so..)
- */
-static inline void wake_one_more(struct semaphore * sem)
-{
-       unsigned long flags;
-
-       save_flags(flags);
-       cli();
-       sem->waking++;
-       restore_flags(flags);
-}
-
-static inline int waking_non_zero(struct semaphore *sem, struct task_struct *tsk)
-{
-       unsigned long flags;
-       int ret = 0;
-
-       save_flags(flags);
-       cli();
-       if (sem->waking > 0) {
-               sem->waking--;
-               ret = 1;
-       }
-       restore_flags(flags);
-       return ret;
-}
-
 #include <asm/proc/semaphore.h>
 
 #endif
index 91c08d6688698d1f62c2b714c49394a23f35c69e..2874c4661f49e851514624238c29a10253a6a202 100644 (file)
@@ -1,10 +1,26 @@
 #ifndef __ASM_ARM_SYSTEM_H
 #define __ASM_ARM_SYSTEM_H
 
+#include <linux/kernel.h>
+
+#ifdef __KERNEL__
+
 #include <linux/config.h>
 
+#define __ebsa285_data         __attribute__((__section__(".data.ebsa285")))
+#define __netwinder_data       __attribute__((__section__(".data.netwinder")))
+
+#ifdef CONFIG_TEXT_SECTIONS
+#define __ebsa285_text         __attribute__((__section__(".text.ebsa285")))
+#define __netwinder_text       __attribute__((__section__(".text.netwinder")))
+#else
+#define __ebsa285_text
+#define __netwinder_text
+#endif
+
 /* The type of machine we're running on */
-extern unsigned int machine_type;
+extern unsigned int __machine_arch_type;
+
 #define MACH_TYPE_EBSA110      0
 #define MACH_TYPE_RISCPC       1
 #define MACH_TYPE_NEXUSPCI     3
@@ -12,31 +28,101 @@ extern unsigned int machine_type;
 #define MACH_TYPE_NETWINDER    5
 #define MACH_TYPE_CATS         6
 #define MACH_TYPE_TBOX         7
+#define MACH_TYPE_CO285                8
+#define MACH_TYPE_CLPS7110     9
+#define MACH_TYPE_ARCHIMEDES   10
+#define MACH_TYPE_A5K          11
+
+/*
+ * Sort out a definition for machine_arch_type
+ * The rules basically are:
+ * 1. If one architecture is selected, then all machine_is_xxx()
+ *    are constant.
+ * 2. If two or more architectures are selected, then the selected
+ *    machine_is_xxx() are variable, and the unselected machine_is_xxx()
+ *    are constant zero.
+ */
+#ifdef CONFIG_ARCH_EBSA110
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type    __machine_arch_type
+# else
+#  define machine_arch_type    MACH_TYPE_EBSA110
+# endif
+# define machine_is_ebsa110()  (machine_arch_type == MACH_TYPE_EBSA110)
+#else
+# define machine_is_ebsa110()  (0)
+#endif
+
+#ifdef CONFIG_ARCH_RPC
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type    __machine_arch_type
+# else
+#  define machine_arch_type    MACH_TYPE_RISCPC
+# endif
+# define machine_is_riscpc()   (machine_arch_type == MACH_TYPE_RISCPC)
+#else
+# define machine_is_riscpc()   (0)
+#endif
 
 #ifdef CONFIG_ARCH_EBSA285
-#define machine_is_ebsa285()   (1)
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type    __machine_arch_type
+# else
+#  define machine_arch_type    MACH_TYPE_EBSA285
+# endif
+# define machine_is_ebsa285()  (machine_arch_type == MACH_TYPE_EBSA285)
 #else
-#define machine_is_ebsa285()   (0)
+# define machine_is_ebsa285()  (0)
 #endif
 
-#ifdef CONFIG_ARCH_VNC
-#define machine_is_netwinder() (1)
+#ifdef CONFIG_ARCH_NETWINDER
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type    __machine_arch_type
+# else
+#  define machine_arch_type    MACH_TYPE_NETWINDER
+# endif
+# define machine_is_netwinder()        (machine_arch_type == MACH_TYPE_NETWINDER)
 #else
-#define machine_is_netwinder() (0)
+# define machine_is_netwinder()        (0)
 #endif
 
-#if defined(CONFIG_CATS)
-#define machine_is_cats()      (machine_type == MACH_TYPE_CATS)
+#ifdef CONFIG_CATS
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type    __machine_arch_type
+# else
+#  define machine_arch_type    MACH_TYPE_CATS
+# endif
+# define machine_is_cats()     (machine_arch_type == MACH_TYPE_CATS)
 #else
-#define machine_is_cats()      (0)
+# define machine_is_cats()     (0)
 #endif
 
-#if 0
-#define machine_is_ebsa285()   (machine_type == MACH_TYPE_EBSA285)
-#define machine_is_netwinder() (machine_type == MACH_TYPE_NETWINDER)
+#ifdef CONFIG_ARCH_CO285
+# ifdef machine_arch_type
+#  undef machine_arch_type
+#  define machine_arch_type    __machine_arch_type
+# else
+#  define machine_arch_type    MACH_TYPE_CO285
+# endif
+# define machine_is_co285()    (machine_arch_type == MACH_TYPE_CO285)
+#else
+# define machine_is_co285()    (0)
 #endif
 
-#include <linux/kernel.h>
+#ifndef machine_arch_type
+#define machine_arch_type      __machine_arch_type
+#endif
+
+/*
+ * task_struct isn't always declared - forward-declare it here.
+ */
+struct task_struct;
+
 #include <asm/proc-fns.h>
 
 extern void arm_malalignedptr(const char *, void *, volatile void *);
@@ -53,7 +139,7 @@ extern void arm_invalidptr(const char *, int);
  *
  * `next' and `prev' should be struct task_struct, but it isn't always defined
  */
-#define switch_to(prev,next) processor._switch_to(prev,next)
+#define switch_to(prev,next,last) do { last = processor._switch_to(prev,next); } while (0)
 
 /*
  * Include processor dependent parts
@@ -62,9 +148,12 @@ extern void arm_invalidptr(const char *, int);
 #include <asm/arch/system.h>
 
 #define mb() __asm__ __volatile__ ("" : : : "memory")
-#define nop() __asm__ __volatile__("mov r0,r0\n\t");
+#define rmb() mb()
+#define wmb() mb()
+#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
 
 extern asmlinkage void __backtrace(void);
 
 #endif
 
+#endif
index 601af3b0abaa4c5cc55f4b0b337f0ef0b7336fb5..86c0c28834fffe60b563eeac859f4b20806474c6 100644 (file)
 #define __NR_capset                    (__NR_SYSCALL_BASE+185)
 #define __NR_sigaltstack               (__NR_SYSCALL_BASE+186)
 #define __NR_sendfile                  (__NR_SYSCALL_BASE+187)
+                                       /* 188 reserved */
+                                       /* 189 reserved */
+#define __NR_vfork                     (__NR_SYSCALL_BASE+190)
 
 #define __sys2(x) #x
 #define __sys1(x) __sys2(x)
@@ -364,7 +367,7 @@ static inline int close(int fd)
 
 static inline int _exit(int exitcode)
 {
-       extern int sys_exit(int);
+       extern int sys_exit(int) __attribute__((noreturn));
        return sys_exit(exitcode);
 }
 
@@ -393,37 +396,11 @@ static inline pid_t wait(int * wait_stat)
 static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp);
 
 /*
- * This is the mechanism for creating a new kernel thread.
- *
- * NOTE! Only a kernel-only process(ie the swapper or direct descendants
- * who haven't done an "execve()") should use this: it will work within
- * a system call from a "real" process, but the process memory space will
- * not be free'd until both the parent and the child have exited.
+ * Create a new kernel thread
  */
-static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
-{
-       long retval;
-
-       __asm__ __volatile__("
-       mov     r0,%1
-       mov     r1,%2
-       "__syscall(clone)"
-       teq     r0, #0
-       bne     1f
-       mov     r0,%4
-       mov     lr, pc
-       mov     pc, %3
-       "__syscall(exit)"
-1:     mov %0,r0"
-        : "=r" (retval)
-        : "Ir" (flags | CLONE_VM), "Ir" (NULL), "r" (fn), "Ir" (arg)
-       : "r0","r1","r2","r3","lr");
-       
-       return retval;
-}
+extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
 
 #endif
-
 #endif /* __ASM_ARM_UNISTD_H */
 
 
index 6a9278df9c113a6c2438f84d319d46b044a82011..19c4543960d1bcf2bfbb9d2875e1f2d1a070cabf 100644 (file)
@@ -1,9 +1,10 @@
 #ifndef ASMARM_VGA_H
 #define ASMARM_VGA_H
 
+#include <asm/hardware.h>
 #include <asm/io.h>
 
-#define VGA_MAP_MEM(x) (0xe0000000 + (x))
+#define VGA_MAP_MEM(x) (PCIMEM_BASE + (x))
 
 #define vga_readb(x)   (*(x))
 #define vga_writeb(x,y)        (*(y) = (x))
index 15405b6e15b5d71fd16df48fbc02dd5aa5f247ef..84e1376b31f094cbeffc853e7b248fa113432432 100644 (file)
@@ -77,7 +77,7 @@ struct dentry {
 };
 
 struct dentry_operations {
-       int (*d_revalidate)(struct dentry *);
+       int (*d_revalidate)(struct dentry *, int);
        int (*d_hash) (struct dentry *, struct qstr *);
        int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
        void (*d_delete)(struct dentry *);
index 4d658c33eb9e081c7f835c2f04d0f0760f8ec152..ec4a0ca22611a0482401d768aefe40f0d418aeb7 100644 (file)
@@ -810,6 +810,18 @@ extern ino_t find_inode_number(struct dentry *, struct qstr *);
 #define PTR_ERR(ptr)   ((long)(ptr))
 #define IS_ERR(ptr)    ((unsigned long)(ptr) > (unsigned long)(-1000))
 
+/*
+ * The bitmask for a lookup event:
+ *  - follow links at the end
+ *  - require a directory
+ *  - ending slashes ok even for nonexistent files
+ *  - internal "there are more path compnents" flag
+ */
+#define LOOKUP_FOLLOW          (1)
+#define LOOKUP_DIRECTORY       (2)
+#define LOOKUP_SLASHOK         (4)
+#define LOOKUP_CONTINUE                (8)
+
 extern struct dentry * lookup_dentry(const char *, struct dentry *, unsigned int);
 extern struct dentry * __namei(const char *, unsigned int);
 
diff --git a/include/linux/mc146818rtc.h b/include/linux/mc146818rtc.h
deleted file mode 100644 (file)
index 0a2efb6..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/* mc146818rtc.h - register definitions for the Real-Time-Clock / CMOS RAM
- * Copyright Torsten Duwe <duwe@informatik.uni-erlangen.de> 1993
- * derived from Data Sheet, Copyright Motorola 1984 (!).
- * It was written to be part of the Linux operating system.
- */
-/* permission is hereby granted to copy, modify and redistribute this code
- * in terms of the GNU Library General Public License, Version 2 or later,
- * at your option.
- */
-
-#ifndef _MC146818RTC_H
-#define _MC146818RTC_H
-#include <asm/io.h>
-
-#ifndef RTC_PORT
-#define RTC_PORT(x)    (0x70 + (x))
-#define RTC_ALWAYS_BCD 1
-#endif
-
-#define CMOS_READ(addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-inb_p(RTC_PORT(1)); \
-})
-#define CMOS_WRITE(val, addr) ({ \
-outb_p((addr),RTC_PORT(0)); \
-outb_p((val),RTC_PORT(1)); \
-})
-
-/**********************************************************************
- * register summary
- **********************************************************************/
-#define RTC_SECONDS            0
-#define RTC_SECONDS_ALARM      1
-#define RTC_MINUTES            2
-#define RTC_MINUTES_ALARM      3
-#define RTC_HOURS              4
-#define RTC_HOURS_ALARM                5
-/* RTC_*_alarm is always true if 2 MSBs are set */
-# define RTC_ALARM_DONT_CARE   0xC0
-
-#define RTC_DAY_OF_WEEK                6
-#define RTC_DAY_OF_MONTH       7
-#define RTC_MONTH              8
-#define RTC_YEAR               9
-
-/* control registers - Moto names
- */
-#define RTC_REG_A              10
-#define RTC_REG_B              11
-#define RTC_REG_C              12
-#define RTC_REG_D              13
-
-/**********************************************************************
- * register details
- **********************************************************************/
-#define RTC_FREQ_SELECT        RTC_REG_A
-
-/* update-in-progress  - set to "1" 244 microsecs before RTC goes off the bus,
- * reset after update (may take 1.984ms @ 32768Hz RefClock) is complete,
- * totalling to a max high interval of 2.228 ms.
- */
-# define RTC_UIP               0x80
-# define RTC_DIV_CTL           0x70
-   /* divider control: refclock values 4.194 / 1.049 MHz / 32.768 kHz */
-#  define RTC_REF_CLCK_4MHZ    0x00
-#  define RTC_REF_CLCK_1MHZ    0x10
-#  define RTC_REF_CLCK_32KHZ   0x20
-   /* 2 values for divider stage reset, others for "testing purposes only" */
-#  define RTC_DIV_RESET1       0x60
-#  define RTC_DIV_RESET2       0x70
-  /* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */
-# define RTC_RATE_SELECT       0x0F
-
-/**********************************************************************/
-#define RTC_CONTROL    RTC_REG_B
-# define RTC_SET 0x80          /* disable updates for clock setting */
-# define RTC_PIE 0x40          /* periodic interrupt enable */
-# define RTC_AIE 0x20          /* alarm interrupt enable */
-# define RTC_UIE 0x10          /* update-finished interrupt enable */
-# define RTC_SQWE 0x08         /* enable square-wave output */
-# define RTC_DM_BINARY 0x04    /* all time/date values are BCD if clear */
-# define RTC_24H 0x02          /* 24 hour mode - else hours bit 7 means pm */
-# define RTC_DST_EN 0x01       /* auto switch DST - works f. USA only */
-
-/**********************************************************************/
-#define RTC_INTR_FLAGS RTC_REG_C
-/* caution - cleared by read */
-# define RTC_IRQF 0x80         /* any of the following 3 is active */
-# define RTC_PF 0x40
-# define RTC_AF 0x20
-# define RTC_UF 0x10
-
-/**********************************************************************/
-#define RTC_VALID      RTC_REG_D
-# define RTC_VRT 0x80          /* valid RAM and time */
-/**********************************************************************/
-
-/* example: !(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) 
- * determines if the following two #defines are needed
- */
-#ifndef BCD_TO_BIN
-#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
-#endif
-
-#ifndef BIN_TO_BCD
-#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
-#endif
-
-/*
- * The struct used to pass data via the following ioctl. Similar to the
- * struct tm in <time.h>, but it needs to be here so that the kernel 
- * source is self contained, allowing cross-compiles, etc. etc.
- */
-
-struct rtc_time {
-       int tm_sec;
-       int tm_min;
-       int tm_hour;
-       int tm_mday;
-       int tm_mon;
-       int tm_year;
-       int tm_wday;
-       int tm_yday;
-       int tm_isdst;
-};
-
-/*
- * ioctl calls that are permitted to the /dev/rtc interface, if 
- * CONFIG_RTC was enabled.
- */
-
-#define RTC_AIE_ON     _IO('p', 0x01)  /* Alarm int. enable on         */
-#define RTC_AIE_OFF    _IO('p', 0x02)  /* ... off                      */
-#define RTC_UIE_ON     _IO('p', 0x03)  /* Update int. enable on        */
-#define RTC_UIE_OFF    _IO('p', 0x04)  /* ... off                      */
-#define RTC_PIE_ON     _IO('p', 0x05)  /* Periodic int. enable on      */
-#define RTC_PIE_OFF    _IO('p', 0x06)  /* ... off                      */
-
-#define RTC_ALM_SET    _IOW('p', 0x07, struct rtc_time) /* Set alarm time  */
-#define RTC_ALM_READ   _IOR('p', 0x08, struct rtc_time) /* Read alarm time */
-#define RTC_RD_TIME    _IOR('p', 0x09, struct rtc_time) /* Read RTC time   */
-#define RTC_SET_TIME   _IOW('p', 0x0a, struct rtc_time) /* Set RTC time    */
-#define RTC_IRQP_READ  _IOR('p', 0x0b, unsigned long)   /* Read IRQ rate   */
-#define RTC_IRQP_SET   _IOW('p', 0x0c, unsigned long)   /* Set IRQ rate    */
-#define RTC_EPOCH_READ _IOR('p', 0x0d, unsigned long)   /* Read epoch      */
-#define RTC_EPOCH_SET  _IOW('p', 0x0e, unsigned long)   /* Set epoch       */
-
-
-#endif /* _MC146818RTC_H */
index 5bf9b9c54abcf9f6b8557b60bde156245e946fd5..af9615066ab16bd1e0b7c23a3a1b8f5f76dc87b2 100644 (file)
@@ -182,6 +182,7 @@ extern struct inode *nfs_fhget(struct dentry *, struct nfs_fh *,
 extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
 extern int nfs_revalidate(struct dentry *);
 extern int nfs_open(struct inode *, struct file *);
+extern int nfs_release(struct inode *, struct file *);
 extern int _nfs_revalidate_inode(struct nfs_server *, struct dentry *);
 
 /*