summaryrefslogtreecommitdiffstats
path: root/arch/sparc
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-02-16 01:07:24 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-02-16 01:07:24 +0000
commit95db6b748fc86297827fbd9c9ef174d491c9ad89 (patch)
tree27a92a942821cde1edda9a1b088718d436b3efe4 /arch/sparc
parent45b27b0a0652331d104c953a5b192d843fff88f8 (diff)
Merge with Linux 2.3.40.
Diffstat (limited to 'arch/sparc')
-rw-r--r--arch/sparc/ap1000/apmmu.c3
-rw-r--r--arch/sparc/config.in4
-rw-r--r--arch/sparc/defconfig38
-rw-r--r--arch/sparc/kernel/etrap.S4
-rw-r--r--arch/sparc/kernel/process.c5
-rw-r--r--arch/sparc/kernel/rtrap.S4
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c8
-rw-r--r--arch/sparc/kernel/sunos_asm.S10
-rw-r--r--arch/sparc/kernel/systbls.S52
-rw-r--r--arch/sparc/kernel/wof.S4
-rw-r--r--arch/sparc/kernel/wuf.S4
-rw-r--r--arch/sparc/lib/copy_user.S3
-rw-r--r--arch/sparc/mm/asyncd.c7
-rw-r--r--arch/sparc/mm/init.c32
-rw-r--r--arch/sparc/mm/io-unit.c10
-rw-r--r--arch/sparc/mm/iommu.c18
-rw-r--r--arch/sparc/mm/loadmmu.c5
-rw-r--r--arch/sparc/mm/srmmu.c789
-rw-r--r--arch/sparc/mm/sun4c.c83
-rw-r--r--arch/sparc/mm/viking.S50
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(&current->sigmask_lock);
+ spin_lock(&current->sigmask_lock);
flush_signals(current);
- spin_unlock_irq(&current->sigmask_lock);
+ spin_unlock(&current->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