diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-16 01:07:24 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-16 01:07:24 +0000 |
commit | 95db6b748fc86297827fbd9c9ef174d491c9ad89 (patch) | |
tree | 27a92a942821cde1edda9a1b088718d436b3efe4 /arch/sparc | |
parent | 45b27b0a0652331d104c953a5b192d843fff88f8 (diff) |
Merge with Linux 2.3.40.
Diffstat (limited to 'arch/sparc')
-rw-r--r-- | arch/sparc/ap1000/apmmu.c | 3 | ||||
-rw-r--r-- | arch/sparc/config.in | 4 | ||||
-rw-r--r-- | arch/sparc/defconfig | 38 | ||||
-rw-r--r-- | arch/sparc/kernel/etrap.S | 4 | ||||
-rw-r--r-- | arch/sparc/kernel/process.c | 5 | ||||
-rw-r--r-- | arch/sparc/kernel/rtrap.S | 4 | ||||
-rw-r--r-- | arch/sparc/kernel/sparc_ksyms.c | 8 | ||||
-rw-r--r-- | arch/sparc/kernel/sunos_asm.S | 10 | ||||
-rw-r--r-- | arch/sparc/kernel/systbls.S | 52 | ||||
-rw-r--r-- | arch/sparc/kernel/wof.S | 4 | ||||
-rw-r--r-- | arch/sparc/kernel/wuf.S | 4 | ||||
-rw-r--r-- | arch/sparc/lib/copy_user.S | 3 | ||||
-rw-r--r-- | arch/sparc/mm/asyncd.c | 7 | ||||
-rw-r--r-- | arch/sparc/mm/init.c | 32 | ||||
-rw-r--r-- | arch/sparc/mm/io-unit.c | 10 | ||||
-rw-r--r-- | arch/sparc/mm/iommu.c | 18 | ||||
-rw-r--r-- | arch/sparc/mm/loadmmu.c | 5 | ||||
-rw-r--r-- | arch/sparc/mm/srmmu.c | 789 | ||||
-rw-r--r-- | arch/sparc/mm/sun4c.c | 83 | ||||
-rw-r--r-- | arch/sparc/mm/viking.S | 50 |
20 files changed, 262 insertions, 871 deletions
diff --git a/arch/sparc/ap1000/apmmu.c b/arch/sparc/ap1000/apmmu.c index 5d852f859..425f23b8c 100644 --- a/arch/sparc/ap1000/apmmu.c +++ b/arch/sparc/ap1000/apmmu.c @@ -907,8 +907,7 @@ static void __init map_kernel(void) make_large_page((KERNBASE+phys)>>12, (phys>>12), APMMU_CACHE|APMMU_PRIV|APMMU_VALID); - init_mm.mmap->vm_start = page_offset = KERNBASE; - stack_top = page_offset - PAGE_SIZE; + init_mm.mmap->vm_start = PAGE_OFFSET; } extern unsigned long free_area_init(unsigned long, unsigned long); diff --git a/arch/sparc/config.in b/arch/sparc/config.in index 9ed06dc1f..31e126f33 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -1,9 +1,11 @@ -# $Id: config.in,v 1.79 1999/12/23 01:46:00 davem Exp $ +# $Id: config.in,v 1.80 2000/01/14 07:12:30 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # mainmenu_name "Linux/SPARC Kernel Configuration" +define_bool CONFIG_UID16 y + mainmenu_option next_comment comment 'Code maturity level options' bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig index b02a836b6..26037c33e 100644 --- a/arch/sparc/defconfig +++ b/arch/sparc/defconfig @@ -1,6 +1,7 @@ # # Automatically generated make config: don't edit # +CONFIG_UID16=y # # Code maturity level options @@ -8,28 +9,25 @@ CONFIG_EXPERIMENTAL=y # -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# # General setup # CONFIG_VT=y CONFIG_VT_CONSOLE=y -# CONFIG_AP1000 is not set # CONFIG_SMP is not set +# CONFIG_AP1000 is not set # CONFIG_SUN4 is not set # CONFIG_PCI is not set -# CONFIG_PCI_NAMES is not set # # Console drivers # CONFIG_PROM_CONSOLE=y CONFIG_FB=y + +# +# Frame-buffer support +# +CONFIG_FB=y CONFIG_DUMMY_CONSOLE=y CONFIG_FB_SBUS=y CONFIG_FB_CGSIX=y @@ -67,6 +65,7 @@ CONFIG_SUN_MOSTEK_RTC=y # CONFIG_SUN_VIDEOPIX is not set CONFIG_SUN_AURORA=m # CONFIG_TADPOLE_TS102_UCTRL is not set +# CONFIG_SUN_JSFLASH is not set # # Linux/SPARC audio subsystem (EXPERIMENTAL) @@ -82,7 +81,6 @@ CONFIG_SYSVIPC=y # CONFIG_BSD_PROCESS_ACCT is not set CONFIG_SYSCTL=y CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y CONFIG_BINFMT_MISC=m @@ -91,9 +89,17 @@ CONFIG_SUNOS_EMUL=y # CONFIG_PRINTER is not set # +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# # Floppy, IDE, and other block devices # CONFIG_BLK_DEV_FD=y +# CONFIG_BLK_DEV_IDE is not set CONFIG_BLK_DEV_MD=y CONFIG_MD_LINEAR=m CONFIG_MD_STRIPED=m @@ -239,14 +245,15 @@ CONFIG_AUTOFS_FS=m # CONFIG_ADFS_FS is not set CONFIG_AFFS_FS=m # CONFIG_HFS_FS is not set +# CONFIG_BFS_FS is not set CONFIG_FAT_FS=m CONFIG_MSDOS_FS=m # CONFIG_UMSDOS_FS is not set CONFIG_VFAT_FS=m CONFIG_EFS_FS=m +# CONFIG_CRAMFS is not set CONFIG_ISO9660_FS=m # CONFIG_JOLIET is not set -# CONFIG_UDF_FS is not set CONFIG_MINIX_FS=m # CONFIG_NTFS_FS is not set CONFIG_HPFS_FS=m @@ -256,6 +263,8 @@ CONFIG_DEVPTS_FS=y CONFIG_ROMFS_FS=m CONFIG_EXT2_FS=y CONFIG_SYSV_FS=m +# CONFIG_SYSV_FS_WRITE is not set +# CONFIG_UDF_FS is not set CONFIG_UFS_FS=m CONFIG_UFS_FS_WRITE=y @@ -265,7 +274,7 @@ CONFIG_UFS_FS_WRITE=y CONFIG_CODA_FS=m CONFIG_NFS_FS=y CONFIG_NFSD=m -# CONFIG_NFSD_SUN is not set +# CONFIG_NFSD_V3 is not set CONFIG_SUNRPC=y CONFIG_LOCKD=y CONFIG_SMB_FS=m @@ -275,7 +284,9 @@ CONFIG_NCP_FS=m # CONFIG_NCPFS_STRONG is not set # CONFIG_NCPFS_NFS_NS is not set # CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set # CONFIG_NCPFS_MOUNT_SUBDIR is not set +# CONFIG_NCPFS_NDS_DOMAINS is not set # CONFIG_NCPFS_NLS is not set # CONFIG_NCPFS_EXTRAS is not set @@ -284,9 +295,6 @@ CONFIG_NCP_FS=m # # CONFIG_PARTITION_ADVANCED is not set CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_SOLARIS_X86_PARTITION=y -# CONFIG_UNIXWARE_DISKLABEL is not set # CONFIG_SGI_PARTITION is not set CONFIG_SUN_PARTITION=y CONFIG_NLS=y diff --git a/arch/sparc/kernel/etrap.S b/arch/sparc/kernel/etrap.S index 10d7750d0..33077d99d 100644 --- a/arch/sparc/kernel/etrap.S +++ b/arch/sparc/kernel/etrap.S @@ -1,4 +1,4 @@ -/* $Id: etrap.S,v 1.30 1999/08/14 03:51:08 anton Exp $ +/* $Id: etrap.S,v 1.31 2000/01/08 16:38:18 anton Exp $ * etrap.S: Sparc trap window preparation for entry into the * Linux kernel. * @@ -278,7 +278,7 @@ tsetup_sun4c_onepage: C_LABEL(tsetup_srmmu_stackchk): /* Check results of callers andcc %sp, 0x7, %g0 */ bne trap_setup_user_stack_is_bolixed - GET_PAGE_OFFSET(glob_tmp) + sethi %hi(PAGE_OFFSET), %glob_tmp cmp %glob_tmp, %sp bleu,a 1f diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 195f26df5..1be5a02e3 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c @@ -1,4 +1,4 @@ -/* $Id: process.c,v 1.142 1999/12/27 06:08:31 anton Exp $ +/* $Id: process.c,v 1.143 2000/01/09 09:13:28 anton Exp $ * linux/arch/sparc/kernel/process.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -503,6 +503,9 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, #endif p->thread.kwim = current->thread.fork_kwim; + /* This is used for sun4c only */ + atomic_set(&p->thread.refcount, 1); + if(regs->psr & PSR_PS) { extern struct pt_regs fake_swapper_regs; diff --git a/arch/sparc/kernel/rtrap.S b/arch/sparc/kernel/rtrap.S index 7039291f0..7b056b47a 100644 --- a/arch/sparc/kernel/rtrap.S +++ b/arch/sparc/kernel/rtrap.S @@ -1,4 +1,4 @@ -/* $Id: rtrap.S,v 1.52 1999/08/14 03:51:18 anton Exp $ +/* $Id: rtrap.S,v 1.53 2000/01/08 16:38:18 anton Exp $ * rtrap.S: Return from Sparc trap low-level code. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -297,7 +297,7 @@ sun4c_rett_onepage: .globl C_LABEL(srmmu_rett_stackchk) C_LABEL(srmmu_rett_stackchk): bne ret_trap_user_stack_is_bolixed - GET_PAGE_OFFSET(g1) + sethi %hi(PAGE_OFFSET), %g1 cmp %g1, %fp bleu ret_trap_user_stack_is_bolixed mov AC_M_SFSR, %g1 diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 0c955178f..6943aa4e6 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc_ksyms.c,v 1.84 2000/01/07 18:15:14 jj Exp $ +/* $Id: sparc_ksyms.c,v 1.86 2000/01/09 10:46:49 anton Exp $ * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -123,13 +123,8 @@ EXPORT_SYMBOL_NOVERS(___down_write); EXPORT_SYMBOL_NOVERS(___up_read); EXPORT_SYMBOL_NOVERS(___up_write); -EXPORT_SYMBOL(page_offset); EXPORT_SYMBOL(sparc_valid_addr_bitmap); -#ifndef CONFIG_SUN4 -EXPORT_SYMBOL(stack_top); -#endif - /* Atomic operations. */ EXPORT_SYMBOL_PRIVATE(_atomic_add); EXPORT_SYMBOL_PRIVATE(_atomic_sub); @@ -176,7 +171,6 @@ EXPORT_SYMBOL_NOVERS(BTFIXUP_CALL(__smp_processor_id)); EXPORT_SYMBOL_NOVERS(BTFIXUP_CALL(enable_irq)); EXPORT_SYMBOL_NOVERS(BTFIXUP_CALL(disable_irq)); EXPORT_SYMBOL_NOVERS(BTFIXUP_CALL(__irq_itoa)); -EXPORT_SYMBOL_NOVERS(BTFIXUP_CALL(mmu_v2p)); EXPORT_SYMBOL_NOVERS(BTFIXUP_CALL(mmu_unlockarea)); EXPORT_SYMBOL_NOVERS(BTFIXUP_CALL(mmu_lockarea)); EXPORT_SYMBOL_NOVERS(BTFIXUP_CALL(mmu_get_scsi_sgl)); diff --git a/arch/sparc/kernel/sunos_asm.S b/arch/sparc/kernel/sunos_asm.S index 0c4e9a673..913630e66 100644 --- a/arch/sparc/kernel/sunos_asm.S +++ b/arch/sparc/kernel/sunos_asm.S @@ -1,4 +1,4 @@ -/* $Id: sunos_asm.S,v 1.14 1996/12/04 18:25:48 jj Exp $ +/* $Id: sunos_asm.S,v 1.15 2000/01/11 17:33:21 jj Exp $ * sunos_asm.S: SunOS system calls which must have a low-level * entry point to operate correctly. * @@ -33,10 +33,10 @@ C_LABEL(sunos_getpid): /* SunOS getuid() returns uid in %o0 and euid in %o1 */ .globl C_LABEL(sunos_getuid) C_LABEL(sunos_getuid): - call C_LABEL(sys_geteuid) + call C_LABEL(sys_geteuid16) nop - call C_LABEL(sys_getuid) + call C_LABEL(sys_getuid16) st %o0, [%sp + REGWIN_SZ + PT_I1] b C_LABEL(ret_sys_call) @@ -45,10 +45,10 @@ C_LABEL(sunos_getuid): /* SunOS getgid() returns gid in %o0 and egid in %o1 */ .globl C_LABEL(sunos_getgid) C_LABEL(sunos_getgid): - call C_LABEL(sys_getegid) + call C_LABEL(sys_getegid16) nop - call C_LABEL(sys_getgid) + call C_LABEL(sys_getgid16) st %o0, [%sp + REGWIN_SZ + PT_I1] b C_LABEL(ret_sys_call) diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index d4be69030..6da3c3f21 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S @@ -1,4 +1,4 @@ -/* $Id: systbls.S,v 1.88 1999/12/21 14:09:06 jj Exp $ +/* $Id: systbls.S,v 1.90 2000/01/11 17:33:20 jj Exp $ * systbls.S: System call entry point tables for OS compatibility. * The native Linux system call table lives here also. * @@ -20,30 +20,30 @@ sys_call_table: /*0*/ .long sys_nis_syscall, sys_exit, sys_fork, sys_read, sys_write /*5*/ .long sys_open, sys_close, sys_wait4, sys_creat, sys_link -/*10*/ .long sys_unlink, sunos_execv, sys_chdir, sys_chown, sys_mknod -/*15*/ .long sys_chmod, sys_lchown, sparc_brk, sys_nis_syscall, sys_lseek -/*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid +/*10*/ .long sys_unlink, sunos_execv, sys_chdir, sys_chown16, sys_mknod +/*15*/ .long sys_chmod, sys_lchown16, sparc_brk, sys_nis_syscall, sys_lseek +/*20*/ .long sys_getpid, sys_capget, sys_capset, sys_setuid16, sys_getuid16 /*25*/ .long sys_time, sys_ptrace, sys_alarm, sys_sigaltstack, sys_pause -/*30*/ .long sys_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice -/*35*/ .long sys_nis_syscall, sys_sync, sys_kill, sys_newstat, sys_sendfile -/*40*/ .long sys_newlstat, sys_dup, sys_pipe, sys_times, sys_nis_syscall -/*45*/ .long sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid -/*50*/ .long sys_getegid, sys_acct, sys_nis_syscall, sys_nis_syscall, sys_ioctl +/*30*/ .long sys_utime, sys_lchown, sys_fchown, sys_access, sys_nice +/*35*/ .long sys_chown, sys_sync, sys_kill, sys_newstat, sys_sendfile +/*40*/ .long sys_newlstat, sys_dup, sys_pipe, sys_times, sys_getuid +/*45*/ .long sys_umount, sys_setgid16, sys_getgid16, sys_signal, sys_geteuid16 +/*50*/ .long sys_getegid16, sys_acct, sys_nis_syscall, sys_getgid, sys_ioctl /*55*/ .long sys_reboot, sys_mmap2, sys_symlink, sys_readlink, sys_execve /*60*/ .long sys_umask, sys_chroot, sys_newfstat, sys_fstat64, sys_getpagesize -/*65*/ .long sys_msync, sys_vfork, sys_pread, sys_pwrite, sys_nis_syscall -/*70*/ .long sys_nis_syscall, sys_mmap, sys_nis_syscall, sys_munmap, sys_mprotect -/*75*/ .long sys_nis_syscall, sys_vhangup, sys_truncate64, sys_nis_syscall, sys_getgroups -/*80*/ .long sys_setgroups, sys_getpgrp, sys_nis_syscall, sys_setitimer, sys_ftruncate64 -/*85*/ .long sys_swapon, sys_getitimer, sys_nis_syscall, sys_sethostname, sys_nis_syscall -/*90*/ .long sys_dup2, sys_nis_syscall, sys_fcntl, sys_select, sys_nis_syscall +/*65*/ .long sys_msync, sys_vfork, sys_pread, sys_pwrite, sys_geteuid +/*70*/ .long sys_getegid, sys_mmap, sys_setreuid, sys_munmap, sys_mprotect +/*75*/ .long sys_setregid, sys_vhangup, sys_truncate64, sys_getgroups, sys_getgroups16 +/*80*/ .long sys_setgroups16, sys_getpgrp, sys_setgroups, sys_setitimer, sys_ftruncate64 +/*85*/ .long sys_swapon, sys_getitimer, sys_setuid, sys_sethostname, sys_setgid +/*90*/ .long sys_dup2, sys_setfsuid, sys_fcntl, sys_select, sys_setfsgid /*95*/ .long sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*100*/ .long sys_getpriority, sys_rt_sigreturn, sys_rt_sigaction, sys_rt_sigprocmask, sys_rt_sigpending -/*105*/ .long sys_rt_sigtimedwait, sys_rt_sigqueueinfo, sys_rt_sigsuspend, sys_nis_syscall, sys_nis_syscall -/*110*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall +/*105*/ .long sys_rt_sigtimedwait, sys_rt_sigqueueinfo, sys_rt_sigsuspend, sys_setresuid, sys_getresuid +/*110*/ .long sys_setresgid, sys_getresgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall /*115*/ .long sys_nis_syscall, sys_gettimeofday, sys_getrusage, sys_nis_syscall, sys_getcwd -/*120*/ .long sys_readv, sys_writev, sys_settimeofday, sys_fchown, sys_fchmod -/*125*/ .long sys_nis_syscall, sys_setreuid, sys_setregid, sys_rename, sys_truncate +/*120*/ .long sys_readv, sys_writev, sys_settimeofday, sys_fchown16, sys_fchmod +/*125*/ .long sys_nis_syscall, sys_setreuid16, sys_setregid16, sys_rename, sys_truncate /*130*/ .long sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall /*135*/ .long sys_nis_syscall, sys_mkdir, sys_rmdir, sys_utimes, sys_stat64 /*140*/ .long sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_getrlimit @@ -63,7 +63,7 @@ sys_call_table: /*210*/ .long sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys_sysinfo /*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys_adjtimex /*220*/ .long sys_sigprocmask, sys_create_module, sys_delete_module, sys_get_kernel_syms, sys_getpgid -/*225*/ .long sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid +/*225*/ .long sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid16, sys_setfsgid16 /*230*/ .long sys_select, sys_time, sys_nis_syscall, sys_stime, sys_nis_syscall /* "We are the Knights of the Forest of Ni!!" */ /*235*/ .long sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall @@ -83,7 +83,7 @@ sunos_sys_table: .long sys_close, sunos_wait4, sys_creat .long sys_link, sys_unlink, sunos_execv .long sys_chdir, sunos_nosys, sys_mknod - .long sys_chmod, sys_lchown, sunos_brk + .long sys_chmod, sys_lchown16, sunos_brk .long sunos_nosys, sys_lseek, sunos_getpid .long sunos_nosys, sunos_nosys, sunos_nosys .long sunos_getuid, sunos_nosys, sys_ptrace @@ -104,8 +104,8 @@ sunos_sys_table: .long sunos_nosys, sunos_sbrk, sunos_sstk .long sunos_mmap, sunos_vadvise, sys_munmap .long sys_mprotect, sunos_madvise, sys_vhangup - .long sunos_nosys, sunos_mincore, sys_getgroups - .long sys_setgroups, sys_getpgrp, sunos_setpgrp + .long sunos_nosys, sunos_mincore, sys_getgroups16 + .long sys_setgroups16, sys_getpgrp, sunos_setpgrp .long sys_setitimer, sunos_nosys, sys_swapon .long sys_getitimer, sys_gethostname, sys_sethostname .long sunos_getdtablesize, sys_dup2, sunos_nop @@ -119,9 +119,9 @@ sunos_sys_table: .long sys_sigstack, sys_recvmsg, sys_sendmsg .long sunos_nosys, sys_gettimeofday, sys_getrusage .long sunos_getsockopt, sunos_nosys, sunos_readv - .long sunos_writev, sys_settimeofday, sys_fchown - .long sys_fchmod, sys_recvfrom, sys_setreuid - .long sys_setregid, sys_rename, sys_truncate + .long sunos_writev, sys_settimeofday, sys_fchown16 + .long sys_fchmod, sys_recvfrom, sys_setreuid16 + .long sys_setregid16, sys_rename, sys_truncate .long sys_ftruncate, sys_flock, sunos_nosys .long sys_sendto, sys_shutdown, sys_socketpair .long sys_mkdir, sys_rmdir, sys_utimes diff --git a/arch/sparc/kernel/wof.S b/arch/sparc/kernel/wof.S index 2fbd15d2f..6c3a697e8 100644 --- a/arch/sparc/kernel/wof.S +++ b/arch/sparc/kernel/wof.S @@ -1,4 +1,4 @@ -/* $Id: wof.S,v 1.39 1999/08/14 03:51:35 anton Exp $ +/* $Id: wof.S,v 1.40 2000/01/08 16:38:18 anton Exp $ * wof.S: Sparc window overflow handler. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -395,7 +395,7 @@ C_LABEL(spwin_srmmu_stackchk): */ /* Check results of callers andcc %sp, 0x7, %g0 */ bne spwin_user_stack_is_bolixed - GET_PAGE_OFFSET(glob_tmp) + sethi %hi(PAGE_OFFSET), %glob_tmp cmp %glob_tmp, %sp bleu spwin_user_stack_is_bolixed mov AC_M_SFSR, %glob_tmp diff --git a/arch/sparc/kernel/wuf.S b/arch/sparc/kernel/wuf.S index 8937e48b3..512c4e79c 100644 --- a/arch/sparc/kernel/wuf.S +++ b/arch/sparc/kernel/wuf.S @@ -1,4 +1,4 @@ -/* $Id: wuf.S,v 1.38 1999/08/14 03:51:36 anton Exp $ +/* $Id: wuf.S,v 1.39 2000/01/08 16:38:18 anton Exp $ * wuf.S: Window underflow trap handler for the Sparc. * * Copyright (C) 1995 David S. Miller @@ -300,7 +300,7 @@ C_LABEL(srmmu_fwin_stackchk): /* Caller did 'andcc %sp, 0x7, %g0' */ bne fwin_user_stack_is_bolixed - GET_PAGE_OFFSET(l5) + sethi %hi(PAGE_OFFSET), %l5 /* Check if the users stack is in kernel vma, then our * trial and error technique below would succeed for diff --git a/arch/sparc/lib/copy_user.S b/arch/sparc/lib/copy_user.S index 728cbf9bd..97c55f02d 100644 --- a/arch/sparc/lib/copy_user.S +++ b/arch/sparc/lib/copy_user.S @@ -14,6 +14,7 @@ #include <asm/cprefix.h> #include <asm/ptrace.h> #include <asm/asmmacro.h> +#include <asm/page.h> #define EX(x,y,a,b,z) \ 98: x,y; \ @@ -355,7 +356,7 @@ short_aligned_end: 97: mov %o2, %g3 fixupretl: - GET_PAGE_OFFSET(g1) + sethi %hi(PAGE_OFFSET), %g1 cmp %o0, %g1 blu 1f cmp %o1, %g1 diff --git a/arch/sparc/mm/asyncd.c b/arch/sparc/mm/asyncd.c index 6ed8a3c99..569940417 100644 --- a/arch/sparc/mm/asyncd.c +++ b/arch/sparc/mm/asyncd.c @@ -1,4 +1,4 @@ -/* $Id: asyncd.c,v 1.18 1999/12/27 06:30:02 anton Exp $ +/* $Id: asyncd.c,v 1.19 2000/01/08 20:22:16 davem Exp $ * The asyncd kernel daemon. This handles paging on behalf of * processes that receive page faults due to remote (async) memory * accesses. @@ -260,10 +260,11 @@ int asyncd(void *unused) save_flags(flags); cli(); while (!async_queue) { - spin_lock_irq(¤t->sigmask_lock); + spin_lock(¤t->sigmask_lock); flush_signals(current); - spin_unlock_irq(¤t->sigmask_lock); + spin_unlock(¤t->sigmask_lock); interruptible_sleep_on(&asyncd_wait); + __sti(); cli(); } restore_flags(flags); diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c index 221496f98..817861a19 100644 --- a/arch/sparc/mm/init.c +++ b/arch/sparc/mm/init.c @@ -1,9 +1,10 @@ -/* $Id: init.c,v 1.72 1999/12/27 06:30:06 anton Exp $ +/* $Id: init.c,v 1.73 2000/01/15 00:51:26 anton Exp $ * linux/arch/sparc/mm/init.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1995 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * Copyright (C) 2000 Anton Blanchard (anton@progsoc.uts.edu.au) */ #include <linux/config.h> @@ -70,8 +71,7 @@ pte_t *__bad_pagetable(void) pte_t __bad_page(void) { memset((void *) &empty_bad_page, 0, PAGE_SIZE); - return pte_mkdirty(mk_pte_phys((((unsigned long) &empty_bad_page) - - PAGE_OFFSET + phys_base), + return pte_mkdirty(mk_pte_phys((unsigned long)__pa(&empty_bad_page) + phys_base, PAGE_SHARED)); } @@ -115,7 +115,7 @@ void __init sparc_context_init(int numctx) add_to_free_ctxlist(ctx_list_pool + ctx); } -#undef DEBUG_BOOTMEM +#define DEBUG_BOOTMEM extern unsigned long cmdline_memory_size; @@ -125,6 +125,10 @@ unsigned long __init bootmem_init(void) unsigned long end_of_phys_memory = 0UL; int i; + /* Limit maximum memory until we implement highmem for sparc */ + if (cmdline_memory_size > 0x9000000) + cmdline_memory_size = 0x9000000; + /* XXX It is a bit ambiguous here, whether we should * XXX treat the user specified mem=xxx as total wanted * XXX physical memory, or as a limit to the upper @@ -161,7 +165,7 @@ unsigned long __init bootmem_init(void) /* Start with page aligned address of last symbol in kernel * image. */ - start_pfn = PAGE_ALIGN((unsigned long) &_end) - PAGE_OFFSET; + start_pfn = (unsigned long)__pa(PAGE_ALIGN((unsigned long) &_end)); /* Adjust up to the physical address where the kernel begins. */ start_pfn += phys_base; @@ -281,8 +285,8 @@ static void __init taint_real_pages(void) unsigned long start, end; start = sp_banks[i].base_addr; - end = start + - sp_banks[i].num_bytes; + end = start + sp_banks[i].num_bytes; + while (start < end) { set_bit (start >> 20, sparc_valid_addr_bitmap); @@ -379,19 +383,17 @@ void __init mem_init(void) } memset(sparc_valid_addr_bitmap, 0, i << 2); - addr = KERNBASE; - last = PAGE_ALIGN((unsigned long)&_end); /* fix this */ - while(addr < last) { #ifdef CONFIG_BLK_DEV_INITRD + addr = __va(phys_base); + last = PAGE_ALIGN((unsigned long)&_end) + phys_base; + while(addr < last) { if (initrd_below_start_ok && addr >= initrd_start && addr < initrd_end) mem_map[MAP_NR(addr)].flags &= ~(1<<PG_reserved); else -#endif - mem_map[MAP_NR(addr)].flags |= (1<<PG_reserved); - set_bit(MAP_NR(addr) >> 8, sparc_valid_addr_bitmap); addr += PAGE_SIZE; } +#endif taint_real_pages(); @@ -444,9 +446,7 @@ void free_initmem (void) unsigned long page; struct page *p; - page = (addr + - ((unsigned long) __va(phys_base)) - - PAGE_OFFSET); + page = addr + phys_base; p = mem_map + MAP_NR(page); ClearPageReserved(p); diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 1a3476a16..90b4aee69 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c @@ -1,4 +1,4 @@ -/* $Id: io-unit.c,v 1.18 1999/12/28 04:28:55 anton Exp $ +/* $Id: io-unit.c,v 1.20 2000/01/15 00:51:27 anton Exp $ * io-unit.c: IO-UNIT specific routines for memory management. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -102,7 +102,7 @@ nexti: scan = find_next_zero_bit(iounit->bmap, limit, scan); goto nexti; iounit->rotor[j - 1] = (scan < limit) ? scan : iounit->limit[j - 1]; scan -= npages; - iopte = MKIOPTE(mmu_v2p(vaddr & PAGE_MASK)); + iopte = MKIOPTE(__pa(vaddr & PAGE_MASK)); vaddr = IOUNIT_DMA_BASE + (scan << PAGE_SHIFT) + (vaddr & ~PAGE_MASK); for (k = 0; k < npages; k++, iopte = __iopte(iopte_val(iopte) + 0x100), scan++) { set_bit(scan, iounit->bmap); @@ -190,7 +190,7 @@ static void iounit_map_dma_area(unsigned long va, __u32 addr, int len) pmdp = pmd_offset(pgdp, addr); ptep = pte_offset(pmdp, addr); - set_pte(ptep, pte_val(mk_pte(page, dvma_prot))); + set_pte(ptep, pte_val(mk_pte(mem_map + MAP_NR(page), dvma_prot))); i = ((addr - IOUNIT_DMA_BASE) >> PAGE_SHIFT); @@ -198,7 +198,7 @@ static void iounit_map_dma_area(unsigned long va, __u32 addr, int len) struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; iopte = (iopte_t *)(iounit->page_table + i); - *iopte = __iopte(MKIOPTE(mmu_v2p(page))); + *iopte = __iopte(MKIOPTE(__pa(page))); } } addr += PAGE_SIZE; @@ -284,6 +284,6 @@ __u32 iounit_map_dma_page(__u32 vaddr, void *addr, struct sbus_bus *sbus) int scan = (vaddr - IOUNIT_DMA_BASE) >> PAGE_SHIFT; struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu; - iounit->page_table[scan] = MKIOPTE(mmu_v2p(((unsigned long)addr) & PAGE_MASK)); + iounit->page_table[scan] = MKIOPTE(__pa(((unsigned long)addr) & PAGE_MASK)); return vaddr + (((unsigned long)addr) & ~PAGE_MASK); } diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 041e00c6a..5a8cc8c5b 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c @@ -1,4 +1,4 @@ -/* $Id: iommu.c,v 1.16 1999/12/28 04:28:54 anton Exp $ +/* $Id: iommu.c,v 1.18 2000/01/15 00:51:27 anton Exp $ * iommu.c: IOMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -36,13 +36,13 @@ extern void viking_mxcc_flush_page(unsigned long page); static inline void iommu_map_dvma_pages_for_iommu(struct iommu_struct *iommu) { unsigned long kern_end = (unsigned long) high_memory; - unsigned long first = page_offset; + unsigned long first = PAGE_OFFSET; unsigned long last = kern_end; iopte_t *iopte = iommu->page_table; iopte += ((first - iommu->start) >> PAGE_SHIFT); while(first <= last) { - *iopte++ = __iopte(MKIOPTE(mmu_v2p(first))); + *iopte++ = __iopte(MKIOPTE(__pa(first))); first += PAGE_SIZE; } } @@ -71,7 +71,7 @@ iommu_init(int iommund, struct sbus_bus *sbus) vers = (iommu->regs->control & IOMMU_CTRL_VERS) >> 24; tmp = iommu->regs->control; tmp &= ~(IOMMU_CTRL_RNGE); - switch(page_offset & 0xf0000000) { + switch(PAGE_OFFSET & 0xf0000000) { case 0xf0000000: tmp |= (IOMMU_RNGE_256MB | IOMMU_CTRL_ENAB); iommu->plow = iommu->start = 0xf0000000; @@ -135,7 +135,7 @@ iommu_init(int iommund, struct sbus_bus *sbus) } } flush_tlb_all(); - iommu->regs->base = mmu_v2p((unsigned long) iommu->page_table) >> 4; + iommu->regs->base = __pa((unsigned long) iommu->page_table) >> 4; iommu_invalidate(iommu->regs); sbus->iommu = iommu; @@ -241,18 +241,18 @@ static void iommu_map_dma_area(unsigned long va, __u32 addr, int len) else if (viking_flush) viking_flush_page(page); else - flush_page_to_ram(page); + __flush_page_to_ram(page); pgdp = pgd_offset(&init_mm, addr); pmdp = pmd_offset(pgdp, addr); ptep = pte_offset(pmdp, addr); - set_pte(ptep, pte_val(mk_pte(page, dvma_prot))); + set_pte(ptep, mk_pte(mem_map + MAP_NR(page), dvma_prot)); if (ipte_cache != 0) { - iopte_val(*iopte++) = MKIOPTE(mmu_v2p(page)); + iopte_val(*iopte++) = MKIOPTE(__pa(page)); } else { iopte_val(*iopte++) = - MKIOPTE(mmu_v2p(page)) & ~IOPTE_CACHE; + MKIOPTE(__pa(page)) & ~IOPTE_CACHE; } } addr += PAGE_SIZE; diff --git a/arch/sparc/mm/loadmmu.c b/arch/sparc/mm/loadmmu.c index c5fc4a7a9..3338666e8 100644 --- a/arch/sparc/mm/loadmmu.c +++ b/arch/sparc/mm/loadmmu.c @@ -1,4 +1,4 @@ -/* $Id: loadmmu.c,v 1.51 1999/08/31 06:54:35 davem Exp $ +/* $Id: loadmmu.c,v 1.53 2000/01/09 10:46:50 anton Exp $ * loadmmu.c: This code loads up all the mm function pointers once the * machine type has been determined. It also sets the static * mmu values such as PAGE_NONE, etc. @@ -19,9 +19,6 @@ #include <asm/mmu_context.h> #include <asm/oplib.h> -unsigned long page_offset = 0xf0000000; -unsigned long stack_top = 0xf0000000 - PAGE_SIZE; - struct ctx_list *ctx_list_pool; struct ctx_list ctx_free; struct ctx_list ctx_used; diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c index c365cf0d5..77e9aa841 100644 --- a/arch/sparc/mm/srmmu.c +++ b/arch/sparc/mm/srmmu.c @@ -1,10 +1,11 @@ -/* $Id: srmmu.c,v 1.199 1999/12/23 02:00:51 davem Exp $ +/* $Id: srmmu.c,v 1.203 2000/01/15 00:51:28 anton Exp $ * srmmu.c: SRMMU specific routines for memory management. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) * Copyright (C) 1995 Pete Zaitcev * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be) * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) + * Copyright (C) 1999 Anton Blanchard (anton@progsoc.uts.edu.au) */ #include <linux/config.h> @@ -16,8 +17,10 @@ #include <linux/init.h> #include <linux/blk.h> #include <linux/spinlock.h> +#include <linux/bootmem.h> #include <asm/page.h> +#include <asm/pgalloc.h> #include <asm/pgtable.h> #include <asm/io.h> #include <asm/kdebug.h> @@ -44,9 +47,6 @@ #include <asm/btfixup.h> -/* #define DEBUG_MAP_KERNEL */ -/* #define PAGESKIP_DEBUG */ - enum mbus_module srmmu_modtype; unsigned int hwbug_bitmask; int vac_cache_size; @@ -55,6 +55,8 @@ int vac_badbits; extern struct resource sparc_iomap; +extern unsigned long last_valid_pfn; + #ifdef __SMP__ #define FLUSH_BEGIN(mm) #define FLUSH_END @@ -63,9 +65,6 @@ extern struct resource sparc_iomap; #define FLUSH_END } #endif -static int phys_mem_contig; -BTFIXUPDEF_SETHI(page_contig_offset) - BTFIXUPDEF_CALL(void, ctxd_set, ctxd_t *, pgd_t *) BTFIXUPDEF_CALL(void, pmd_set, pmd_t *, pte_t *) @@ -96,95 +95,9 @@ char *srmmu_name; ctxd_t *srmmu_ctx_table_phys; ctxd_t *srmmu_context_table; -/* Don't change this without changing access to this - * in arch/sparc/mm/viking.S - */ -static struct srmmu_trans { - unsigned long vbase; - unsigned long pbase; - unsigned long size; -} srmmu_map[SPARC_PHYS_BANKS]; - -#define SRMMU_HASHSZ 256 - -/* Not static, viking.S uses it. */ -unsigned long srmmu_v2p_hash[SRMMU_HASHSZ]; -static unsigned long srmmu_p2v_hash[SRMMU_HASHSZ]; - -#define srmmu_ahashfn(addr) ((addr) >> 24) - int viking_mxcc_present = 0; static spinlock_t srmmu_context_spinlock = SPIN_LOCK_UNLOCKED; -/* Physical memory can be _very_ non-contiguous on the sun4m, especially - * the SS10/20 class machines and with the latest openprom revisions. - * So we have to do a quick lookup. - * We use the same for SS1000/SC2000 as a fall back, when phys memory is - * non-contiguous. - */ -static inline unsigned long srmmu_v2p(unsigned long vaddr) -{ - unsigned long off = srmmu_v2p_hash[srmmu_ahashfn(vaddr)]; - - return (vaddr + off); -} - -static inline unsigned long srmmu_p2v(unsigned long paddr) -{ - unsigned long off = srmmu_p2v_hash[srmmu_ahashfn(paddr)]; - - if (off != 0xffffffffUL) - return (paddr - off); - else - return 0xffffffffUL; -} - -/* Physical memory on most SS1000/SC2000 can be contiguous, so we handle that case - * as a special case to make things faster. - */ -/* FIXME: gcc is stupid here and generates very very bad code in this - * heavily used routine. So we help it a bit. */ -static inline unsigned long srmmu_c_v2p(unsigned long vaddr) -{ -#if KERNBASE != 0xf0000000 - if (vaddr >= KERNBASE) return vaddr - KERNBASE; - return vaddr - BTFIXUP_SETHI(page_contig_offset); -#else - register unsigned long kernbase; - - __asm__ ("sethi %%hi(0xf0000000), %0" : "=r"(kernbase)); - return vaddr - ((vaddr >= kernbase) ? kernbase : BTFIXUP_SETHI(page_contig_offset)); -#endif -} - -static inline unsigned long srmmu_c_p2v(unsigned long paddr) -{ -#if KERNBASE != 0xf0000000 - if (paddr < (0xfd000000 - KERNBASE)) return paddr + KERNBASE; - return (paddr + BTFIXUP_SETHI(page_contig_offset)); -#else - register unsigned long kernbase; - register unsigned long limit; - - __asm__ ("sethi %%hi(0x0d000000), %0" : "=r"(limit)); - __asm__ ("sethi %%hi(0xf0000000), %0" : "=r"(kernbase)); - - return paddr + ((paddr < limit) ? kernbase : BTFIXUP_SETHI(page_contig_offset)); -#endif -} - -/* On boxes where there is no lots_of_ram, KERNBASE is mapped to PA<0> and highest - PA is below 0x0d000000, we can optimize even more :) */ -static inline unsigned long srmmu_s_v2p(unsigned long vaddr) -{ - return vaddr - PAGE_OFFSET; -} - -static inline unsigned long srmmu_s_p2v(unsigned long paddr) -{ - return paddr + PAGE_OFFSET; -} - /* In general all page table modifications should use the V8 atomic * swap instruction. This insures the mmu and the cpu are in sync * with respect to ref/mod bits in the page tables. @@ -198,91 +111,6 @@ static inline unsigned long srmmu_swap(unsigned long *addr, unsigned long value) /* Functions really use this, not srmmu_swap directly. */ #define srmmu_set_entry(ptr, newentry) srmmu_swap((unsigned long *) (ptr), (newentry)) -#ifdef PAGESKIP_DEBUG -#define PGSKIP_DEBUG(from,to) prom_printf("PG_skip %ld->%ld\n", (long)(from), (long)(to)); printk("PG_skip %ld->%ld\n", (long)(from), (long)(to)) -#else -#define PGSKIP_DEBUG(from,to) do { } while (0) -#endif - -void __init srmmu_frob_mem_map(unsigned long start_mem) -{ - unsigned long bank_start, bank_end = 0; - unsigned long addr; - int i; - - /* First, mark all pages as invalid. */ - for(addr = PAGE_OFFSET; MAP_NR(addr) < max_mapnr; addr += PAGE_SIZE) - mem_map[MAP_NR(addr)].flags |= (1<<PG_reserved); - - /* Next, pg[0-3] is sun4c cruft, so we can free it... */ - mem_map[MAP_NR(pg0)].flags &= ~(1<<PG_reserved); - mem_map[MAP_NR(pg1)].flags &= ~(1<<PG_reserved); - mem_map[MAP_NR(pg2)].flags &= ~(1<<PG_reserved); - mem_map[MAP_NR(pg3)].flags &= ~(1<<PG_reserved); - - start_mem = PAGE_ALIGN(start_mem); - for(i = 0; srmmu_map[i].size; i++) { - bank_start = srmmu_map[i].vbase; - - /* Making a one or two pages PG_skip holes - * is not necessary. We add one more because - * we must set the PG_skip flag on the first - * two mem_map[] entries for the hole. Go and - * see the mm/filemap.c:shrink_mmap() loop for - * details. -DaveM - */ - if (i && bank_start - bank_end > 3 * PAGE_SIZE) { - mem_map[MAP_NR(bank_end)].flags |= (1<<PG_skip); - mem_map[MAP_NR(bank_end)].next_hash = mem_map + MAP_NR(bank_start); - mem_map[MAP_NR(bank_end)+1UL].flags |= (1<<PG_skip); - mem_map[MAP_NR(bank_end)+1UL].next_hash = mem_map + MAP_NR(bank_start); - PGSKIP_DEBUG(MAP_NR(bank_end), MAP_NR(bank_start)); - if (bank_end > KERNBASE && bank_start < KERNBASE) { - mem_map[0].flags |= (1<<PG_skip); - mem_map[0].next_hash = mem_map + MAP_NR(bank_start); - mem_map[1].flags |= (1<<PG_skip); - mem_map[1].next_hash = mem_map + MAP_NR(bank_start); - PGSKIP_DEBUG(0, MAP_NR(bank_start)); - } - } - - bank_end = bank_start + srmmu_map[i].size; - while(bank_start < bank_end) { - set_bit(MAP_NR(bank_start) >> 8, sparc_valid_addr_bitmap); - if((bank_start >= KERNBASE) && - (bank_start < start_mem)) { - bank_start += PAGE_SIZE; - continue; - } - mem_map[MAP_NR(bank_start)].flags &= ~(1<<PG_reserved); - bank_start += PAGE_SIZE; - } - - if (bank_end == 0xfd000000) - bank_end = PAGE_OFFSET; - } - - if (bank_end < KERNBASE) { - mem_map[MAP_NR(bank_end)].flags |= (1<<PG_skip); - mem_map[MAP_NR(bank_end)].next_hash = mem_map + MAP_NR(KERNBASE); - mem_map[MAP_NR(bank_end)+1UL].flags |= (1<<PG_skip); - mem_map[MAP_NR(bank_end)+1UL].next_hash = mem_map + MAP_NR(KERNBASE); - PGSKIP_DEBUG(MAP_NR(bank_end), MAP_NR(KERNBASE)); - } else if (MAP_NR(bank_end) < max_mapnr) { - mem_map[MAP_NR(bank_end)].flags |= (1<<PG_skip); - mem_map[MAP_NR(bank_end)+1UL].flags |= (1<<PG_skip); - if (mem_map[0].flags & (1 << PG_skip)) { - mem_map[MAP_NR(bank_end)].next_hash = mem_map[0].next_hash; - mem_map[MAP_NR(bank_end)+1UL].next_hash = mem_map[0].next_hash; - PGSKIP_DEBUG(MAP_NR(bank_end), mem_map[0].next_hash - mem_map); - } else { - mem_map[MAP_NR(bank_end)].next_hash = mem_map; - mem_map[MAP_NR(bank_end)+1UL].next_hash = mem_map; - PGSKIP_DEBUG(MAP_NR(bank_end), 0); - } - } -} - /* The very generic SRMMU page table operations. */ static inline int srmmu_device_memory(unsigned long x) { @@ -290,31 +118,13 @@ static inline int srmmu_device_memory(unsigned long x) } static unsigned long srmmu_pgd_page(pgd_t pgd) -{ return srmmu_device_memory(pgd_val(pgd))?~0:srmmu_p2v((pgd_val(pgd) & SRMMU_PTD_PMASK) << 4); } +{ return srmmu_device_memory(pgd_val(pgd))?~0:(unsigned long)__va((pgd_val(pgd) & SRMMU_PTD_PMASK) << 4); } static unsigned long srmmu_pmd_page(pmd_t pmd) -{ return srmmu_device_memory(pmd_val(pmd))?~0:srmmu_p2v((pmd_val(pmd) & SRMMU_PTD_PMASK) << 4); } +{ return srmmu_device_memory(pmd_val(pmd))?~0:(unsigned long)__va((pmd_val(pmd) & SRMMU_PTD_PMASK) << 4); } -static unsigned long srmmu_pte_page(pte_t pte) -{ return srmmu_device_memory(pte_val(pte))?~0:srmmu_p2v((pte_val(pte) & SRMMU_PTE_PMASK) << 4); } - -static unsigned long srmmu_c_pgd_page(pgd_t pgd) -{ return srmmu_device_memory(pgd_val(pgd))?~0:srmmu_c_p2v((pgd_val(pgd) & SRMMU_PTD_PMASK) << 4); } - -static unsigned long srmmu_c_pmd_page(pmd_t pmd) -{ return srmmu_device_memory(pmd_val(pmd))?~0:srmmu_c_p2v((pmd_val(pmd) & SRMMU_PTD_PMASK) << 4); } - -static unsigned long srmmu_c_pte_page(pte_t pte) -{ return srmmu_device_memory(pte_val(pte))?~0:srmmu_c_p2v((pte_val(pte) & SRMMU_PTE_PMASK) << 4); } - -static unsigned long srmmu_s_pgd_page(pgd_t pgd) -{ return srmmu_device_memory(pgd_val(pgd))?~0:srmmu_s_p2v((pgd_val(pgd) & SRMMU_PTD_PMASK) << 4); } - -static unsigned long srmmu_s_pmd_page(pmd_t pmd) -{ return srmmu_device_memory(pmd_val(pmd))?~0:srmmu_s_p2v((pmd_val(pmd) & SRMMU_PTD_PMASK) << 4); } - -static unsigned long srmmu_s_pte_page(pte_t pte) -{ return srmmu_device_memory(pte_val(pte))?~0:srmmu_s_p2v((pte_val(pte) & SRMMU_PTE_PMASK) << 4); } +static unsigned long srmmu_pte_pagenr(pte_t pte) +{ return srmmu_device_memory(pte_val(pte))?~0:(((pte_val(pte) & SRMMU_PTE_PMASK) << 4) >> PAGE_SHIFT); } static inline int srmmu_pte_none(pte_t pte) { return !(pte_val(pte) & 0xFFFFFFF); } @@ -359,14 +169,8 @@ static inline pte_t srmmu_pte_mkyoung(pte_t pte) { return __pte(pte_val(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. */ -static pte_t srmmu_mk_pte(unsigned long page, pgprot_t pgprot) -{ return __pte(((srmmu_v2p(page)) >> 4) | pgprot_val(pgprot)); } - -static pte_t srmmu_c_mk_pte(unsigned long page, pgprot_t pgprot) -{ return __pte(((srmmu_c_v2p(page)) >> 4) | pgprot_val(pgprot)); } - -static pte_t srmmu_s_mk_pte(unsigned long page, pgprot_t pgprot) -{ return __pte(((srmmu_s_v2p(page)) >> 4) | pgprot_val(pgprot)); } +static pte_t srmmu_mk_pte(struct page *page, pgprot_t pgprot) +{ return __pte((((page - mem_map) << PAGE_SHIFT) >> 4) | pgprot_val(pgprot)); } static pte_t srmmu_mk_pte_phys(unsigned long page, pgprot_t pgprot) { return __pte(((page) >> 4) | pgprot_val(pgprot)); } @@ -378,47 +182,17 @@ static pte_t srmmu_mk_pte_io(unsigned long page, pgprot_t pgprot, int space) static void srmmu_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp) { - set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (srmmu_v2p((unsigned long) pgdp) >> 4))); + set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (__pa((unsigned long) pgdp) >> 4))); } static void srmmu_pgd_set(pgd_t * pgdp, pmd_t * pmdp) { - set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (srmmu_v2p((unsigned long) pmdp) >> 4))); + set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (__pa((unsigned long) pmdp) >> 4))); } static void srmmu_pmd_set(pmd_t * pmdp, pte_t * ptep) { - set_pte((pte_t *)pmdp, (SRMMU_ET_PTD | (srmmu_v2p((unsigned long) ptep) >> 4))); -} - -static void srmmu_c_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp) -{ - set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (srmmu_c_v2p((unsigned long) pgdp) >> 4))); -} - -static void srmmu_c_pgd_set(pgd_t * pgdp, pmd_t * pmdp) -{ - set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (srmmu_c_v2p((unsigned long) pmdp) >> 4))); -} - -static void srmmu_c_pmd_set(pmd_t * pmdp, pte_t * ptep) -{ - set_pte((pte_t *)pmdp, (SRMMU_ET_PTD | (srmmu_c_v2p((unsigned long) ptep) >> 4))); -} - -static void srmmu_s_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp) -{ - set_pte((pte_t *)ctxp, (SRMMU_ET_PTD | (srmmu_s_v2p((unsigned long) pgdp) >> 4))); -} - -static void srmmu_s_pgd_set(pgd_t * pgdp, pmd_t * pmdp) -{ - set_pte((pte_t *)pgdp, (SRMMU_ET_PTD | (srmmu_s_v2p((unsigned long) pmdp) >> 4))); -} - -static void srmmu_s_pmd_set(pmd_t * pmdp, pte_t * ptep) -{ - set_pte((pte_t *)pmdp, (SRMMU_ET_PTD | (srmmu_s_v2p((unsigned long) ptep) >> 4))); + set_pte((pte_t *)pmdp, (SRMMU_ET_PTD | (__pa((unsigned long) ptep) >> 4))); } static inline pte_t srmmu_pte_modify(pte_t pte, pgprot_t newprot) @@ -444,26 +218,6 @@ static inline pte_t *srmmu_pte_offset(pmd_t * dir, unsigned long address) return (pte_t *) srmmu_pmd_page(*dir) + ((address >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE - 1)); } -static inline pmd_t *srmmu_c_pmd_offset(pgd_t * dir, unsigned long address) -{ - return (pmd_t *) srmmu_c_pgd_page(*dir) + ((address >> SRMMU_PMD_SHIFT) & (SRMMU_PTRS_PER_PMD - 1)); -} - -static inline pte_t *srmmu_c_pte_offset(pmd_t * dir, unsigned long address) -{ - return (pte_t *) srmmu_c_pmd_page(*dir) + ((address >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE - 1)); -} - -static inline pmd_t *srmmu_s_pmd_offset(pgd_t * dir, unsigned long address) -{ - return (pmd_t *) srmmu_s_pgd_page(*dir) + ((address >> SRMMU_PMD_SHIFT) & (SRMMU_PTRS_PER_PMD - 1)); -} - -static inline pte_t *srmmu_s_pte_offset(pmd_t * dir, unsigned long address) -{ - return (pte_t *) srmmu_s_pmd_page(*dir) + ((address >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE - 1)); -} - static inline pte_t *srmmu_get_pte_fast(void) { struct page *ret; @@ -841,7 +595,7 @@ void srmmu_mapioaddr(unsigned long physaddr, unsigned long virt_addr, int bus_ty tmp |= SRMMU_PRIV_RDONLY; else tmp |= SRMMU_PRIV; - flush_page_to_ram(virt_addr); + __flush_page_to_ram(virt_addr); set_pte(ptep, __pte(tmp)); flush_tlb_all(); } @@ -857,7 +611,7 @@ void srmmu_unmapioaddr(unsigned long virt_addr) ptep = pte_offset(pmdp, virt_addr); /* No need to flush uncacheable page. */ - set_pte(ptep, mk_pte((unsigned long) EMPTY_PGE, PAGE_SHARED)); + pte_clear(ptep); flush_tlb_all(); } @@ -879,6 +633,11 @@ static void srmmu_free_task_struct(struct task_struct *tsk) free_pages((unsigned long)tsk, 1); } +static void srmmu_get_task_struct(struct task_struct *tsk) +{ + atomic_inc(&mem_map[MAP_NR(tsk)].count); +} + /* tsunami.S */ extern void tsunami_flush_cache_all(void); extern void tsunami_flush_cache_mm(struct mm_struct *mm); @@ -1235,8 +994,6 @@ extern void viking_flush_sig_insns(struct mm_struct *mm, unsigned long addr); extern void viking_flush_page(unsigned long page); extern void viking_mxcc_flush_page(unsigned long page); extern void viking_flush_chunk(unsigned long chunk); -extern void viking_c_flush_chunk(unsigned long chunk); -extern void viking_s_flush_chunk(unsigned long chunk); extern void viking_mxcc_flush_chunk(unsigned long chunk); extern void viking_flush_tlb_all(void); extern void viking_flush_tlb_mm(struct mm_struct *mm); @@ -1276,7 +1033,7 @@ static void srmmu_set_pte_nocache_hyper(pte_t *ptep, pte_t pteval) static void hypersparc_ctxd_set(ctxd_t *ctxp, pgd_t *pgdp) { - srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (srmmu_v2p((unsigned long) pgdp) >> 4)))); + srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (__pa((unsigned long) pgdp) >> 4)))); hypersparc_flush_page_to_ram((unsigned long)ctxp); hyper_flush_whole_icache(); } @@ -1291,57 +1048,23 @@ static void hypersparc_switch_mm(struct mm_struct *old_mm, alloc_context(old_mm, mm); spin_unlock(&srmmu_context_spinlock); ctxp = &srmmu_context_table[mm->context]; - srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (srmmu_v2p((unsigned long) mm->pgd) >> 4)))); + srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (__pa((unsigned long) mm->pgd) >> 4)))); hypersparc_flush_page_to_ram((unsigned long)ctxp); } hyper_flush_whole_icache(); srmmu_set_context(mm->context); } -static unsigned long mempool; - /* NOTE: All of this startup code assumes the low 16mb (approx.) of * kernel mappings are done with one single contiguous chunk of * ram. On small ram machines (classics mainly) we only get * around 8mb mapped for us. */ -static unsigned long kbpage; - -/* Some dirty hacks to abstract away the painful boot up init. */ -static inline unsigned long srmmu_early_paddr(unsigned long vaddr) +void __init early_pgtable_allocfail(char *type) { - return ((vaddr - KERNBASE) + kbpage); -} - -static inline void srmmu_early_pgd_set(pgd_t *pgdp, pmd_t *pmdp) -{ - set_pte((pte_t *)pgdp, __pte((SRMMU_ET_PTD | (srmmu_early_paddr((unsigned long) pmdp) >> 4)))); -} - -static inline void srmmu_early_pmd_set(pmd_t *pmdp, pte_t *ptep) -{ - set_pte((pte_t *)pmdp, __pte((SRMMU_ET_PTD | (srmmu_early_paddr((unsigned long) ptep) >> 4)))); -} - -static inline unsigned long srmmu_early_pgd_page(pgd_t pgd) -{ - return (((pgd_val(pgd) & SRMMU_PTD_PMASK) << 4) - kbpage) + KERNBASE; -} - -static inline unsigned long srmmu_early_pmd_page(pmd_t pmd) -{ - return (((pmd_val(pmd) & SRMMU_PTD_PMASK) << 4) - kbpage) + KERNBASE; -} - -static inline pmd_t *srmmu_early_pmd_offset(pgd_t *dir, unsigned long address) -{ - return (pmd_t *) srmmu_early_pgd_page(*dir) + ((address >> SRMMU_PMD_SHIFT) & (SRMMU_PTRS_PER_PMD - 1)); -} - -static inline pte_t *srmmu_early_pte_offset(pmd_t *dir, unsigned long address) -{ - return (pte_t *) srmmu_early_pmd_page(*dir) + ((address >> PAGE_SHIFT) & (SRMMU_PTRS_PER_PTE - 1)); + prom_printf("inherit_prom_mappings: Cannot alloc kernel %s.\n", type); + prom_halt(); } static inline void srmmu_allocate_ptable_skeleton(unsigned long start, unsigned long end) @@ -1353,13 +1076,20 @@ static inline void srmmu_allocate_ptable_skeleton(unsigned long start, unsigned while(start < end) { pgdp = srmmu_pgd_offset(&init_mm, start); if(srmmu_pgd_none(*pgdp)) { - pmdp = sparc_init_alloc(&mempool, SRMMU_PMD_TABLE_SIZE); - srmmu_early_pgd_set(pgdp, pmdp); + pmdp = __alloc_bootmem(SRMMU_PMD_TABLE_SIZE, + SRMMU_PMD_TABLE_SIZE, 0UL); + if (pmdp == NULL) + early_pgtable_allocfail("pmd"); + memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE); + srmmu_pgd_set(pgdp, pmdp); } - pmdp = srmmu_early_pmd_offset(pgdp, start); + pmdp = srmmu_pmd_offset(pgdp, start); if(srmmu_pmd_none(*pmdp)) { - ptep = sparc_init_alloc(&mempool, SRMMU_PTE_TABLE_SIZE); - srmmu_early_pmd_set(pmdp, ptep); + ptep = __alloc_bootmem(SRMMU_PTE_TABLE_SIZE, SRMMU_PTE_TABLE_SIZE, 0UL); + if (ptep == NULL) + early_pgtable_allocfail("pte"); + memset(ptep, 0, SRMMU_PTE_TABLE_SIZE); + srmmu_pmd_set(pmdp, ptep); } start = (start + SRMMU_PMD_SIZE) & SRMMU_PMD_MASK; } @@ -1408,94 +1138,34 @@ void __init srmmu_inherit_prom_mappings(unsigned long start,unsigned long end) continue; } if(srmmu_pgd_none(*pgdp)) { - pmdp = sparc_init_alloc(&mempool, SRMMU_PMD_TABLE_SIZE); - srmmu_early_pgd_set(pgdp, pmdp); + pmdp = __alloc_bootmem(SRMMU_PMD_TABLE_SIZE, + SRMMU_PMD_TABLE_SIZE, 0UL); + if (pmdp == NULL) + early_pgtable_allocfail("pmd"); + memset(pmdp, 0, SRMMU_PMD_TABLE_SIZE); + srmmu_pgd_set(pgdp, pmdp); } - pmdp = srmmu_early_pmd_offset(pgdp, start); + pmdp = srmmu_pmd_offset(pgdp, start); if(what == 1) { *pmdp = __pmd(prompte); start += SRMMU_PMD_SIZE; continue; } if(srmmu_pmd_none(*pmdp)) { - ptep = sparc_init_alloc(&mempool, SRMMU_PTE_TABLE_SIZE); - srmmu_early_pmd_set(pmdp, ptep); + ptep = __alloc_bootmem(SRMMU_PTE_TABLE_SIZE, SRMMU_PTE_TABLE_SIZE, 0UL); + if (ptep == NULL) + early_pgtable_allocfail("pte"); + memset(ptep, 0, SRMMU_PTE_TABLE_SIZE); + srmmu_pmd_set(pmdp, ptep); } - ptep = srmmu_early_pte_offset(pmdp, start); + ptep = srmmu_pte_offset(pmdp, start); *ptep = __pte(prompte); start += PAGE_SIZE; } } -#ifdef DEBUG_MAP_KERNEL -#define MKTRACE(foo) prom_printf foo -#else -#define MKTRACE(foo) -#endif - -static int lots_of_ram __initdata = 0; -static int srmmu_low_pa __initdata = 0; static unsigned long end_of_phys_memory __initdata = 0; -void __init srmmu_end_memory(unsigned long memory_size, unsigned long *end_mem_p) -{ - unsigned int sum = 0; - unsigned long last = 0xff000000; - long first, cur; - unsigned long pa; - unsigned long total = 0; - int i; - - pa = srmmu_hwprobe(KERNBASE + PAGE_SIZE); - pa = (pa & SRMMU_PTE_PMASK) << 4; - if (!sp_banks[0].base_addr && pa == PAGE_SIZE) { - for(i = 0; sp_banks[i].num_bytes != 0; i++) { - if (sp_banks[i].base_addr + sp_banks[i].num_bytes > 0x0d000000) - break; - } - if (!sp_banks[i].num_bytes) { - srmmu_low_pa = 1; - end_of_phys_memory = SRMMU_PGDIR_ALIGN(sp_banks[i-1].base_addr + sp_banks[i-1].num_bytes); - *end_mem_p = KERNBASE + end_of_phys_memory; - if (sp_banks[0].num_bytes >= (6 * 1024 * 1024) || end_of_phys_memory <= 0x06000000) { - /* Make sure there will be enough memory for the whole mem_map (even if sparse) */ - return; - } - } - } - for(i = 0; sp_banks[i].num_bytes != 0; i++) { - pa = sp_banks[i].base_addr; - first = (pa & (~SRMMU_PGDIR_MASK)); - cur = (sp_banks[i].num_bytes + first - SRMMU_PGDIR_SIZE); - if (cur < 0) cur = 0; - if (!first || last != (pa & SRMMU_PGDIR_MASK)) - total += SRMMU_PGDIR_SIZE; - sum += sp_banks[i].num_bytes; - if (memory_size) { - if (sum > memory_size) { - sp_banks[i].num_bytes -= - (sum - memory_size); - cur = (sp_banks[i].num_bytes + first - SRMMU_PGDIR_SIZE); - if (cur < 0) cur = 0; - total += SRMMU_PGDIR_ALIGN(cur); - sum = memory_size; - sp_banks[++i].base_addr = 0xdeadbeef; - sp_banks[i].num_bytes = 0; - break; - } - } - total += SRMMU_PGDIR_ALIGN(cur); - last = (sp_banks[i].base_addr + sp_banks[i].num_bytes - 1) & SRMMU_PGDIR_MASK; - } - if (total <= 0x0d000000) - *end_mem_p = KERNBASE + total; - else { - *end_mem_p = 0xfd000000; - lots_of_ram = 1; - } - end_of_phys_memory = total; -} - #define KERNEL_PTE(page_shifted) ((page_shifted)|SRMMU_CACHE|SRMMU_PRIV|SRMMU_VALID) /* Create a third-level SRMMU 16MB page mapping. */ @@ -1504,44 +1174,10 @@ static void __init do_large_mapping(unsigned long vaddr, unsigned long phys_base pgd_t *pgdp = srmmu_pgd_offset(&init_mm, vaddr); unsigned long big_pte; - MKTRACE(("dlm[v<%08lx>-->p<%08lx>]", vaddr, phys_base)); big_pte = KERNEL_PTE(phys_base >> 4); *pgdp = __pgd(big_pte); } -/* Look in the sp_bank for the given physical page, return the - * index number the entry was found in, or -1 for not found. - */ -static inline int find_in_spbanks(unsigned long phys_page) -{ - int entry; - - for(entry = 0; sp_banks[entry].num_bytes; entry++) { - unsigned long start = sp_banks[entry].base_addr; - unsigned long end = start + sp_banks[entry].num_bytes; - - if((start <= phys_page) && (phys_page < end)) - return entry; - } - return -1; -} - -/* Find an spbank entry not mapped as of yet, TAKEN_VECTOR is an - * array of char's, each member indicating if that spbank is mapped - * yet or not. - */ -static int __init find_free_spbank(char *taken_vector) -{ - int entry; - - for(entry = 0; sp_banks[entry].num_bytes; entry++) - if(!taken_vector[entry]) - break; - return entry; -} - -static unsigned long map_spbank_last_pa __initdata = 0xff000000; - /* Map sp_bank entry SP_ENTRY, starting at virtual address VBASE. */ static unsigned long __init map_spbank(unsigned long vbase, int sp_entry) @@ -1549,20 +1185,11 @@ static unsigned long __init map_spbank(unsigned long vbase, int sp_entry) unsigned long pstart = (sp_banks[sp_entry].base_addr & SRMMU_PGDIR_MASK); unsigned long vstart = (vbase & SRMMU_PGDIR_MASK); unsigned long vend = SRMMU_PGDIR_ALIGN(vbase + sp_banks[sp_entry].num_bytes); - static int srmmu_bank = 0; - MKTRACE(("map_spbank %d[v<%08lx>p<%08lx>s<%08lx>]", sp_entry, vbase, sp_banks[sp_entry].base_addr, sp_banks[sp_entry].num_bytes)); - MKTRACE(("map_spbank2 %d[p%08lx v%08lx-%08lx]", sp_entry, pstart, vstart, vend)); while(vstart < vend) { do_large_mapping(vstart, pstart); vstart += SRMMU_PGDIR_SIZE; pstart += SRMMU_PGDIR_SIZE; } - srmmu_map[srmmu_bank].vbase = vbase; - srmmu_map[srmmu_bank].pbase = sp_banks[sp_entry].base_addr; - srmmu_map[srmmu_bank].size = sp_banks[sp_entry].num_bytes; - if (srmmu_map[srmmu_bank].size) - srmmu_bank++; - map_spbank_last_pa = pstart - SRMMU_PGDIR_SIZE; return vstart; } @@ -1573,251 +1200,35 @@ static inline void memprobe_error(char *msg) prom_halt(); } -/* Assumptions: The bank given to the kernel from the prom/bootloader - * is part of a full bank which is at least 4MB in size and begins at - * 0xf0000000 (ie. KERNBASE). - */ static inline void map_kernel(void) { - unsigned long raw_pte, physpage; - unsigned long vaddr, low_base; - char etaken[SPARC_PHYS_BANKS]; - int entry; - - /* Step 1: Clear out sp_banks taken map. */ - MKTRACE(("map_kernel: clearing etaken vector... ")); - for(entry = 0; entry < SPARC_PHYS_BANKS; entry++) - etaken[entry] = 0; - - low_base = KERNBASE; - - /* Step 2: Fill in KERNBASE base pgd. Lots of sanity checking here. */ - raw_pte = srmmu_hwprobe(KERNBASE + PAGE_SIZE); - if((raw_pte & SRMMU_ET_MASK) != SRMMU_ET_PTE) - memprobe_error("Wheee, kernel not mapped at all by boot loader.\n"); - physpage = (raw_pte & SRMMU_PTE_PMASK) << 4; - physpage -= PAGE_SIZE; - if(physpage & ~(SRMMU_PGDIR_MASK)) - memprobe_error("Wheee, kernel not mapped on 16MB physical boundry.\n"); - entry = find_in_spbanks(physpage); - if(entry == -1 || (sp_banks[entry].base_addr != physpage)) - memprobe_error("Kernel mapped in non-existant memory.\n"); - MKTRACE(("map_kernel: map_spbank(vbase=%08x, entry<%d>)[%08lx,%08lx]\n", KERNBASE, entry, sp_banks[entry].base_addr, sp_banks[entry].num_bytes)); - if (sp_banks[entry].num_bytes > 0x0d000000) { - unsigned long orig_base = sp_banks[entry].base_addr; - unsigned long orig_len = sp_banks[entry].num_bytes; - unsigned long can_map = 0x0d000000; - - /* Map a partial bank in this case, adjust the base - * and the length, but don't mark it used. - */ - sp_banks[entry].num_bytes = can_map; - MKTRACE(("wheee really big mapping [%08lx,%08lx]", orig_base, can_map)); - vaddr = map_spbank(KERNBASE, entry); - MKTRACE(("vaddr now %08lx ", vaddr)); - sp_banks[entry].base_addr = orig_base + can_map; - sp_banks[entry].num_bytes = orig_len - can_map; - MKTRACE(("adjust[%08lx,%08lx]\n", (orig_base + can_map), (orig_len - can_map))); - MKTRACE(("map_kernel: skipping first loop\n")); - goto loop_skip; - } - vaddr = map_spbank(KERNBASE, entry); - etaken[entry] = 1; - - /* Step 3: Map what we can above KERNBASE. */ - MKTRACE(("map_kernel: vaddr=%08lx, entering first loop\n", vaddr)); - for(;;) { - unsigned long bank_size; - - MKTRACE(("map_kernel: ffsp()")); - entry = find_free_spbank(&etaken[0]); - bank_size = sp_banks[entry].num_bytes; - MKTRACE(("<%d> base=%08lx bs=%08lx ", entry, sp_banks[entry].base_addr, bank_size)); - if(!bank_size) - break; - if (srmmu_low_pa) - vaddr = KERNBASE + sp_banks[entry].base_addr; - else if (sp_banks[entry].base_addr & (~SRMMU_PGDIR_MASK)) { - if (map_spbank_last_pa == (sp_banks[entry].base_addr & SRMMU_PGDIR_MASK)) - vaddr -= SRMMU_PGDIR_SIZE; - vaddr += (sp_banks[entry].base_addr & (~SRMMU_PGDIR_MASK)); - } - if ((vaddr + bank_size - KERNBASE) > 0x0d000000) { - unsigned long orig_base = sp_banks[entry].base_addr; - unsigned long orig_len = sp_banks[entry].num_bytes; - unsigned long can_map = (0xfd000000 - vaddr); - - /* Map a partial bank in this case, adjust the base - * and the length, but don't mark it used. - */ - sp_banks[entry].num_bytes = can_map; - MKTRACE(("wheee really big mapping [%08lx,%08lx]", orig_base, can_map)); - vaddr = map_spbank(vaddr, entry); - MKTRACE(("vaddr now %08lx ", vaddr)); - sp_banks[entry].base_addr = orig_base + can_map; - sp_banks[entry].num_bytes = orig_len - can_map; - MKTRACE(("adjust[%08lx,%08lx]\n", (orig_base + can_map), (orig_len - can_map))); - break; - } - - /* Ok, we can map this one, do it. */ - MKTRACE(("map_spbank(%08lx,entry<%d>) ", vaddr, entry)); - vaddr = map_spbank(vaddr, entry); - etaken[entry] = 1; - MKTRACE(("vaddr now %08lx\n", vaddr)); - } - MKTRACE(("\n")); - /* If not lots_of_ram, assume we did indeed map it all above. */ -loop_skip: - if(!lots_of_ram) - goto check_and_return; - - /* Step 4: Map the rest (if any) right below KERNBASE. */ - MKTRACE(("map_kernel: doing low mappings... ")); - low_base = (KERNBASE - end_of_phys_memory + 0x0d000000); - MKTRACE(("end_of_phys_memory=%08lx low_base=%08lx\n", end_of_phys_memory, low_base)); - - /* Ok, now map 'em. */ - MKTRACE(("map_kernel: Allocate pt skeleton (%08lx, %08x)\n",low_base,KERNBASE)); - srmmu_allocate_ptable_skeleton(low_base, KERNBASE); - vaddr = low_base; - map_spbank_last_pa = 0xff000000; - MKTRACE(("map_kernel: vaddr=%08lx Entering second loop for low maps.\n", vaddr)); - for(;;) { - unsigned long bank_size; - - entry = find_free_spbank(&etaken[0]); - bank_size = sp_banks[entry].num_bytes; - MKTRACE(("map_kernel: e<%d> base=%08lx bs=%08lx ", entry, sp_banks[entry].base_addr, bank_size)); - if(!bank_size) - break; - if (sp_banks[entry].base_addr & (~SRMMU_PGDIR_MASK)) { - if (map_spbank_last_pa == (sp_banks[entry].base_addr & SRMMU_PGDIR_MASK)) - vaddr -= SRMMU_PGDIR_SIZE; - vaddr += (sp_banks[entry].base_addr & (~SRMMU_PGDIR_MASK)); - } - if((vaddr + bank_size) > KERNBASE) - memprobe_error("Wheee, kernel low mapping overflow.\n"); - MKTRACE(("map_spbank(%08lx, %d) ", vaddr, entry)); - vaddr = map_spbank(vaddr, entry); - etaken[entry] = 1; - MKTRACE(("Now, vaddr=%08lx end_of_phys_memory=%08lx\n", vaddr, end_of_phys_memory)); - } - MKTRACE(("\n")); - -check_and_return: - /* Step 5: Sanity check, make sure we did it all. */ - MKTRACE(("check_and_return: ")); - for(entry = 0; sp_banks[entry].num_bytes; entry++) { - MKTRACE(("e[%d]=%d ", entry, etaken[entry])); - if(!etaken[entry]) { - MKTRACE(("oops\n")); - memprobe_error("Some bank did not get mapped.\n"); - } - } - MKTRACE(("success\n")); - init_mm.mmap->vm_start = page_offset = low_base; - stack_top = page_offset - PAGE_SIZE; - BTFIXUPSET_SETHI(page_offset, low_base); - BTFIXUPSET_SETHI(stack_top, page_offset - PAGE_SIZE); - BTFIXUPSET_SIMM13(user_ptrs_per_pgd, page_offset / SRMMU_PGDIR_SIZE); - -#if 1 - for(entry = 0; srmmu_map[entry].size; entry++) { - printk("[%d]: v[%08lx,%08lx](%lx) p[%08lx]\n", entry, - srmmu_map[entry].vbase, - srmmu_map[entry].vbase + srmmu_map[entry].size, - srmmu_map[entry].size, - srmmu_map[entry].pbase); - } -#endif + int i; - /* Now setup the p2v/v2p hash tables. */ - for(entry = 0; entry < SRMMU_HASHSZ; entry++) - srmmu_v2p_hash[entry] = ((0xff - entry) << 24); - for(entry = 0; entry < SRMMU_HASHSZ; entry++) - srmmu_p2v_hash[entry] = 0xffffffffUL; - for(entry = 0; srmmu_map[entry].size; entry++) { - unsigned long addr; - - for(addr = srmmu_map[entry].vbase; - addr < (srmmu_map[entry].vbase + srmmu_map[entry].size); - addr += (1 << 24)) - srmmu_v2p_hash[srmmu_ahashfn(addr)] = - srmmu_map[entry].pbase - srmmu_map[entry].vbase; - for(addr = srmmu_map[entry].pbase; - addr < (srmmu_map[entry].pbase + srmmu_map[entry].size); - addr += (1 << 24)) - srmmu_p2v_hash[srmmu_ahashfn(addr)] = - srmmu_map[entry].pbase - srmmu_map[entry].vbase; + for (i = 0; sp_banks[i].num_bytes != 0; i++) { + map_spbank(__va(sp_banks[i].base_addr), i); } - BTFIXUPSET_SETHI(page_contig_offset, page_offset - (0xfd000000 - KERNBASE)); - if (srmmu_low_pa) - phys_mem_contig = 0; - else { - phys_mem_contig = 1; - for(entry = 0; srmmu_map[entry].size; entry++) - if (srmmu_map[entry].pbase != srmmu_c_v2p (srmmu_map[entry].vbase)) { - phys_mem_contig = 0; - break; - } - } - if (phys_mem_contig) { - printk ("SRMMU: Physical memory is contiguous, bypassing VA<->PA hashes.\n"); - BTFIXUPSET_CALL(pte_page, srmmu_c_pte_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_page, srmmu_c_pmd_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_page, srmmu_c_pgd_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mk_pte, srmmu_c_mk_pte, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_offset, srmmu_c_pte_offset, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_offset, srmmu_c_pmd_offset, BTFIXUPCALL_NORM); - if (BTFIXUPVAL_CALL(ctxd_set) == (unsigned long)srmmu_ctxd_set) - BTFIXUPSET_CALL(ctxd_set, srmmu_c_ctxd_set, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_set, srmmu_c_pgd_set, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_set, srmmu_c_pmd_set, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_v2p, srmmu_c_v2p, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_p2v, srmmu_c_p2v, BTFIXUPCALL_NORM); - if (BTFIXUPVAL_CALL(flush_chunk) == (unsigned long)viking_flush_chunk) - BTFIXUPSET_CALL(flush_chunk, viking_c_flush_chunk, BTFIXUPCALL_NORM); - } else if (srmmu_low_pa) { - printk ("SRMMU: Compact physical memory. Using strightforward VA<->PA translations.\n"); - BTFIXUPSET_CALL(pte_page, srmmu_s_pte_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_page, srmmu_s_pmd_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_page, srmmu_s_pgd_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mk_pte, srmmu_s_mk_pte, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_offset, srmmu_s_pte_offset, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_offset, srmmu_s_pmd_offset, BTFIXUPCALL_NORM); - if (BTFIXUPVAL_CALL(ctxd_set) == (unsigned long)srmmu_ctxd_set) - BTFIXUPSET_CALL(ctxd_set, srmmu_s_ctxd_set, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pgd_set, srmmu_s_pgd_set, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pmd_set, srmmu_s_pmd_set, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_v2p, srmmu_s_v2p, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_p2v, srmmu_s_p2v, BTFIXUPCALL_NORM); - if (BTFIXUPVAL_CALL(flush_chunk) == (unsigned long)viking_flush_chunk) - BTFIXUPSET_CALL(flush_chunk, viking_s_flush_chunk, BTFIXUPCALL_NORM); - } - btfixup(); - - return; /* SUCCESS! */ + init_mm.mmap->vm_start = PAGE_OFFSET; + BTFIXUPSET_SIMM13(user_ptrs_per_pgd, PAGE_OFFSET / SRMMU_PGDIR_SIZE); } /* Paging initialization on the Sparc Reference MMU. */ -extern unsigned long free_area_init(unsigned long, unsigned long); -extern unsigned long sparc_context_init(unsigned long, int); +extern void sparc_context_init(int); -extern int physmem_mapped_contig; extern int linux_num_cpus; void (*poke_srmmu)(void) __initdata = NULL; -unsigned long __init srmmu_paging_init(unsigned long start_mem, unsigned long end_mem) +extern unsigned long bootmem_init(void); +extern void sun_serial_setup(void); + +void __init srmmu_paging_init(void) { - unsigned long ptables_start; int i, cpunode; char node_str[128]; + unsigned long end_pfn; sparc_iomap.start = 0xfd000000; /* 16MB of IOSPACE on all sun4m's. */ - physmem_mapped_contig = 0; /* for init.c:taint_real_pages() */ if (sparc_cpu_model == sun4d) num_contexts = 65536; /* We know it is Viking */ @@ -1840,32 +1251,42 @@ unsigned long __init srmmu_paging_init(unsigned long start_mem, unsigned long en prom_halt(); } - ptables_start = mempool = PAGE_ALIGN(start_mem); memset(swapper_pg_dir, 0, PAGE_SIZE); - kbpage = srmmu_hwprobe(KERNBASE + PAGE_SIZE); - kbpage = (kbpage & SRMMU_PTE_PMASK) << 4; - kbpage -= PAGE_SIZE; - srmmu_allocate_ptable_skeleton(KERNBASE, end_mem); + last_valid_pfn = end_pfn = bootmem_init(); + + srmmu_allocate_ptable_skeleton(KERNBASE, __va(end_of_phys_memory)); #if CONFIG_SUN_IO srmmu_allocate_ptable_skeleton(sparc_iomap.start, IOBASE_END); srmmu_allocate_ptable_skeleton(DVMA_VADDR, DVMA_END); #endif - mempool = PAGE_ALIGN(mempool); + /* This does not logically belong here, but we need to + * call it at the moment we are able to use the bootmem + * allocator. + */ + sun_serial_setup(); + srmmu_inherit_prom_mappings(0xfe400000,(LINUX_OPPROM_ENDVM-PAGE_SIZE)); map_kernel(); - srmmu_context_table = sparc_init_alloc(&mempool, num_contexts*sizeof(ctxd_t)); - srmmu_ctx_table_phys = (ctxd_t *) srmmu_v2p((unsigned long) srmmu_context_table); + +#define BOOTMEM_BROKEN +#ifdef BOOTMEM_BROKEN + srmmu_context_table = __alloc_bootmem(num_contexts*sizeof(ctxd_t)*2, SMP_CACHE_BYTES, 0UL); + (unsigned long)srmmu_context_table += num_contexts*sizeof(ctxd_t); + (unsigned long)srmmu_context_table &= ~(num_contexts*sizeof(ctxd_t)-1); +#else + srmmu_context_table = __alloc_bootmem(num_contexts*sizeof(ctxd_t), num_contexts*sizeof(ctxd_t), 0UL); +#endif + + srmmu_ctx_table_phys = (ctxd_t *) __pa((unsigned long) srmmu_context_table); for(i = 0; i < num_contexts; i++) ctxd_set(&srmmu_context_table[i], swapper_pg_dir); - start_mem = PAGE_ALIGN(mempool); - flush_cache_all(); if(BTFIXUPVAL_CALL(flush_page_for_dma) == (unsigned long)viking_flush_page) { - unsigned long start = ptables_start; - unsigned long end = start_mem; + unsigned long start = (unsigned long)srmmu_context_table; + unsigned long end = PAGE_ALIGN((unsigned long)srmmu_context_table + num_contexts*sizeof(ctxd_t)); while(start < end) { viking_flush_page(start); @@ -1876,22 +1297,27 @@ unsigned long __init srmmu_paging_init(unsigned long start_mem, unsigned long en flush_tlb_all(); poke_srmmu(); - start_mem = sparc_context_init(start_mem, num_contexts); - start_mem = free_area_init(start_mem, end_mem); + sparc_context_init(num_contexts); + + { + unsigned int zones_size[MAX_NR_ZONES] = { 0, 0, 0}; + + zones_size[ZONE_DMA] = end_pfn; + free_area_init(zones_size); + } #ifdef CONFIG_BLK_DEV_INITRD /* If initial ramdisk was specified with physical address, translate it here, as the p2v translation in srmmu is not straightforward. */ if (initrd_start && initrd_start < KERNBASE) { - initrd_start = srmmu_p2v(initrd_start); - initrd_end = srmmu_p2v(initrd_end); + initrd_start = __va(initrd_start); + initrd_end = __va(initrd_end); if (initrd_end <= initrd_start) initrd_start = 0; } #endif - return PAGE_ALIGN(start_mem); } static int srmmu_mmu_info(char *buf) @@ -2012,7 +1438,7 @@ static void hypersparc_destroy_context(struct mm_struct *mm) flush_cache_mm(mm); ctxp = &srmmu_context_table[mm->context]; - srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (srmmu_v2p((unsigned long) swapper_pg_dir) >> 4)))); + srmmu_set_entry((pte_t *)ctxp, __pte((SRMMU_ET_PTD | (__pa((unsigned long) swapper_pg_dir) >> 4)))); hypersparc_flush_page_to_ram((unsigned long)ctxp); flush_tlb_mm(mm); @@ -2127,7 +1553,7 @@ static void __init init_hypersparc(void) BTFIXUPSET_CALL(flush_tlb_range, hypersparc_flush_tlb_range, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_tlb_page, hypersparc_flush_tlb_page, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_page_to_ram, hypersparc_flush_page_to_ram, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__flush_page_to_ram, hypersparc_flush_page_to_ram, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_sig_insns, hypersparc_flush_sig_insns, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_page_for_dma, hypersparc_flush_page_for_dma, BTFIXUPCALL_NOP); @@ -2201,7 +1627,7 @@ static void __init init_cypress_common(void) BTFIXUPSET_CALL(flush_chunk, cypress_flush_chunk, BTFIXUPCALL_NORM); /* local flush _only_ */ - BTFIXUPSET_CALL(flush_page_to_ram, cypress_flush_page_to_ram, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__flush_page_to_ram, cypress_flush_page_to_ram, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_sig_insns, cypress_flush_sig_insns, BTFIXUPCALL_NOP); BTFIXUPSET_CALL(flush_page_for_dma, cypress_flush_page_for_dma, BTFIXUPCALL_NOP); @@ -2315,7 +1741,7 @@ static void __init init_swift(void) BTFIXUPSET_CALL(flush_tlb_page, swift_flush_tlb_page, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_tlb_range, swift_flush_tlb_range, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_page_to_ram, swift_flush_page_to_ram, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__flush_page_to_ram, swift_flush_page_to_ram, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_sig_insns, swift_flush_sig_insns, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_page_for_dma, swift_flush_page_for_dma, BTFIXUPCALL_NORM); @@ -2475,7 +1901,7 @@ static void __init init_turbosparc(void) BTFIXUPSET_CALL(flush_tlb_page, turbosparc_flush_tlb_page, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_tlb_range, turbosparc_flush_tlb_range, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_page_to_ram, turbosparc_flush_page_to_ram, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__flush_page_to_ram, turbosparc_flush_page_to_ram, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_chunk, turbosparc_flush_chunk, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_sig_insns, turbosparc_flush_sig_insns, BTFIXUPCALL_NOP); @@ -2517,7 +1943,7 @@ static void __init init_tsunami(void) BTFIXUPSET_CALL(flush_tlb_page, tsunami_flush_tlb_page, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_tlb_range, tsunami_flush_tlb_range, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_page_to_ram, tsunami_flush_page_to_ram, BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(__flush_page_to_ram, tsunami_flush_page_to_ram, BTFIXUPCALL_NOP); BTFIXUPSET_CALL(flush_sig_insns, tsunami_flush_sig_insns, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_page_for_dma, tsunami_flush_page_for_dma, BTFIXUPCALL_NORM); @@ -2574,7 +2000,7 @@ static void __init poke_viking(void) BTFIXUPCOPY_CALL(flush_cache_mm, local_flush_cache_mm); BTFIXUPCOPY_CALL(flush_cache_range, local_flush_cache_range); BTFIXUPCOPY_CALL(flush_cache_page, local_flush_cache_page); - BTFIXUPCOPY_CALL(flush_page_to_ram, local_flush_page_to_ram); + BTFIXUPCOPY_CALL(__flush_page_to_ram, local_flush_page_to_ram); BTFIXUPCOPY_CALL(flush_sig_insns, local_flush_sig_insns); BTFIXUPCOPY_CALL(flush_page_for_dma, local_flush_page_for_dma); btfixup(); @@ -2637,7 +2063,7 @@ static void __init init_viking(void) BTFIXUPSET_CALL(flush_tlb_range, viking_flush_tlb_range, BTFIXUPCALL_NORM); } - BTFIXUPSET_CALL(flush_page_to_ram, viking_flush_page_to_ram, BTFIXUPCALL_NOP); + BTFIXUPSET_CALL(__flush_page_to_ram, viking_flush_page_to_ram, BTFIXUPCALL_NOP); BTFIXUPSET_CALL(flush_sig_insns, viking_flush_sig_insns, BTFIXUPCALL_NOP); poke_srmmu = poke_viking; @@ -2883,7 +2309,7 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_CALL(set_pte, srmmu_set_pte_cacheable, BTFIXUPCALL_SWAPO0O1); BTFIXUPSET_CALL(switch_mm, srmmu_switch_mm, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(pte_page, srmmu_pte_page, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(pte_pagenr, srmmu_pte_pagenr, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pmd_page, srmmu_pmd_page, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(pgd_page, srmmu_pgd_page, BTFIXUPCALL_NORM); @@ -2934,12 +2360,11 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_CALL(destroy_context, srmmu_destroy_context, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(mmu_info, srmmu_mmu_info, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_v2p, srmmu_v2p, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_p2v, srmmu_p2v, BTFIXUPCALL_NORM); /* Task struct and kernel stack allocating/freeing. */ BTFIXUPSET_CALL(alloc_task_struct, srmmu_alloc_task_struct, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(free_task_struct, srmmu_free_task_struct, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(get_task_struct, srmmu_get_task_struct, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(quick_kernel_fault, srmmu_quick_kernel_fault, BTFIXUPCALL_NORM); @@ -2966,7 +2391,7 @@ void __init ld_mmu_srmmu(void) BTFIXUPCOPY_CALL(local_flush_tlb_mm, flush_tlb_mm); BTFIXUPCOPY_CALL(local_flush_tlb_range, flush_tlb_range); BTFIXUPCOPY_CALL(local_flush_tlb_page, flush_tlb_page); - BTFIXUPCOPY_CALL(local_flush_page_to_ram, flush_page_to_ram); + BTFIXUPCOPY_CALL(local_flush_page_to_ram, __flush_page_to_ram); BTFIXUPCOPY_CALL(local_flush_sig_insns, flush_sig_insns); BTFIXUPCOPY_CALL(local_flush_page_for_dma, flush_page_for_dma); @@ -2980,7 +2405,7 @@ void __init ld_mmu_srmmu(void) BTFIXUPSET_CALL(flush_tlb_range, smp_flush_tlb_range, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_tlb_page, smp_flush_tlb_page, BTFIXUPCALL_NORM); } - BTFIXUPSET_CALL(flush_page_to_ram, smp_flush_page_to_ram, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__flush_page_to_ram, smp_flush_page_to_ram, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_sig_insns, smp_flush_sig_insns, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_page_for_dma, smp_flush_page_for_dma, BTFIXUPCALL_NORM); #endif diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c index 0530e635f..e0bd738d6 100644 --- a/arch/sparc/mm/sun4c.c +++ b/arch/sparc/mm/sun4c.c @@ -1,4 +1,4 @@ -/* $Id: sun4c.c,v 1.182 1999/12/27 06:30:04 anton Exp $ +/* $Id: sun4c.c,v 1.185 2000/01/15 00:51:32 anton Exp $ * sun4c.c: Doing in software what should be done in hardware. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -68,20 +68,6 @@ extern int num_segmaps, num_contexts; struct sun4c_vac_props sun4c_vacinfo; unsigned long sun4c_kernel_faults; -/* convert a virtual address to a physical address and vice - * versa. Easy on the 4c - */ -static unsigned long sun4c_v2p(unsigned long vaddr) -{ - return (vaddr - PAGE_OFFSET); -} - -static unsigned long sun4c_p2v(unsigned long vaddr) -{ - return (vaddr + PAGE_OFFSET); -} - - /* Invalidate every sun4c cache line tag. */ void sun4c_flush_all(void) { @@ -1162,21 +1148,23 @@ static void sun4c_free_task_struct_hw(struct task_struct *tsk) unsigned long pages = BUCKET_PTE_PAGE(sun4c_get_pte(tsaddr)); int entry = BUCKET_NUM(tsaddr); - /* We are deleting a mapping, so the flush here is mandatory. */ - sun4c_flush_page_hw(tsaddr); + if (atomic_dec_and_test(&(tsk)->thread.refcount)) { + /* We are deleting a mapping, so the flush here is mandatory. */ + sun4c_flush_page_hw(tsaddr); #ifndef CONFIG_SUN4 - sun4c_flush_page_hw(tsaddr + PAGE_SIZE); + sun4c_flush_page_hw(tsaddr + PAGE_SIZE); #endif - sun4c_put_pte(tsaddr, 0); + sun4c_put_pte(tsaddr, 0); #ifndef CONFIG_SUN4 - sun4c_put_pte(tsaddr + PAGE_SIZE, 0); + sun4c_put_pte(tsaddr + PAGE_SIZE, 0); #endif - sun4c_bucket[entry] = BUCKET_EMPTY; - if (entry < sun4c_lowbucket_avail) - sun4c_lowbucket_avail = entry; + sun4c_bucket[entry] = BUCKET_EMPTY; + if (entry < sun4c_lowbucket_avail) + sun4c_lowbucket_avail = entry; - free_pages(pages, TASK_STRUCT_ORDER); - garbage_collect(entry); + free_pages(pages, TASK_STRUCT_ORDER); + garbage_collect(entry); + } } static void sun4c_free_task_struct_sw(struct task_struct *tsk) @@ -1185,21 +1173,28 @@ static void sun4c_free_task_struct_sw(struct task_struct *tsk) unsigned long pages = BUCKET_PTE_PAGE(sun4c_get_pte(tsaddr)); int entry = BUCKET_NUM(tsaddr); - /* We are deleting a mapping, so the flush here is mandatory. */ - sun4c_flush_page_sw(tsaddr); + if (atomic_dec_and_test(&(tsk)->thread.refcount)) { + /* We are deleting a mapping, so the flush here is mandatory. */ + sun4c_flush_page_sw(tsaddr); #ifndef CONFIG_SUN4 - sun4c_flush_page_sw(tsaddr + PAGE_SIZE); + sun4c_flush_page_sw(tsaddr + PAGE_SIZE); #endif - sun4c_put_pte(tsaddr, 0); + sun4c_put_pte(tsaddr, 0); #ifndef CONFIG_SUN4 - sun4c_put_pte(tsaddr + PAGE_SIZE, 0); + sun4c_put_pte(tsaddr + PAGE_SIZE, 0); #endif - sun4c_bucket[entry] = BUCKET_EMPTY; - if (entry < sun4c_lowbucket_avail) - sun4c_lowbucket_avail = entry; + sun4c_bucket[entry] = BUCKET_EMPTY; + if (entry < sun4c_lowbucket_avail) + sun4c_lowbucket_avail = entry; - free_pages(pages, TASK_STRUCT_ORDER); - garbage_collect(entry); + free_pages(pages, TASK_STRUCT_ORDER); + garbage_collect(entry); + } +} + +static void sun4c_get_task_struct(struct task_struct *tsk) +{ + atomic_inc(&(tsk)->thread.refcount); } static void __init sun4c_init_buckets(void) @@ -1568,13 +1563,12 @@ static void sun4c_flush_cache_page_hw(struct vm_area_struct *vma, unsigned long } } -static void sun4c_flush_page_to_ram_hw(struct page *page) +static void sun4c_flush_page_to_ram_hw(unsigned long page) { unsigned long flags; - unsigned long addr = page_address(page); save_and_cli(flags); - sun4c_flush_page_hw(addr); + sun4c_flush_page_hw(page); restore_flags(flags); } @@ -1691,13 +1685,12 @@ static void sun4c_flush_cache_page_sw(struct vm_area_struct *vma, unsigned long } } -static void sun4c_flush_page_to_ram_sw(struct page *page) +static void sun4c_flush_page_to_ram_sw(unsigned long page) { unsigned long flags; - unsigned long addr = page_address(page); save_and_cli(flags); - sun4c_flush_page_sw(addr); + sun4c_flush_page_sw(page); restore_flags(flags); } @@ -2643,7 +2636,7 @@ void __init ld_mmu_sun4c(void) BTFIXUPSET_CALL(flush_cache_mm, sun4c_flush_cache_mm_hw, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_cache_range, sun4c_flush_cache_range_hw, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_cache_page, sun4c_flush_cache_page_hw, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_page_to_ram, sun4c_flush_page_to_ram_hw, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__flush_page_to_ram, sun4c_flush_page_to_ram_hw, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_tlb_mm, sun4c_flush_tlb_mm_hw, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_tlb_range, sun4c_flush_tlb_range_hw, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_tlb_page, sun4c_flush_tlb_page_hw, BTFIXUPCALL_NORM); @@ -2654,7 +2647,7 @@ void __init ld_mmu_sun4c(void) BTFIXUPSET_CALL(flush_cache_mm, sun4c_flush_cache_mm_sw, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_cache_range, sun4c_flush_cache_range_sw, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_cache_page, sun4c_flush_cache_page_sw, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(flush_page_to_ram, sun4c_flush_page_to_ram_sw, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(__flush_page_to_ram, sun4c_flush_page_to_ram_sw, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_tlb_mm, sun4c_flush_tlb_mm_sw, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_tlb_range, sun4c_flush_tlb_range_sw, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(flush_tlb_page, sun4c_flush_tlb_page_sw, BTFIXUPCALL_NORM); @@ -2731,11 +2724,9 @@ void __init ld_mmu_sun4c(void) BTFIXUPSET_CALL(mmu_flush_dma_area, sun4c_flush_dma_area, BTFIXUPCALL_NOP); BTFIXUPSET_CALL(mmu_inval_dma_area, sun4c_inval_dma_area, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_v2p, sun4c_v2p, BTFIXUPCALL_NORM); - BTFIXUPSET_CALL(mmu_p2v, sun4c_p2v, BTFIXUPCALL_NORM); - /* Task struct and kernel stack allocating/freeing. */ BTFIXUPSET_CALL(alloc_task_struct, sun4c_alloc_task_struct, BTFIXUPCALL_NORM); + BTFIXUPSET_CALL(get_task_struct, sun4c_get_task_struct, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(quick_kernel_fault, sun4c_quick_kernel_fault, BTFIXUPCALL_NORM); BTFIXUPSET_CALL(mmu_info, sun4c_mmu_info, BTFIXUPCALL_NORM); diff --git a/arch/sparc/mm/viking.S b/arch/sparc/mm/viking.S index f8959a0ac..bee2865dc 100644 --- a/arch/sparc/mm/viking.S +++ b/arch/sparc/mm/viking.S @@ -1,4 +1,4 @@ -/* $Id: viking.S,v 1.14 1999/08/14 03:51:50 anton Exp $ +/* $Id: viking.S,v 1.15 2000/01/15 00:51:36 anton Exp $ * viking.S: High speed Viking cache/mmu operations * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -35,37 +35,14 @@ sun4dsmp_flush_tlb_spin: .globl viking_flush_tlb_all, viking_flush_tlb_mm .globl viking_flush_tlb_range, viking_flush_tlb_page - .globl viking_c_flush_chunk, viking_s_flush_chunk - -viking_s_flush_chunk: - sethi %hi(KERNBASE), %g2 - ba 2f - sub %o0, %g2, %g3 - -viking_c_flush_chunk: - sethi %hi(KERNBASE), %g2 - cmp %o0, %g2 - bgeu 2f - sub %o0, %g2, %g3 - sethi BTFIXUP_SETHI(page_contig_offset), %g2 - ba 2f - sub %o0, %g2, %g3 - -viking_flush_page: viking_flush_chunk: - sethi %hi(C_LABEL(srmmu_v2p_hash)), %g2 - srl %o0, 24, %o1 - or %g2, %lo(C_LABEL(srmmu_v2p_hash)), %g2 - sll %o1, 2, %o1 - ld [%g2 + %o1], %g3 - and %o0, PAGE_MASK, %o0 - cmp %g3, -1 - be 9f - add %o0, %g3, %g3 -2: srl %g3, 12, %g1 ! ppage >> 12 +viking_flush_page: + sethi %hi(PAGE_OFFSET), %g2 + sub %o0, %g2, %g3 + srl %g3, 12, %g1 ! ppage >> 12 clr %o1 ! set counter, 0 - 127 - sethi %hi(KERNBASE + PAGE_SIZE - 0x80000000), %o3 + sethi %hi(PAGE_OFFSET + PAGE_SIZE - 0x80000000), %o3 sethi %hi(0x80000000), %o4 sethi %hi(VIKING_PTAG_VALID), %o5 sethi %hi(2*PAGE_SIZE), %o0 @@ -85,7 +62,7 @@ viking_flush_chunk: andcc %g2, %o5, %g0 ! ptag VALID? be 7f - add %g4, %o3, %g2 ! (KERNBASE + PAGE_SIZE) | (set << 5) + add %g4, %o3, %g2 ! (PAGE_OFFSET + PAGE_SIZE) | (set << 5) ld [%g2], %g3 ld [%g2 + %g7], %g3 add %g2, %o0, %g2 @@ -113,16 +90,9 @@ viking_flush_chunk: nop viking_mxcc_flush_page: - sethi %hi(C_LABEL(srmmu_v2p_hash)), %g2 - srl %o0, 24, %o1 - or %g2, %lo(C_LABEL(srmmu_v2p_hash)), %g2 - sll %o1, 2, %o1 - ld [%g2 + %o1], %g3 - and %o0, PAGE_MASK, %o0 - cmp %g3, -1 - be 9f - add %o0, %g3, %g3 -2: sub %g3, -PAGE_SIZE, %g3 ! ppage + PAGE_SIZE + sethi %hi(PAGE_OFFSET), %g2 + sub %o0, %g2, %g3 + sub %g3, -PAGE_SIZE, %g3 ! ppage + PAGE_SIZE sethi %hi(MXCC_SRCSTREAM), %o3 ! assume %hi(MXCC_SRCSTREAM) == %hi(MXCC_DESTSTREAM) mov 0x10, %g2 ! set cacheable bit or %o3, %lo(MXCC_SRCSTREAM), %o2 |