summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/config.in13
-rw-r--r--arch/alpha/defconfig81
-rw-r--r--arch/alpha/kernel/core_mcpcia.c2
-rw-r--r--arch/alpha/kernel/entry.S6
-rw-r--r--arch/alpha/kernel/osf_sys.c102
-rw-r--r--arch/alpha/kernel/pci.c16
-rw-r--r--arch/alpha/mm/init.c3
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/boot/compressed/Makefile6
-rw-r--r--arch/arm/boot/compressed/head-sa1100.S65
-rw-r--r--arch/arm/boot/compressed/head-victor.S45
-rw-r--r--arch/arm/boot/compressed/head.S8
-rw-r--r--arch/arm/config.in22
-rw-r--r--arch/arm/def-configs/a5k260
-rw-r--r--arch/arm/def-configs/footbridge172
-rw-r--r--arch/arm/def-configs/rpc224
-rw-r--r--arch/arm/defconfig285
-rw-r--r--arch/arm/kernel/armksyms.c7
-rw-r--r--arch/arm/kernel/bios32.c65
-rw-r--r--arch/arm/kernel/bios32.h1
-rw-r--r--arch/arm/kernel/calls.S71
-rw-r--r--arch/arm/kernel/debug-armv.S15
-rw-r--r--arch/arm/kernel/dec21285.c4
-rw-r--r--arch/arm/kernel/entry-armo.S1
-rw-r--r--arch/arm/kernel/entry-armv.S10
-rw-r--r--arch/arm/kernel/entry-common.S129
-rw-r--r--arch/arm/kernel/head-armv.S70
-rw-r--r--arch/arm/kernel/process.c7
-rw-r--r--arch/arm/kernel/setup.c91
-rw-r--r--arch/arm/kernel/signal.c3
-rw-r--r--arch/arm/kernel/sys_arm.c84
-rw-r--r--arch/arm/kernel/time.c2
-rw-r--r--arch/arm/kernel/traps.c58
-rw-r--r--arch/arm/lib/Makefile22
-rw-r--r--arch/arm/lib/bitops.S152
-rw-r--r--arch/arm/lib/changebit.S26
-rw-r--r--arch/arm/lib/clearbit.S26
-rw-r--r--arch/arm/lib/copy_page.S35
-rw-r--r--arch/arm/lib/csumipv6.S28
-rw-r--r--arch/arm/lib/csumpartial.S64
-rw-r--r--arch/arm/lib/csumpartialcopy.S257
-rw-r--r--arch/arm/lib/csumpartialcopyuser.S (renamed from arch/arm/lib/checksum.S)327
-rw-r--r--arch/arm/lib/findbit.S65
-rw-r--r--arch/arm/lib/getconsdata.c10
-rw-r--r--arch/arm/lib/io-footbridge.S2
-rw-r--r--arch/arm/lib/memchr.S24
-rw-r--r--arch/arm/lib/memcpy.S (renamed from arch/arm/lib/string.S)255
-rw-r--r--arch/arm/lib/memset.S88
-rw-r--r--arch/arm/lib/memzero.S80
-rw-r--r--arch/arm/lib/setbit.S26
-rw-r--r--arch/arm/lib/strchr.S26
-rw-r--r--arch/arm/lib/strrchr.S25
-rw-r--r--arch/arm/lib/system.c22
-rw-r--r--arch/arm/lib/testchangebit.S25
-rw-r--r--arch/arm/lib/testclearbit.S25
-rw-r--r--arch/arm/lib/testsetbit.S25
-rw-r--r--arch/arm/lib/uaccess.S16
-rw-r--r--arch/arm/mm/fault-armv.c184
-rw-r--r--arch/arm/mm/fault-common.c15
-rw-r--r--arch/arm/mm/init.c31
-rw-r--r--arch/arm/mm/mm-armo.c14
-rw-r--r--arch/arm/mm/mm-armv.c139
-rw-r--r--arch/arm/mm/mm-sa1100.c53
-rw-r--r--arch/arm/mm/proc-arm6,7.S14
-rw-r--r--arch/arm/mm/proc-sa110.S17
-rw-r--r--arch/arm/vmlinux-armv.lds.in134
-rw-r--r--arch/i386/config.in18
-rw-r--r--arch/i386/defconfig8
-rw-r--r--arch/i386/kernel/Makefile6
-rw-r--r--arch/i386/kernel/acpi.c120
-rw-r--r--arch/i386/kernel/apic.c656
-rw-r--r--arch/i386/kernel/entry.S59
-rw-r--r--arch/i386/kernel/i386_ksyms.c7
-rw-r--r--arch/i386/kernel/i8259.c22
-rw-r--r--arch/i386/kernel/io_apic.c213
-rw-r--r--arch/i386/kernel/irq.c20
-rw-r--r--arch/i386/kernel/mpparse.c514
-rw-r--r--arch/i386/kernel/pci-i386.c87
-rw-r--r--arch/i386/kernel/pci-pc.c16
-rw-r--r--arch/i386/kernel/ptrace.c387
-rw-r--r--arch/i386/kernel/setup.c60
-rw-r--r--arch/i386/kernel/signal.c2
-rw-r--r--arch/i386/kernel/smp.c486
-rw-r--r--arch/i386/kernel/smpboot.c946
-rw-r--r--arch/i386/kernel/time.c10
-rw-r--r--arch/i386/kernel/traps.c24
-rw-r--r--arch/i386/mm/fault.c14
-rw-r--r--arch/i386/mm/init.c23
-rw-r--r--arch/i386/vmlinux.lds6
-rw-r--r--arch/m68k/atari/stram.c2
-rw-r--r--arch/m68k/config.in3
-rw-r--r--arch/m68k/kernel/entry.S63
-rw-r--r--arch/m68k/kernel/signal.c2
-rw-r--r--arch/mips64/defconfig1
-rw-r--r--arch/mips64/defconfig-ip271
-rw-r--r--arch/mips64/sgi-ip27/ip27-pci.c13
-rw-r--r--arch/ppc/Makefile3
-rw-r--r--arch/ppc/coffboot/Makefile4
-rw-r--r--arch/ppc/coffboot/chrpmain.c1
-rw-r--r--arch/ppc/coffboot/coffmain.c1
-rw-r--r--arch/ppc/config.in17
-rw-r--r--arch/ppc/configs/common_defconfig6
-rw-r--r--arch/ppc/configs/gemini_defconfig45
-rw-r--r--arch/ppc/configs/oak_defconfig79
-rw-r--r--arch/ppc/configs/pmac_defconfig1
-rw-r--r--arch/ppc/configs/walnut_defconfig77
-rw-r--r--arch/ppc/defconfig8
-rw-r--r--arch/ppc/kernel/Makefile7
-rw-r--r--arch/ppc/kernel/entry.S50
-rw-r--r--arch/ppc/kernel/gemini_pci.c6
-rw-r--r--arch/ppc/kernel/gemini_setup.c4
-rw-r--r--arch/ppc/kernel/head.S8
-rw-r--r--arch/ppc/kernel/head_4xx.S183
-rw-r--r--arch/ppc/kernel/head_8xx.S36
-rw-r--r--arch/ppc/kernel/irq.c6
-rw-r--r--arch/ppc/kernel/oak_setup.c237
-rw-r--r--arch/ppc/kernel/oak_setup.h26
-rw-r--r--arch/ppc/kernel/open_pic.c11
-rw-r--r--arch/ppc/kernel/open_pic.h1
-rw-r--r--arch/ppc/kernel/pci.c80
-rw-r--r--arch/ppc/kernel/pmac_nvram.c1
-rw-r--r--arch/ppc/kernel/pmac_time.c1
-rw-r--r--arch/ppc/kernel/ppc4xx_pic.c204
-rw-r--r--arch/ppc/kernel/ppc4xx_pic.h36
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c3
-rw-r--r--arch/ppc/kernel/process.c8
-rw-r--r--arch/ppc/kernel/setup.c139
-rw-r--r--arch/ppc/kernel/smp.c2
-rw-r--r--arch/ppc/kernel/time.c3
-rw-r--r--arch/ppc/kernel/time.h18
-rw-r--r--arch/ppc/kernel/traps.c1
-rw-r--r--arch/ppc/mm/4xx_tlb.c397
-rw-r--r--arch/ppc/mm/4xx_tlb.h35
-rw-r--r--arch/ppc/mm/init.c98
-rw-r--r--arch/ppc/mm/mem_pieces.c2
-rw-r--r--arch/ppc/treeboot/Makefile4
-rw-r--r--arch/ppc/treeboot/crt0.S2
-rw-r--r--arch/ppc/treeboot/main.c45
-rw-r--r--arch/ppc/treeboot/misc.S30
-rw-r--r--arch/ppc/xmon/start.c4
-rw-r--r--arch/ppc/xmon/xmon.c4
-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
-rw-r--r--arch/sparc64/config.in2
-rw-r--r--arch/sparc64/defconfig2
-rw-r--r--arch/sparc64/kernel/binfmt_elf32.c7
-rw-r--r--arch/sparc64/kernel/entry.S10
-rw-r--r--arch/sparc64/kernel/ioctl32.c67
-rw-r--r--arch/sparc64/kernel/pci.c7
-rw-r--r--arch/sparc64/kernel/pci_psycho.c7
-rw-r--r--arch/sparc64/kernel/pci_sabre.c3
-rw-r--r--arch/sparc64/kernel/signal32.c2
-rw-r--r--arch/sparc64/kernel/sys32.S18
-rw-r--r--arch/sparc64/kernel/sys_sparc.c9
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c493
-rw-r--r--arch/sparc64/kernel/systbls.S56
-rw-r--r--arch/sparc64/mm/asyncd.c7
-rw-r--r--arch/sparc64/solaris/entry64.S10
-rw-r--r--arch/sparc64/solaris/fs.c67
-rw-r--r--arch/sparc64/solaris/misc.c14
-rw-r--r--arch/sparc64/solaris/systbl.S8
179 files changed, 6661 insertions, 5168 deletions
diff --git a/arch/alpha/config.in b/arch/alpha/config.in
index 35e9edeb0..ce5c0853e 100644
--- a/arch/alpha/config.in
+++ b/arch/alpha/config.in
@@ -2,6 +2,9 @@
# For a description of the syntax of this configuration file,
# see the Configure script.
#
+
+define_bool CONFIG_UID16 n
+
mainmenu_name "Kernel configuration of Linux for Alpha machines"
mainmenu_option next_comment
@@ -180,6 +183,12 @@ fi
source drivers/pci/Config.in
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
+if [ "$CONFIG_HOTPLUG" = "y" ] ; then
+ source drivers/pcmcia/Config.in
+fi
+
bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
@@ -250,6 +259,10 @@ endmenu
source drivers/char/Config.in
+source drivers/usb/Config.in
+
+source drivers/misc/Config.in
+
source fs/Config.in
if [ "$CONFIG_VT" = "y" ]; then
diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig
index ba6f0070b..9365dc4e2 100644
--- a/arch/alpha/defconfig
+++ b/arch/alpha/defconfig
@@ -28,6 +28,7 @@ CONFIG_ALPHA_GENERIC=y
# CONFIG_ALPHA_EB64P is not set
# CONFIG_ALPHA_EB66 is not set
# CONFIG_ALPHA_EB66P is not set
+# CONFIG_ALPHA_EIGER is not set
# CONFIG_ALPHA_JENSEN is not set
# CONFIG_ALPHA_LX164 is not set
# CONFIG_ALPHA_MIATA is not set
@@ -44,14 +45,15 @@ CONFIG_ALPHA_GENERIC=y
# CONFIG_ALPHA_SABLE is not set
# CONFIG_ALPHA_TAKARA is not set
CONFIG_PCI=y
-CONFIG_PCI_NAMES=y
# CONFIG_SMP is not set
+CONFIG_PCI_NAMES=y
+# CONFIG_HOTPLUG is not set
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
CONFIG_KCORE_ELF=y
# CONFIG_KCORE_AOUT is not set
-CONFIG_SYSCTL=y
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
@@ -84,6 +86,7 @@ CONFIG_BLK_DEV_FD=y
# CONFIG_BLK_DEV_MD is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
CONFIG_PARIDE_PARPORT=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
@@ -92,7 +95,8 @@ CONFIG_PARIDE_PARPORT=y
#
# Networking options
#
-# CONFIG_PACKET is not set
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK is not set
# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
@@ -135,6 +139,7 @@ CONFIG_BLK_DEV_SR=y
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
# CONFIG_SCSI_MULTI_LUN is not set
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set
@@ -148,6 +153,7 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
@@ -164,6 +170,7 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_NCR53C8XX is not set
# CONFIG_SCSI_SYM53C8XX is not set
@@ -201,6 +208,7 @@ CONFIG_NET_ETHERNET=y
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
CONFIG_NET_EISA=y
# CONFIG_PCNET32 is not set
@@ -211,16 +219,27 @@ CONFIG_DE4X5=y
# CONFIG_DGRS is not set
# CONFIG_EEXPRESS_PRO100 is not set
# CONFIG_NE2K_PCI is not set
+# CONFIG_SIS900 is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
# CONFIG_NET_RADIO is not set
#
-# Token ring devices
+# Token Ring driver support
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
@@ -228,13 +247,7 @@ CONFIG_DE4X5=y
#
# Wan interfaces
#
-# CONFIG_HOSTESS_SV11 is not set
-# CONFIG_COSA is not set
-# CONFIG_SEALEVEL_4021 is not set
-# CONFIG_DLCI is not set
-# CONFIG_WAN_DRIVERS is not set
-# CONFIG_LAPBETHER is not set
-# CONFIG_X25_ASY is not set
+# CONFIG_WAN is not set
#
# Amateur Radio support
@@ -264,6 +277,11 @@ CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
# Mice
#
# CONFIG_BUSMOUSE is not set
@@ -271,7 +289,16 @@ CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
@@ -280,17 +307,25 @@ CONFIG_PSMOUSE=y
# Video For Linux
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Misc devices
+#
#
# Filesystems
@@ -298,11 +333,11 @@ CONFIG_PSMOUSE=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
+# CONFIG_CRAMFS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
# CONFIG_MINIX_FS is not set
@@ -313,6 +348,7 @@ CONFIG_DEVPTS_FS=y
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
# CONFIG_UFS_FS is not set
#
@@ -320,6 +356,7 @@ CONFIG_EXT2_FS=y
#
# CONFIG_CODA_FS is not set
CONFIG_NFS_FS=y
+# CONFIG_NFSD is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set
@@ -329,16 +366,20 @@ CONFIG_LOCKD=y
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MSDOS_PARTITION=y
CONFIG_OSF_PARTITION=y
-# CONFIG_SMD_DISKLABEL is not set
-# CONFIG_SGI_DISKLABEL is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
#
# Console drivers
#
CONFIG_VGA_CONSOLE=y
+
+#
+# Frame-buffer support
+#
# CONFIG_FB is not set
#
diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c
index 4b165940d..847958212 100644
--- a/arch/alpha/kernel/core_mcpcia.c
+++ b/arch/alpha/kernel/core_mcpcia.c
@@ -560,12 +560,14 @@ mcpcia_machine_check(unsigned long vector, unsigned long la_ptr,
switch (expected) {
case 0:
+ {
/* FIXME: how do we figure out which hose the
error was on? */
struct pci_controler *hose;
for (hose = hose_head; hose; hose = hose->next)
mcpcia_pci_clr_err(hose2mid(hose->index));
break;
+ }
case 1:
mcpcia_pci_clr_err(mcheck_extra(cpu));
break;
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 6b37bd23c..af1567fd1 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -985,9 +985,9 @@ sys_call_table:
.quad osf_utsname
.quad sys_lchown
.quad osf_shmat
- .quad sys_shmctlold /* 210 */
+ .quad sys_shmctl /* 210 */
.quad sys_shmdt
- .quad sys_shmget
+ .quad osf_shmget
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 215 */
@@ -1150,4 +1150,4 @@ sys_call_table:
.quad sys_setresgid
.quad sys_getresgid
.quad sys_ni_syscall /* sys_dipc */
- .quad sys_shmctl
+ .quad sys_shmget
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index e81687bdb..95e539d34 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -439,7 +439,7 @@ static int osf_ufs_mount(char *dirname, struct ufs_args *args, int flags)
dentry = getdev(tmp.devname, 0);
retval = PTR_ERR(dentry);
- if (IS_ERR(dentry)
+ if (IS_ERR(dentry))
goto out;
retval = do_mount(dentry->d_inode->i_bdev, tmp.devname, dirname,
"ext2", flags, NULL);
@@ -471,7 +471,6 @@ out:
static int osf_procfs_mount(char *dirname, struct procfs_args *args, int flags)
{
- int retval;
struct procfs_args tmp;
if (copy_from_user(&tmp, args, sizeof(tmp)))
@@ -1401,102 +1400,7 @@ asmlinkage int sys_old_adjtimex(struct timex32 *txc_p)
return ret;
}
-struct shmid_ds_old {
- struct ipc_perm shm_perm; /* operation perms */
- int shm_segsz; /* size of segment (bytes) */
- __kernel_time_t shm_atime; /* last attach time */
- __kernel_time_t shm_dtime; /* last detach time */
- __kernel_time_t shm_ctime; /* last change time */
- __kernel_ipc_pid_t shm_cpid; /* pid of creator */
- __kernel_ipc_pid_t shm_lpid; /* pid of last operator */
- unsigned short shm_nattch; /* no. of current attaches */
- unsigned short shm_unused; /* compatibility */
- void *shm_unused2; /* ditto - used by DIPC */
- void *shm_unused3; /* unused */
-};
-
-struct shminfo_old {
- int shmmax;
- int shmmin;
- int shmmni;
- int shmseg;
- int shmall;
-};
-
-asmlinkage long sys_shmctlold(int shmid, int cmd, struct shmid_ds_old *buf)
+asmlinkage long osf_shmget (key_t key, int size, int flag)
{
- struct shmid_ds arg;
- long ret;
- mm_segment_t old_fs;
-
- if (cmd == IPC_SET) {
- struct shmid_ds_old tbuf;
-
- if(copy_from_user (&tbuf, buf, sizeof(*buf)))
- return -EFAULT;
- arg.shm_perm = tbuf.shm_perm;
- arg.shm_segsz = tbuf.shm_segsz;
- arg.shm_atime = tbuf.shm_atime;
- arg.shm_dtime = tbuf.shm_dtime;
- arg.shm_ctime = tbuf.shm_ctime;
- arg.shm_cpid = tbuf.shm_cpid;
- arg.shm_lpid = tbuf.shm_lpid;
- arg.shm_nattch = tbuf.shm_nattch;
- arg.shm_unused = tbuf.shm_unused;
- arg.shm_unused2 = tbuf.shm_unused2;
- arg.shm_unused3 = tbuf.shm_unused3;
- }
- old_fs = get_fs ();
- set_fs (KERNEL_DS);
- ret = sys_shmctl(shmid, cmd, &arg);
- set_fs (old_fs);
- if (ret < 0)
- return(ret);
- switch(cmd) {
- case IPC_INFO:
- {
- struct shminfo *tbuf = (struct shminfo *) &arg;
- struct shminfo_old shminfo_oldst;
-
- shminfo_oldst.shmmax = (tbuf->shmmax > INT_MAX ?
- INT_MAX : tbuf->shmmax);
- shminfo_oldst.shmmin = tbuf->shmmin;
- shminfo_oldst.shmmni = tbuf->shmmni;
- shminfo_oldst.shmseg = tbuf->shmseg;
- shminfo_oldst.shmall = tbuf->shmall;
- if (copy_to_user(buf, &shminfo_oldst,
- sizeof(struct shminfo_old)))
- return -EFAULT;
- return(ret);
- }
- case SHM_INFO:
- {
- struct shm_info *tbuf = (struct shm_info *) &arg;
-
- if (copy_to_user (buf, tbuf, sizeof(struct shm_info)))
- return -EFAULT;
- return(ret);
- }
- case SHM_STAT:
- case IPC_STAT:
- {
- struct shmid_ds_old tbuf;
-
- tbuf.shm_perm = arg.shm_perm;
- tbuf.shm_segsz = arg.shm_segsz;
- tbuf.shm_atime = arg.shm_atime;
- tbuf.shm_dtime = arg.shm_dtime;
- tbuf.shm_ctime = arg.shm_ctime;
- tbuf.shm_cpid = arg.shm_cpid;
- tbuf.shm_lpid = arg.shm_lpid;
- tbuf.shm_nattch = arg.shm_nattch;
- tbuf.shm_unused = arg.shm_unused;
- tbuf.shm_unused2 = arg.shm_unused2;
- tbuf.shm_unused3 = arg.shm_unused3;
- if (copy_to_user (buf, &tbuf, sizeof(tbuf)))
- return -EFAULT;
- return(ret);
- }
- }
- return(ret);
+ return sys_shmget (key, size, flag);
}
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index 601cb9401..aa0a8d968 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -251,11 +251,13 @@ pcibios_fixup_bus(struct pci_bus *bus)
/* Propogate hose info into the subordinate devices. */
struct pci_controler *hose = (struct pci_controler *) bus->sysdata;
- struct pci_dev *dev;
+ struct list_head *ln;
bus->resource[0] = hose->io_space;
bus->resource[1] = hose->mem_space;
- for (dev = bus->devices; dev; dev = dev->sibling) {
+
+ for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) {
+ struct pci_dev *dev = pci_dev_b(ln);
if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
pcibios_fixup_device_resources(dev, bus);
}
@@ -322,6 +324,13 @@ pcibios_fixup_pbus_ranges(struct pci_bus * bus,
ranges->mem_end -= bus->resource[1]->start;
}
+int __init
+pcibios_enable_device(struct pci_dev *dev)
+{
+ /* Not needed, since we enable all devices at startup. */
+ return 0;
+}
+
void __init
common_init_pci(void)
{
@@ -339,8 +348,7 @@ common_init_pci(void)
next_busno += 1;
}
- pci_assign_unassigned_resources(alpha_mv.min_io_address,
- alpha_mv.min_mem_address);
+ pci_assign_unassigned_resources();
pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
pci_set_bus_ranges();
}
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index daaa36e09..97bb6df9d 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -274,7 +274,8 @@ srm_paging_stop (void)
}
#endif
-static void __init printk_memory_info(void)
+static void __init
+printk_memory_info(void)
{
unsigned long codesize, reservedpages, datasize, initsize, tmp;
extern int page_is_ram(unsigned long) __init;
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 2c81731b9..0df16ffa4 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -136,7 +136,7 @@ MACHINE = nexuspci
ARCHDIR = nexuspci
endif
-ifeq ($(CONFIG_ARCH_SA1100),u)
+ifeq ($(CONFIG_ARCH_SA1100),y)
MACHINE = sa1100
ARCHDIR = sa1100
endif
@@ -146,7 +146,7 @@ HEAD := arch/arm/kernel/head-$(PROCESSOR).o \
SUBDIRS += arch/arm/kernel arch/arm/mm arch/arm/lib \
arch/arm/special arch/arm/nwfpe
CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES)
-LIBS := arch/arm/lib/lib.a $(LIBS) $(GCCLIB)
+LIBS := arch/arm/lib/lib.o arch/arm/lib/lib.a $(LIBS) $(GCCLIB)
DRIVERS += arch/arm/special/special.a
ifeq ($(CONFIG_NWFPE),y)
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 8a100eb77..d2992a491 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -44,9 +44,9 @@ ZTEXTADDR = 0x40200000
ZRELADDR = 0x40008000
endif
-ifeq ($(CONFIG_ARCH_SA110),y)
+ifeq ($(CONFIG_ARCH_SA1100),y)
+OBJS += head-sa1100.o
ifeq ($(CONFIG_SA1100_VICTOR),y)
-HEAD = head-victor.o
ZTEXTADDR = 0x00002000
ZBSSADDR = 0xc0100000
else
@@ -91,7 +91,7 @@ font.o: $(FONTC)
vmlinux.lds: vmlinux.lds.in
@sed "$(SEDFLAGS)" < vmlinux.lds.in > $@
-clean:; rm -f vmlinux core piggy*
+clean:; rm -f vmlinux core piggy* vmlinux.lds
.PHONY: vmlinux.lds clean
diff --git a/arch/arm/boot/compressed/head-sa1100.S b/arch/arm/boot/compressed/head-sa1100.S
new file mode 100644
index 000000000..90018e52b
--- /dev/null
+++ b/arch/arm/boot/compressed/head-sa1100.S
@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/boot/compressed/head-sa1100.S
+ *
+ * Copyright (C) 1999 Nicolas Pitre <nico@cam.org>
+ *
+ * SA1100 specific tweaks. This is merged with head.S by the linker.
+ */
+
+#include <linux/config.h>
+
+
+ .section ".start", #alloc, #execinstr
+
+#ifndef CONFIG_ARCH_SA1100
+#error What am I doing here...
+#endif
+
+#ifdef CONFIG_SA1100_BRUTUS
+@ need to enter SVC mode
+#define angel_SWIreason_EnterSVC 0x17 /* from arm.h, in angel source */
+#define angel_SWI_ARM (0xEF123456 & 0xffffff)
+ mov r0, #angel_SWIreason_EnterSVC
+ swi #angel_SWI_ARM
+
+ @ turn off interrupts to prevent the angel from running
+ mrs r0, cpsr
+ orr r0, r0, #0xc0
+ msr cpsr, r0
+#endif
+
+#ifdef CONFIG_SA1100_VICTOR
+ @ Copy cmdline to 0xc0000000
+ mov r1, #0xc0000000
+ cmp r0, #0
+ moveq r2, #0
+1: ldrneb r2, [r0], #1
+ cmpne r2, #0
+ strb r2, [r1], #1
+ bne 1b
+#endif
+
+ @ Data cache might be active.
+ @ Be sure to flush kernel binary out of the cache,
+ @ whatever state it is, before it is turned off.
+ @ This is done by fetching through currently executed
+ @ memory to be sure we hit the same cache.
+ bic r2, pc, #0x1f
+ add r3, r2, #0x4000 @ 16 kb is quite enough...
+1: ldr r0, [r2], #32
+ teq r2, r3
+ bne 1b
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c7, c7, 0 @ flush I & D caches
+
+ @ disabling MMU, enabling I cache
+ mrc p15, 0, r0, c1, c0, 0 @ read control reg
+ bic r0, r0, #0x0d @ clear WB, DC, MMU
+ orr r0, r0, #0x1000 @ set Icache
+ mcr p15, 0, r0, c1, c0, 0
+
+ @ set registers for entry
+ mov r0, #0
+ mov r1, #16
+
+
diff --git a/arch/arm/boot/compressed/head-victor.S b/arch/arm/boot/compressed/head-victor.S
deleted file mode 100644
index e556383ba..000000000
--- a/arch/arm/boot/compressed/head-victor.S
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * linux/arch/arm/boot/compressed/head-victor.S
- *
- * Copyright (C) 1998 Nicolas Pitre <nico@visuaide.com>
- */
-
-#include <linux/linkage.h>
-
- .text
- .globl _start
-_start:
- @ just in case we still use an a.out loader...
- nop
- nop
- nop
- nop
- nop
- nop
- nop
- nop
-
- @ load different addresses
- adr r2, LC0
- ldmia r2, {r4, r5, r6, sp}
-
- @ clear BSS
- mov r2, #0
-1: str r2, [r5], #4
- cmp r5, r6
- blt 1b
-
- @ uncompress the kernel
- mov r8, r0 @ save cmdline ptr
- mov r0, r4 @ where to put uncompressed data
- add r1, r6, #31
- bic r1, r1, #31 @ free memory space
- add r2, r1, #65536 @ end of free mem space
- bl SYMBOL_NAME(decompress_kernel)
- mov r0, r8 @ retrieve cmdline ptr
- mov pc, r4 @ call via EXEC entry
-
-LC0: .word _load_addr
- .word __bss_start
- .word SYMBOL_NAME(_end)
- .word SYMBOL_NAME(user_stack)+4096
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index e87c0a72e..796f812ab 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -77,10 +77,10 @@ start:
cmp r2, r3
blt 1b
- eor r1, r6, #0x44 << 24 @ SA-110?
+ eor r1, r6, #0x44 << 24 @ SA-110 or SA-1100?
eor r1, r1, #0x01 << 16
eor r1, r1, #0xa1 << 8
- movs r1, r1, lsr #4
+ movs r1, r1, lsr #5
mcreq p15, 0, r1, c7, c7, 0 @ flush I & D-cache
mcreq p15, 0, r1, c7, c10, 4 @ drain WB
add pc, r5, r0 @ call relocation code
@@ -144,10 +144,10 @@ reloc_start: add r8, r5, r0
mov r0, r4
bl memdump
#endif
- eor r0, r6, #0x44 << 24 @ SA-110?
+ eor r0, r6, #0x44 << 24 @ SA-110 or SA-1100?
eor r0, r0, #0x01 << 16
eor r0, r0, #0xa1 << 8
- movs r0, r0, lsr #4
+ movs r0, r0, lsr #5
mcreq p15, 0, r0, c7, c7, 0 @ flush I cache
mcreq p15, 0, r1, c7, c10, 4 @ drain WB
diff --git a/arch/arm/config.in b/arch/arm/config.in
index e1d54c4e7..be7102698 100644
--- a/arch/arm/config.in
+++ b/arch/arm/config.in
@@ -6,6 +6,8 @@ mainmenu_name "Linux Kernel Configuration"
define_bool CONFIG_ARM y
+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
@@ -44,7 +46,6 @@ if [ "$CONFIG_ADDIN_FOOTBRIDGE" = "y" ]; then
fi
if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
- define_bool CONFIG_CPU_SA1100 y
choice 'SA1100 implementation' \
"Brutus CONFIG_SA1100_BRUTUS \
Empeg CONFIG_SA1100_EMPEG \
@@ -93,7 +94,11 @@ else
"$CONFIG_FOOTBRIDGE" = "y" -o \
"$CONFIG_ARCH_NEXUSPCI" = "y" ]; then
define_bool CONFIG_CPU_32v4 y
- define_bool CONFIG_CPU_SA110 y
+ if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
+ define_bool CONFIG_CPU_SA1100 y
+ else
+ define_bool CONFIG_CPU_SA110 y
+ fi
else
if [ "$CONFIG_ARCH_RPC" = "y" ]; then
define_bool CONFIG_CPU_32v3 y
@@ -110,7 +115,7 @@ fi
if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o \
"$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then
define_bool CONFIG_PCI y
- source drivers/pci/Config.h
+ source drivers/pci/Config.in
fi
#
@@ -123,8 +128,8 @@ else
define_bool CONFIG_ISA_DMA n
fi
-if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool 'Enable kernel-mode alignment trap handler (EXPERIMENTAL)' CONFIG_ALIGNMENT_TRAP
+if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then
+ bool 'Kernel-mode alignment trap handler' CONFIG_ALIGNMENT_TRAP
fi
#bool 'Split text into discardable sections' CONFIG_TEXT_SECTIONS
endmenu
@@ -273,11 +278,10 @@ bool 'Verbose user fault messages' CONFIG_DEBUG_USER
bool 'Include debugging information in kernel binary' CONFIG_DEBUG_INFO
#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
+if [ "$CONFIG_CPU_26" = "y" ]; then
+ bool 'Disable pgtable cache' CONFIG_NO_PGT_CACHE
+fi
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- if [ "$CONFIG_CPU_26" = "y" ]; then
- bool 'Disable pgtable cache (EXPERIMENTAL)' CONFIG_NO_PGT_CACHE
- fi
-
# These options are only for real kernel hackers
# who want to get their hands dirty.
bool 'Kernel low-level debugging functions' CONFIG_DEBUG_LL
diff --git a/arch/arm/def-configs/a5k b/arch/arm/def-configs/a5k
index 8b402a59e..b5fd4b315 100644
--- a/arch/arm/def-configs/a5k
+++ b/arch/arm/def-configs/a5k
@@ -4,6 +4,11 @@
CONFIG_ARM=y
#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
# System and processor type
#
# CONFIG_ARCH_ARC is not set
@@ -12,22 +17,10 @@ CONFIG_ARCH_A5K=y
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_FOOTBRIDGE is not set
CONFIG_ARCH_ACORN=y
-# CONFIG_ISA_DMA is not set
# CONFIG_CPU_32 is not set
CONFIG_CPU_26=y
-# CONFIG_CPU_ARM2 is not set
-CONFIG_CPU_ARM3=y
-# CONFIG_CPU_ARM6 is not set
-# CONFIG_CPU_ARM7 is not set
-# CONFIG_CPU_SA110 is not set
-CONFIG_PAGESIZE_32=y
# CONFIG_PAGESIZE_16 is not set
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
-# CONFIG_TEXT_SECTIONS is not set
+# CONFIG_ISA_DMA is not set
#
# Loadable module support
@@ -43,17 +36,38 @@ CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
-# CONFIG_NWFPE is not set
+CONFIG_NWFPE=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_AOUT=y
-CONFIG_BINFMT_ELF=m
+# CONFIG_BINFMT_ELF is not set
# CONFIG_BINFMT_MISC is not set
-CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=y
+CONFIG_PARPORT=m
+CONFIG_PARPORT_PC=m
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_ARC is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_1284 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
#
-# Plug and Play support
+# Plug and Play configuration
#
# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
#
# Block devices
@@ -66,11 +80,19 @@ CONFIG_BLK_DEV_IDE=y
#
# CONFIG_BLK_DEV_HD_IDE is not set
CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
# CONFIG_BLK_DEV_CMD640 is not set
+CONFIG_BLK_DEV_IDE_ICSIDE=y
+# CONFIG_BLK_DEV_IDEDMA_ICS is not set
+# CONFIG_BLK_DEV_IDE_RAPIDE is not set
# CONFIG_IDE_CHIPSETS is not set
#
@@ -82,16 +104,14 @@ CONFIG_BLK_DEV_LOOP=m
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_DEV_XD is not set
-CONFIG_PARIDE_PARPORT=y
+CONFIG_PARIDE_PARPORT=m
# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
# CONFIG_BLK_DEV_HD is not set
#
# Acorn-specific block devices
#
-CONFIG_BLK_DEV_IDE_CARDS=y
-CONFIG_BLK_DEV_IDE_ICSIDE=y
-# CONFIG_BLK_DEV_IDE_RAPIDE is not set
# CONFIG_BLK_DEV_FD1772 is not set
CONFIG_BLK_DEV_MFM=m
CONFIG_BLK_DEV_MFM_AUTODETECT=y
@@ -102,26 +122,33 @@ CONFIG_BLK_DEV_MFM_AUTODETECT=y
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_ATOMWIDE_SERIAL is not set
+# CONFIG_DUALSP_SERIAL is not set
# CONFIG_SERIAL_EXTENDED is not set
-CONFIG_ATOMWIDE_SERIAL=y
-CONFIG_DUALSP_SERIAL=y
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_UNIX98_PTYS is not set
-CONFIG_PRINTER=y
-CONFIG_PRINTER_READBACK=y
-CONFIG_MOUSE=y
+# CONFIG_PRINTER is not set
+# CONFIG_PPDEV is not set
#
# Mice
#
-# CONFIG_ATIXL_BUSMOUSE is not set
# CONFIG_BUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
+CONFIG_MOUSE=y
# CONFIG_PSMOUSE is not set
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
@@ -130,27 +157,38 @@ CONFIG_MOUSE=y
# Video For Linux
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-CONFIG_KBDMOUSE=y
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
+
+#
+# Support for USB
+#
+# CONFIG_USB is not set
#
# Console drivers
#
CONFIG_FB=y
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_FB_ACORN=y
# CONFIG_FB_MATROX is not set
# CONFIG_FB_ATY is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_3DFX is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FBCON_ADVANCED is not set
CONFIG_FBCON_MFB=y
@@ -158,9 +196,13 @@ CONFIG_FBCON_CFB2=y
CONFIG_FBCON_CFB4=y
CONFIG_FBCON_CFB8=y
# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
-# CONFIG_FBCON_FONTS is not set
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
CONFIG_FONT_ACORN_8x8=y
#
@@ -168,7 +210,7 @@ CONFIG_FONT_ACORN_8x8=y
#
# CONFIG_PACKET is not set
# CONFIG_NETLINK is not set
-# CONFIG_FIREWALL is not set
+# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
@@ -184,15 +226,17 @@ CONFIG_INET=y
#
# (it is safe to leave these untouched)
#
-# CONFIG_INET_RARP is not set
# CONFIG_SKB_LARGE is not set
# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_BRIDGE is not set
@@ -201,7 +245,6 @@ CONFIG_INET=y
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
-# CONFIG_CPU_IS_SLOW is not set
#
# QoS and/or fair queueing
@@ -214,7 +257,7 @@ CONFIG_INET=y
# CONFIG_HAMRADIO is not set
#
-# IrDA subsystem support
+# IrDA (infrared) support
#
# CONFIG_IRDA is not set
@@ -222,9 +265,18 @@ CONFIG_INET=y
# Network device support
#
CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
CONFIG_NET_ETHERNET=y
CONFIG_ARM_ETHER1=y
CONFIG_ARM_ETHER3=y
@@ -234,96 +286,47 @@ CONFIG_ARM_ETHER3=y
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_RTL8139 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_ACENIC is not set
+# CONFIG_DM9102 is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_EISA is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
-# CONFIG_DLCI is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring driver support
+#
# CONFIG_TR is not set
-# CONFIG_SHAPER is not set
-# CONFIG_HOSTESS_SV11 is not set
-# CONFIG_COSA is not set
+# CONFIG_NET_FC is not set
# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
#
# SCSI support
#
-CONFIG_SCSI=y
-
-#
-# SCSI support type (disk, tape, CD-ROM)
-#
-CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
-CONFIG_BLK_DEV_SR=y
-# CONFIG_BLK_DEV_SR_VENDOR is not set
-# CONFIG_CHR_DEV_SG is not set
-
-#
-# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
-#
-# CONFIG_SCSI_MULTI_LUN is not set
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-
-#
-# SCSI low-level drivers
-#
-# CONFIG_SCSI_7000FASST is not set
-# CONFIG_SCSI_ACARD is not set
-# CONFIG_SCSI_AHA152X is not set
-# CONFIG_SCSI_AHA1542 is not set
-# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_ADVANSYS is not set
-# CONFIG_SCSI_IN2000 is not set
-# CONFIG_SCSI_AM53C974 is not set
-# CONFIG_SCSI_MEGARAID is not set
-# CONFIG_SCSI_BUSLOGIC is not set
-# CONFIG_SCSI_DTC3280 is not set
-# CONFIG_SCSI_EATA is not set
-# CONFIG_SCSI_EATA_DMA is not set
-# CONFIG_SCSI_EATA_PIO is not set
-# CONFIG_SCSI_FUTURE_DOMAIN is not set
-# CONFIG_SCSI_GDTH is not set
-# CONFIG_SCSI_GENERIC_NCR5380 is not set
-CONFIG_SCSI_PPA=m
-# CONFIG_SCSI_IMM is not set
-# CONFIG_SCSI_IZIP_EPP16 is not set
-# CONFIG_SCSI_IZIP_SLOW_CTR is not set
-# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_PAS16 is not set
-# CONFIG_SCSI_PCI2000 is not set
-# CONFIG_SCSI_PCI2220I is not set
-# CONFIG_SCSI_PSI240I is not set
-# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_SEAGATE is not set
-# CONFIG_SCSI_T128 is not set
-# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
-# CONFIG_SCSI_DEBUG is not set
-CONFIG_SCSI_ACORNSCSI_3=y
-CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE=y
-CONFIG_SCSI_ACORNSCSI_SYNC=y
-CONFIG_SCSI_ARXESCSI=m
-# CONFIG_SCSI_CUMANA_2 is not set
-CONFIG_SCSI_EESOXSCSI=y
-# CONFIG_SCSI_POWERTECSCSI is not set
-
-#
-# The following drivers are not fully supported
-#
-# CONFIG_SCSI_CUMANA_1 is not set
-# CONFIG_SCSI_ECOSCSI is not set
-# CONFIG_SCSI_OAK1 is not set
+# CONFIG_SCSI is not set
#
# Sound
@@ -338,12 +341,14 @@ CONFIG_SCSI_EESOXSCSI=y
CONFIG_ADFS_FS=y
# CONFIG_AFFS_FS is not set
# 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_ISO9660_FS=y
-CONFIG_JOLIET=y
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -352,6 +357,7 @@ CONFIG_PROC_FS=y
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
# CONFIG_UFS_FS is not set
#
@@ -359,8 +365,7 @@ CONFIG_EXT2_FS=y
#
# CONFIG_CODA_FS is not set
CONFIG_NFS_FS=y
-CONFIG_NFSD=y
-# CONFIG_NFSD_SUN is not set
+# CONFIG_NFSD is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set
@@ -369,12 +374,10 @@ CONFIG_LOCKD=y
#
# Partition Types
#
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
+# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
CONFIG_ACORN_PARTITION=y
CONFIG_ACORN_PARTITION_ADFS=y
CONFIG_ACORN_PARTITION_ICS=y
@@ -410,6 +413,7 @@ CONFIG_NLS=y
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
@@ -418,8 +422,8 @@ CONFIG_NLS=y
#
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_INFO is not set
CONFIG_MAGIC_SYSRQ=y
CONFIG_NO_PGT_CACHE=y
-# CONFIG_DEBUG_LL is not set
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/def-configs/footbridge b/arch/arm/def-configs/footbridge
index fa410d522..d68d0b358 100644
--- a/arch/arm/def-configs/footbridge
+++ b/arch/arm/def-configs/footbridge
@@ -4,6 +4,11 @@
CONFIG_ARM=y
#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
# System and processor type
#
# CONFIG_ARCH_ARC is not set
@@ -23,11 +28,6 @@ CONFIG_CPU_32v4=y
CONFIG_CPU_SA110=y
CONFIG_PCI=y
CONFIG_ISA_DMA=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
# CONFIG_ALIGNMENT_TRAP is not set
#
@@ -45,6 +45,8 @@ CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_NWFPE=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
@@ -52,7 +54,6 @@ CONFIG_BINFMT_ELF=y
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
CONFIG_PARPORT_PC_FIFO=y
-# CONFIG_PARPORT_PC_PCMCIA is not set
# CONFIG_PARPORT_ARC is not set
# CONFIG_PARPORT_AMIGA is not set
# CONFIG_PARPORT_MFC3 is not set
@@ -60,7 +61,7 @@ CONFIG_PARPORT_PC_FIFO=y
# CONFIG_PARPORT_SUNBPP is not set
# CONFIG_PARPORT_OTHER is not set
CONFIG_PARPORT_1284=y
-CONFIG_CMDLINE="root=/dev/hda2 ro mem=32M parport=0x378,7 ide0=autotune"
+CONFIG_CMDLINE="root=/dev/hda1 ro mem=32M parport=0x378,7 ide0=autotune"
CONFIG_LEDS=y
CONFIG_LEDS_TIMER=y
# CONFIG_LEDS_CPU is not set
@@ -97,15 +98,20 @@ CONFIG_IDEDISK_MULTI_MODE=y
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_BLK_DEV_IDEDMA_PCI=y
CONFIG_IDEDMA_PCI_AUTO=y
-# IDEDMA_NEW_DRIVE_LISTINGS is not set
-IDEDMA_PCI_EXPERIMENTAL=y
+CONFIG_IDEDMA_NEW_DRIVE_LISTINGS=y
+CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
CONFIG_BLK_DEV_OFFBOARD=y
# CONFIG_BLK_DEV_AEC6210 is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
# CONFIG_BLK_DEV_CMD646 is not set
CONFIG_BLK_DEV_CY82C693=y
# CONFIG_BLK_DEV_HPT34X is not set
@@ -113,8 +119,8 @@ CONFIG_BLK_DEV_CY82C693=y
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_PDC202XX=y
-# PDC202XX_FORCE_BURST_BIT is not set
-# PDC202XX_FORCE_MASTER_MODE is not set
+# CONFIG_PDC202XX_FORCE_BURST_BIT is not set
+# CONFIG_PDC202XX_FORCE_MASTER_MODE is not set
# CONFIG_BLK_DEV_TRM290 is not set
CONFIG_BLK_DEV_SL82C105=y
CONFIG_BLK_DEV_IDEDMA=y
@@ -135,6 +141,7 @@ CONFIG_MD_RAID5=m
CONFIG_BLK_DEV_RAM=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
CONFIG_PARIDE_PARPORT=y
CONFIG_PARIDE=m
@@ -176,7 +183,8 @@ CONFIG_SERIAL=y
CONFIG_SERIAL_CONSOLE=y
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
CONFIG_PRINTER=m
# CONFIG_LP_CONSOLE is not set
# CONFIG_PPDEV is not set
@@ -189,12 +197,17 @@ CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
# CONFIG_QIC02_TAPE is not set
-CONFIG_WATCHDOG=y
#
# Watchdog Cards
#
+CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
# CONFIG_WDT is not set
CONFIG_SOFT_WATCHDOG=y
@@ -212,12 +225,33 @@ CONFIG_RTC=y
#
# Video For Linux
#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
+CONFIG_VIDEO_DEV=y
+# CONFIG_I2C_PARPORT is not set
+
+#
+# Radio/Video Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_RADIO_GEMTEK is not set
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_RADIO_MIROPCM20 is not set
+# CONFIG_VIDEO_BWQCAM is not set
+# CONFIG_VIDEO_CQCAM is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_BUZ is not set
+# CONFIG_VIDEO_ZR36120 is not set
+CONFIG_VIDEO_CYBERPRO=m
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -226,41 +260,64 @@ CONFIG_RTC=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
#
-# USB drivers - not for the faint of heart
+# Support for USB
#
CONFIG_USB=m
+
+#
+# USB Controllers
+#
# CONFIG_USB_UHCI is not set
CONFIG_USB_OHCI=m
CONFIG_USB_OHCI_DEBUG=y
CONFIG_USB_OHCI_HCD=m
CONFIG_USB_OHCI_VROOTHUB=y
+
+#
+# Miscellaneous USB options
+#
# CONFIG_USB_DEBUG_ISOC is not set
-CONFIG_USB_HUB=m
+CONFIG_USB_PROC=y
+# CONFIG_USB_EZUSB is not set
+
+#
+# USB Devices
+#
CONFIG_USB_MOUSE=m
+# CONFIG_USB_HP_SCANNER is not set
CONFIG_USB_KBD=m
CONFIG_USB_AUDIO=m
CONFIG_USB_ACM=m
CONFIG_USB_PRINTER=m
+# CONFIG_USB_SERIAL is not set
# CONFIG_USB_CPIA is not set
-CONFIG_USB_SCSI=m
-CONFIG_USB_SCSI_DEBUG=m
-# CONFIG_USB_EZUSB is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_SCSI is not set
# CONFIG_USB_USS720 is not set
-CONFIG_USB_PROC=y
#
# Console drivers
#
CONFIG_VGA_CONSOLE=y
CONFIG_FB=y
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
# CONFIG_FB_CLGEN is not set
# CONFIG_FB_PM2 is not set
CONFIG_FB_CYBER2000=y
# CONFIG_FB_MATROX is not set
# CONFIG_FB_ATY is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_3DFX is not set
# CONFIG_FB_VIRTUAL is not set
CONFIG_FBCON_ADVANCED=y
# CONFIG_FBCON_MFB is not set
@@ -377,12 +434,13 @@ CONFIG_VORTEX=y
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
-# CONFIG_YELLOWFIN is not set
+# CONFIG_DM9102 is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
CONFIG_NET_EISA=y
# CONFIG_PCNET32 is not set
-# CONFIG_ACENIC is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_AC3200 is not set
# CONFIG_APRICOT is not set
# CONFIG_CS89x0 is not set
@@ -393,27 +451,40 @@ CONFIG_DEC_ELCP=m
# CONFIG_LNE390 is not set
# CONFIG_NE3210 is not set
CONFIG_NE2K_PCI=y
+# CONFIG_SIS900 is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_ES3210 is not set
# CONFIG_EPIC100 is not set
# CONFIG_ZNET is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PLIP is not set
CONFIG_PPP=m
CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_BSDCOMP=m
CONFIG_SLIP=m
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLIP_SMART=y
CONFIG_SLIP_MODE_SLIP6=y
+
+#
+# Wireless LAN (non-hamradio)
+#
# CONFIG_NET_RADIO is not set
#
-# Token ring devices
+# Token Ring driver support
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
@@ -423,10 +494,7 @@ CONFIG_SLIP_MODE_SLIP6=y
#
# Wan interfaces
#
-# CONFIG_HOSTESS_SV11 is not set
-# CONFIG_COSA is not set
-# CONFIG_SEALEVEL_4021 is not set
-# CONFIG_DLCI is not set
+# CONFIG_WAN is not set
#
# SCSI support
@@ -441,30 +509,33 @@ CONFIG_SOUND=m
# CONFIG_SOUND_ES1370 is not set
# CONFIG_SOUND_ES1371 is not set
# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
CONFIG_SOUND_OSS=m
-# CONFIG_SOUND_PAS is not set
-CONFIG_SOUND_SB=m
-CONFIG_SOUND_ADLIB=m
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_CS4232 is not set
# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SOFTOSS is not set
+CONFIG_SOUND_SB=m
# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_CS4232 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_VIA82CXXX is not set
# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
# CONFIG_SOUND_UART6850 is not set
# CONFIG_SOUND_VIDC is not set
CONFIG_SOUND_WAVEARTIST=m
@@ -482,10 +553,11 @@ CONFIG_WAVEARTIST_DMA2=7
# Filesystems
#
# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS_FS=y
CONFIG_ADFS_FS=y
# CONFIG_AFFS_FS is not set
# 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
@@ -497,10 +569,12 @@ CONFIG_JOLIET=y
# CONFIG_NTFS_FS is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
+CONFIG_DEVPTS_FS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
# CONFIG_UFS_FS is not set
#
@@ -510,7 +584,7 @@ CONFIG_EXT2_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=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 is not set
diff --git a/arch/arm/def-configs/rpc b/arch/arm/def-configs/rpc
index 904bb0724..e801bf641 100644
--- a/arch/arm/def-configs/rpc
+++ b/arch/arm/def-configs/rpc
@@ -4,6 +4,11 @@
CONFIG_ARM=y
#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
# System and processor type
#
# CONFIG_ARCH_ARC is not set
@@ -12,21 +17,14 @@ CONFIG_ARCH_RPC=y
# CONFIG_ARCH_EBSA110 is not set
# CONFIG_FOOTBRIDGE is not set
CONFIG_ARCH_ACORN=y
-# CONFIG_ISA_DMA is not set
CONFIG_CPU_32=y
# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM2 is not set
-# CONFIG_CPU_ARM3 is not set
-# CONFIG_CPU_ARM6 is not set
-# CONFIG_CPU_ARM7 is not set
+CONFIG_CPU_32v3=y
+CONFIG_CPU_ARM6=y
+CONFIG_CPU_ARM7=y
CONFIG_CPU_SA110=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
+# CONFIG_ISA_DMA is not set
# CONFIG_ALIGNMENT_TRAP is not set
-# CONFIG_TEXT_SECTIONS is not set
#
# Loadable module support
@@ -43,16 +41,38 @@ CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
# CONFIG_NWFPE is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
+# CONFIG_ARTHUR is not set
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_ARC is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_1284 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
#
-# Plug and Play support
+# Plug and Play configuration
#
# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
#
# Block devices
@@ -65,11 +85,22 @@ CONFIG_BLK_DEV_IDE=y
#
# CONFIG_BLK_DEV_HD_IDE is not set
CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_IDETAPE=y
-CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
# CONFIG_BLK_DEV_CMD640 is not set
+CONFIG_BLK_DEV_IDE_ICSIDE=y
+CONFIG_BLK_DEV_IDEDMA_ICS=y
+CONFIG_IDEDMA_ICS_AUTO=y
+CONFIG_BLK_DEV_IDE_RAPIDE=y
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDEDMA_AUTO=y
# CONFIG_IDE_CHIPSETS is not set
#
@@ -83,14 +114,12 @@ CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_DEV_XD is not set
CONFIG_PARIDE_PARPORT=y
# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
# CONFIG_BLK_DEV_HD is not set
#
# Acorn-specific block devices
#
-CONFIG_BLK_DEV_IDE_CARDS=y
-CONFIG_BLK_DEV_IDE_ICSIDE=y
-CONFIG_BLK_DEV_IDE_RAPIDE=y
#
# Character devices
@@ -99,25 +128,36 @@ CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_SERIAL=y
# CONFIG_SERIAL_CONSOLE is not set
-# CONFIG_SERIAL_EXTENDED is not set
CONFIG_ATOMWIDE_SERIAL=y
CONFIG_DUALSP_SERIAL=y
+# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_UNIX98_PTYS is not set
CONFIG_PRINTER=m
-CONFIG_PRINTER_READBACK=y
-CONFIG_MOUSE=y
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
#
# Mice
#
+CONFIG_BUSMOUSE=y
# CONFIG_ATIXL_BUSMOUSE is not set
-# CONFIG_BUSMOUSE is not set
+# CONFIG_LOGIBUSMOUSE is not set
# CONFIG_MS_BUSMOUSE is not set
+CONFIG_MOUSE=y
# CONFIG_PSMOUSE is not set
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
@@ -126,27 +166,39 @@ CONFIG_MOUSE=y
# Video For Linux
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
CONFIG_RPCMOUSE=y
#
+# Support for USB
+#
+# CONFIG_USB is not set
+
+#
# Console drivers
#
CONFIG_FB=y
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
CONFIG_DUMMY_CONSOLE=y
CONFIG_FB_ACORN=y
# CONFIG_FB_MATROX is not set
# CONFIG_FB_ATY is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_3DFX is not set
# CONFIG_FB_VIRTUAL is not set
CONFIG_FBCON_ADVANCED=y
CONFIG_FBCON_MFB=y
@@ -162,6 +214,7 @@ CONFIG_FBCON_CFB32=y
# CONFIG_FBCON_IPLAN2P4 is not set
# CONFIG_FBCON_IPLAN2P8 is not set
# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
# CONFIG_FBCON_VGA is not set
# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
CONFIG_FBCON_FONTS=y
@@ -178,7 +231,7 @@ CONFIG_FONT_ACORN_8x8=y
#
# CONFIG_PACKET is not set
# CONFIG_NETLINK is not set
-# CONFIG_FIREWALL is not set
+# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
@@ -194,15 +247,17 @@ CONFIG_INET=y
#
# (it is safe to leave these untouched)
#
-# CONFIG_INET_RARP is not set
CONFIG_SKB_LARGE=y
# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_BRIDGE is not set
@@ -211,7 +266,6 @@ CONFIG_SKB_LARGE=y
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
-# CONFIG_CPU_IS_SLOW is not set
#
# QoS and/or fair queueing
@@ -224,7 +278,7 @@ CONFIG_SKB_LARGE=y
# CONFIG_HAMRADIO is not set
#
-# IrDA subsystem support
+# IrDA (infrared) support
#
# CONFIG_IRDA is not set
@@ -232,39 +286,67 @@ CONFIG_SKB_LARGE=y
# Network device support
#
CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
CONFIG_NET_ETHERNET=y
CONFIG_ARM_ETHER1=m
CONFIG_ARM_ETHER3=m
-CONFIG_ARM_ETHERH=m
+CONFIG_ARM_ETHERH=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_RTL8139 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_ACENIC is not set
+# CONFIG_DM9102 is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_EISA is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
-# CONFIG_DLCI is not set
# CONFIG_PLIP is not set
CONFIG_PPP=m
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_SLIP is not set
#
-# CCP compressors for PPP are only built as modules.
+# Wireless LAN (non-hamradio)
#
-# CONFIG_SLIP is not set
# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring driver support
+#
# CONFIG_TR is not set
-# CONFIG_SHAPER is not set
-# CONFIG_HOSTESS_SV11 is not set
-# CONFIG_COSA is not set
+# CONFIG_NET_FC is not set
# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
#
# SCSI support
@@ -283,6 +365,7 @@ CONFIG_CHR_DEV_SG=y
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
+CONFIG_SCSI_DEBUG_QUEUES=y
# CONFIG_SCSI_MULTI_LUN is not set
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_LOGGING=y
@@ -296,6 +379,7 @@ CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
@@ -314,6 +398,7 @@ CONFIG_SCSI_IMM=m
# CONFIG_SCSI_IZIP_SLOW_CTR is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
@@ -342,32 +427,37 @@ CONFIG_SCSI_OAK1=m
# Sound
#
CONFIG_SOUND=m
+# CONFIG_SOUND_CMPCI is not set
# CONFIG_SOUND_ES1370 is not set
# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
CONFIG_SOUND_OSS=m
-# CONFIG_SOUND_PAS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_CS4232 is not set
# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_SB is not set
# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_CS4232 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_VIA82CXXX is not set
# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
# CONFIG_SOUND_UART6850 is not set
CONFIG_SOUND_VIDC=m
# CONFIG_SOUND_WAVEARTIST is not set
@@ -385,10 +475,12 @@ CONFIG_SOUND_VIDC=m
CONFIG_ADFS_FS=y
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
CONFIG_ISO9660_FS=y
CONFIG_JOLIET=y
# CONFIG_MINIX_FS is not set
@@ -399,6 +491,7 @@ CONFIG_PROC_FS=y
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
# CONFIG_UFS_FS is not set
#
@@ -415,12 +508,17 @@ CONFIG_LOCKD=y
#
# Partition Types
#
-# CONFIG_OSF_PARTITION is not set
-# CONFIG_MAC_PARTITION is not set
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_OSF_PARTITION=y
+CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
-# CONFIG_AMIGA_PARTITION is not set
+CONFIG_BSD_DISKLABEL=y
+CONFIG_SOLARIS_X86_PARTITION=y
+# CONFIG_UNIXWARE_DISKLABEL is not set
+CONFIG_SGI_PARTITION=y
+CONFIG_SUN_PARTITION=y
+CONFIG_AMIGA_PARTITION=y
+# CONFIG_ATARI_PARTITION is not set
CONFIG_ACORN_PARTITION=y
CONFIG_ACORN_PARTITION_ADFS=y
CONFIG_ACORN_PARTITION_ICS=y
@@ -456,6 +554,7 @@ CONFIG_NLS_ISO8859_6=m
CONFIG_NLS_ISO8859_7=m
CONFIG_NLS_ISO8859_8=m
CONFIG_NLS_ISO8859_9=m
+# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
CONFIG_NLS_KOI8_R=m
@@ -467,5 +566,4 @@ CONFIG_DEBUG_ERRORS=y
# CONFIG_DEBUG_USER is not set
# CONFIG_DEBUG_INFO is not set
CONFIG_MAGIC_SYSRQ=y
-# CONFIG_ARTHUR is not set
-# CONFIG_DEBUG_LL is not set
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/defconfig b/arch/arm/defconfig
index 2aba351c2..472c637c3 100644
--- a/arch/arm/defconfig
+++ b/arch/arm/defconfig
@@ -4,6 +4,11 @@
CONFIG_ARM=y
#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
# System and processor type
#
# CONFIG_ARCH_ARC is not set
@@ -17,23 +22,13 @@ CONFIG_ARCH_EBSA285=y
# CONFIG_CATS is not set
CONFIG_ARCH_NETWINDER=y
# CONFIG_ARCH_ACORN is not set
-CONFIG_PCI=y
-CONFIG_PCI_NAMES=y
-CONFIG_ISA_DMA=y
CONFIG_CPU_32=y
# CONFIG_CPU_26 is not set
-# CONFIG_CPU_ARM2 is not set
-# CONFIG_CPU_ARM3 is not set
-# CONFIG_CPU_ARM6 is not set
-# CONFIG_CPU_ARM7 is not set
+CONFIG_CPU_32v4=y
CONFIG_CPU_SA110=y
-
-#
-# Code maturity level options
-#
-CONFIG_EXPERIMENTAL=y
+CONFIG_PCI=y
+CONFIG_ISA_DMA=y
# CONFIG_ALIGNMENT_TRAP is not set
-# CONFIG_TEXT_SECTIONS is not set
#
# Loadable module support
@@ -58,15 +53,34 @@ CONFIG_BINFMT_ELF=y
# CONFIG_ARTHUR is not set
CONFIG_PARPORT=y
CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_FIFO=y
+# CONFIG_PARPORT_ARC is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_PARPORT_1284=y
CONFIG_CMDLINE="root=/dev/hda1 ro mem=32M parport=0x378,7 ide0=autotune"
CONFIG_LEDS=y
CONFIG_LEDS_TIMER=y
# CONFIG_LEDS_CPU is not set
#
-# Plug and Play support
+# I2O device support
#
-# CONFIG_PNP is not set
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# Plug and Play configuration
+#
+CONFIG_PNP=y
+CONFIG_ISAPNP=y
#
# Block devices
@@ -79,23 +93,40 @@ CONFIG_BLK_DEV_IDE=y
#
# CONFIG_BLK_DEV_HD_IDE is not set
CONFIG_BLK_DEV_IDEDISK=y
+CONFIG_IDEDISK_MULTI_MODE=y
# CONFIG_BLK_DEV_IDECD is not set
# CONFIG_BLK_DEV_IDETAPE is not set
# CONFIG_BLK_DEV_IDEFLOPPY is not set
# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_BLK_DEV_OFFBOARD=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
CONFIG_IDEDMA_PCI_AUTO=y
+CONFIG_IDEDMA_NEW_DRIVE_LISTINGS=y
+CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
+CONFIG_BLK_DEV_OFFBOARD=y
+# CONFIG_BLK_DEV_AEC6210 is not set
+# CONFIG_BLK_DEV_ALI15X3 is not set
+# CONFIG_BLK_DEV_CMD646 is not set
+CONFIG_BLK_DEV_CY82C693=y
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_PDC202XX=y
+# CONFIG_PDC202XX_FORCE_BURST_BIT is not set
+# CONFIG_PDC202XX_FORCE_MASTER_MODE is not set
# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_VIA82C586 is not set
-# CONFIG_BLK_DEV_CMD646 is not set
CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDEDMA_AUTO=y
# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_CPQ_DA is not set
#
# Additional Block Devices
@@ -110,6 +141,7 @@ CONFIG_MD_RAID5=m
CONFIG_BLK_DEV_RAM=y
# CONFIG_BLK_DEV_INITRD is not set
# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
CONFIG_PARIDE_PARPORT=y
CONFIG_PARIDE=m
@@ -139,6 +171,7 @@ CONFIG_PARIDE_KBIC=m
CONFIG_PARIDE_KTTI=m
CONFIG_PARIDE_ON20=m
CONFIG_PARIDE_ON26=m
+CONFIG_BLK_DEV_IDE_MODES=y
# CONFIG_BLK_DEV_HD is not set
#
@@ -150,31 +183,38 @@ CONFIG_SERIAL=y
CONFIG_SERIAL_CONSOLE=y
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
CONFIG_PRINTER=m
-CONFIG_PRINTER_READBACK=y
-CONFIG_MOUSE=y
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
#
# Mice
#
-# CONFIG_ATIXL_BUSMOUSE is not set
# CONFIG_BUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
+CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
# CONFIG_QIC02_TAPE is not set
-CONFIG_WATCHDOG=y
#
# Watchdog Cards
#
+CONFIG_WATCHDOG=y
# CONFIG_WATCHDOG_NOWAYOUT is not set
# CONFIG_WDT is not set
CONFIG_SOFT_WATCHDOG=y
# CONFIG_PCWATCHDOG is not set
# CONFIG_ACQUIRE_WDT is not set
+# CONFIG_21285_WATCHDOG is not set
+CONFIG_977_WATCHDOG=m
CONFIG_DS1620=y
CONFIG_NWBUTTON=y
CONFIG_NWBUTTON_REBOOT=y
@@ -185,29 +225,100 @@ CONFIG_RTC=y
#
# Video For Linux
#
-# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
+CONFIG_VIDEO_DEV=y
+# CONFIG_I2C_PARPORT is not set
+
+#
+# Radio/Video Adapters
+#
+# CONFIG_RADIO_CADET is not set
+# CONFIG_RADIO_RTRACK is not set
+# CONFIG_RADIO_RTRACK2 is not set
+# CONFIG_RADIO_AZTECH is not set
+# CONFIG_VIDEO_BT848 is not set
+# CONFIG_RADIO_GEMTEK is not set
+# CONFIG_VIDEO_PMS is not set
+# CONFIG_RADIO_MIROPCM20 is not set
+# CONFIG_VIDEO_BWQCAM is not set
+# CONFIG_VIDEO_CQCAM is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_RADIO_SF16FMI is not set
+# CONFIG_VIDEO_STRADIS is not set
+# CONFIG_RADIO_TERRATEC is not set
+# CONFIG_RADIO_TRUST is not set
+# CONFIG_RADIO_TYPHOON is not set
+# CONFIG_RADIO_ZOLTRIX is not set
+# CONFIG_VIDEO_ZORAN is not set
+# CONFIG_VIDEO_BUZ is not set
+# CONFIG_VIDEO_ZR36120 is not set
+CONFIG_VIDEO_CYBERPRO=m
# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
#
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
+
+#
+# Support for USB
+#
+CONFIG_USB=m
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+CONFIG_USB_OHCI=m
+CONFIG_USB_OHCI_DEBUG=y
+CONFIG_USB_OHCI_HCD=m
+CONFIG_USB_OHCI_VROOTHUB=y
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEBUG_ISOC is not set
+CONFIG_USB_PROC=y
+# CONFIG_USB_EZUSB is not set
+
+#
+# USB Devices
+#
+CONFIG_USB_MOUSE=m
+# CONFIG_USB_HP_SCANNER is not set
+CONFIG_USB_KBD=m
+CONFIG_USB_AUDIO=m
+CONFIG_USB_ACM=m
+CONFIG_USB_PRINTER=m
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_CPIA is not set
+# CONFIG_USB_DC2XX is not set
+# CONFIG_USB_SCSI is not set
+# CONFIG_USB_USS720 is not set
#
# Console drivers
#
CONFIG_VGA_CONSOLE=y
CONFIG_FB=y
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
# CONFIG_FB_PM2 is not set
CONFIG_FB_CYBER2000=y
# CONFIG_FB_MATROX is not set
# CONFIG_FB_ATY is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_3DFX is not set
# CONFIG_FB_VIRTUAL is not set
CONFIG_FBCON_ADVANCED=y
# CONFIG_FBCON_MFB is not set
@@ -223,6 +334,7 @@ CONFIG_FBCON_CFB24=y
# CONFIG_FBCON_IPLAN2P4 is not set
# CONFIG_FBCON_IPLAN2P8 is not set
# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
CONFIG_FBCON_VGA=y
# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
CONFIG_FBCON_FONTS=y
@@ -238,8 +350,9 @@ CONFIG_FONT_ACORN_8x8=y
# Networking options
#
CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK is not set
-# CONFIG_FIREWALL is not set
+# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
CONFIG_UNIX=y
CONFIG_INET=y
@@ -257,15 +370,17 @@ CONFIG_IP_ALIAS=y
#
# (it is safe to leave these untouched)
#
-# CONFIG_INET_RARP is not set
CONFIG_SKB_LARGE=y
# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
# CONFIG_BRIDGE is not set
@@ -274,7 +389,6 @@ CONFIG_SKB_LARGE=y
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_FASTROUTE is not set
# CONFIG_NET_HW_FLOWCONTROL is not set
-# CONFIG_CPU_IS_SLOW is not set
#
# QoS and/or fair queueing
@@ -287,7 +401,7 @@ CONFIG_SKB_LARGE=y
# CONFIG_HAMRADIO is not set
#
-# IrDA subsystem support
+# IrDA (infrared) support
#
# CONFIG_IRDA is not set
@@ -295,9 +409,18 @@ CONFIG_SKB_LARGE=y
# Network device support
#
CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
CONFIG_NET_ETHERNET=y
# CONFIG_ARM_AM79C961A is not set
CONFIG_NET_VENDOR_3COM=y
@@ -312,11 +435,13 @@ CONFIG_VORTEX=y
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_RTL8139 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_ACENIC is not set
+# CONFIG_DM9102 is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
CONFIG_NET_EISA=y
# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_AC3200 is not set
# CONFIG_APRICOT is not set
# CONFIG_CS89x0 is not set
@@ -327,31 +452,50 @@ CONFIG_DEC_ELCP=m
# CONFIG_LNE390 is not set
# CONFIG_NE3210 is not set
CONFIG_NE2K_PCI=y
+# CONFIG_SIS900 is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_ES3210 is not set
# CONFIG_EPIC100 is not set
# CONFIG_ZNET is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
-# CONFIG_DLCI is not set
# CONFIG_PLIP is not set
CONFIG_PPP=m
-
-#
-# CCP compressors for PPP are only built as modules.
-#
+CONFIG_PPP_ASYNC=m
+# CONFIG_PPP_SYNC_TTY is not set
+CONFIG_PPP_DEFLATE=m
+CONFIG_PPP_BSDCOMP=m
CONFIG_SLIP=m
CONFIG_SLIP_COMPRESSED=y
CONFIG_SLIP_SMART=y
CONFIG_SLIP_MODE_SLIP6=y
+
+#
+# Wireless LAN (non-hamradio)
+#
# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring driver support
+#
# CONFIG_TR is not set
-# CONFIG_SHAPER is not set
-# CONFIG_HOSTESS_SV11 is not set
-# CONFIG_COSA is not set
+# CONFIG_NET_FC is not set
# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
#
# SCSI support
@@ -362,32 +506,37 @@ CONFIG_SLIP_MODE_SLIP6=y
# Sound
#
CONFIG_SOUND=m
+# CONFIG_SOUND_CMPCI is not set
# CONFIG_SOUND_ES1370 is not set
# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
CONFIG_SOUND_OSS=m
-# CONFIG_SOUND_PAS is not set
-CONFIG_SOUND_SB=m
-CONFIG_SOUND_ADLIB=m
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_CS4232 is not set
# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SOFTOSS is not set
+CONFIG_SOUND_SB=m
# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_CS4232 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_VIA82CXXX is not set
# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
# CONFIG_SOUND_UART6850 is not set
# CONFIG_SOUND_VIDC is not set
CONFIG_SOUND_WAVEARTIST=m
@@ -405,24 +554,28 @@ CONFIG_WAVEARTIST_DMA2=7
# Filesystems
#
# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS_FS=y
CONFIG_ADFS_FS=y
# CONFIG_AFFS_FS is not set
# 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 is not set
CONFIG_ISO9660_FS=m
CONFIG_JOLIET=y
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
+CONFIG_DEVPTS_FS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
# CONFIG_UFS_FS is not set
#
@@ -432,7 +585,7 @@ CONFIG_EXT2_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=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 is not set
@@ -441,12 +594,17 @@ CONFIG_LOCKD=y
#
# Partition Types
#
+CONFIG_PARTITION_ADVANCED=y
# CONFIG_OSF_PARTITION is not set
# CONFIG_MAC_PARTITION is not set
CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
CONFIG_ACORN_PARTITION=y
CONFIG_ACORN_PARTITION_ADFS=y
# CONFIG_ACORN_PARTITION_ICS is not set
@@ -482,6 +640,7 @@ CONFIG_NLS_ISO8859_2=m
# CONFIG_NLS_ISO8859_7 is not set
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_14 is not set
CONFIG_NLS_ISO8859_15=m
# CONFIG_NLS_KOI8_R is not set
@@ -490,7 +649,7 @@ CONFIG_NLS_ISO8859_15=m
#
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_ERRORS=y
-# CONFIG_DEBUG_USER is not set
+CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_INFO is not set
CONFIG_MAGIC_SYSRQ=y
# CONFIG_DEBUG_LL is not set
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index cdd7a9821..0caf4bf26 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -16,6 +16,7 @@
#include <asm/dma.h>
#include <asm/pgalloc.h>
#include <asm/proc-fns.h>
+#include <asm/processor.h>
#include <asm/semaphore.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -29,8 +30,6 @@ extern void outswb(unsigned int port, const void *to, int len);
extern unsigned int local_bh_count[NR_CPUS];
extern unsigned int local_irq_count[NR_CPUS];
-extern pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags);
-
/*
* syscalls
*/
@@ -125,7 +124,6 @@ EXPORT_SYMBOL(cpu_cache_purge_area);
EXPORT_SYMBOL(__machine_arch_type);
/* networking */
-EXPORT_SYMBOL(csum_partial_copy);
EXPORT_SYMBOL(csum_partial_copy_nocheck);
EXPORT_SYMBOL(__csum_ipv6_magic);
@@ -172,8 +170,7 @@ EXPORT_SYMBOL_NOVERS(strpbrk);
EXPORT_SYMBOL_NOVERS(strtok);
EXPORT_SYMBOL_NOVERS(strrchr);
EXPORT_SYMBOL_NOVERS(strstr);
-EXPORT_SYMBOL_NOVERS(__memset);
-EXPORT_SYMBOL_NOVERS(memset); /* needed for some versions of gcc */
+EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(memmove);
EXPORT_SYMBOL_NOVERS(memcmp);
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index b9b7d57b4..d055ae1fb 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -5,6 +5,7 @@
*
* Bits taken from various places.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/errno.h>
@@ -33,8 +34,8 @@ void pcibios_report_device_errors(void)
continue;
pci_write_config_word(dev, PCI_STATUS, status & 0xf900);
- printk(KERN_DEBUG "PCI: status %04X on %s\n",
- status, dev->name);
+ printk(KERN_DEBUG "PCI: %02X:%02X: status %04X on %s\n",
+ dev->bus->number, dev->devfn, status, dev->name);
}
}
@@ -162,9 +163,10 @@ void __init pcibios_update_irq(struct pci_dev *dev, int irq)
*/
void __init pcibios_fixup_bus(struct pci_bus *bus)
{
- struct pci_dev *dev;
+ struct list_head *walk = &bus->devices;
- for (dev = bus->devices; dev; dev = dev->sibling) {
+ for (walk = walk->next; walk != &bus->devices; walk = walk->next) {
+ struct pci_dev *dev = pci_dev_b(walk);
u16 cmd;
/*
@@ -220,6 +222,7 @@ static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
return 0;
}
+#ifdef CONFIG_FOOTBRIDGE
/* ebsa285 host-specific stuff */
static int irqmap_ebsa285[] __initdata = { IRQ_IN1, IRQ_IN0, IRQ_PCI, IRQ_IN3 };
@@ -255,7 +258,7 @@ static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
if (dev->irq >= 128)
- return 16 + (dev->irq & 0x1f);
+ return dev->irq & 0x1f;
if (dev->irq >= 1 && dev->irq <= 4)
return irqmap_cats[dev->irq - 1];
@@ -313,17 +316,53 @@ static struct hw_pci netwinder_pci __initdata = {
no_swizzle,
netwinder_map_irq
};
+#endif
+
+#ifdef CONFIG_ARCH_NEXUSPCI
+/*
+ * Owing to a PCB cockup, issue A backplanes are wired thus:
+ *
+ * Slot 1 2 3 4 5 Bridge
+ * IRQ D C B A A
+ * A D C B B
+ * B A D C C
+ * C B A D D
+ *
+ * ID A31 A30 A29 A28 A27 A26
+ */
+
+static int irqmap_ftv[] __initdata = { IRQ_PCI_A, IRQ_PCI_B, IRQ_PCI_C, IRQ_PCI_D };
+
+static int __init ftv_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return irqmap_ftv[(slot + pin) & 3];
+}
+
+/* ftv host-specific stuff */
+static struct hw_pci ftv_pci __initdata = {
+ plx90x0_init,
+ 0x9000,
+ 0x00100000,
+ no_swizzle,
+ ftv_map_irq
+};
+#endif
void __init pcibios_init(void)
{
struct hw_pci *hw_pci = NULL;
+#ifdef CONFIG_FOOTBRIDGE
if (machine_is_ebsa285())
hw_pci = &ebsa285_pci;
else if (machine_is_cats())
hw_pci = &cats_pci;
else if (machine_is_netwinder())
hw_pci = &netwinder_pci;
+#endif
+#ifdef CONFIG_ARCH_NEXUSPCI
+ hw_pci = &ftv_pci;
+#endif
if (hw_pci == NULL)
return;
@@ -346,12 +385,14 @@ void __init pcibios_init(void)
pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq);
pci_set_bus_ranges();
+#ifdef CONFIG_FOOTBRIDGE
/*
* Initialise any other hardware after we've got the PCI bus
* initialised. We may need the PCI bus to talk to this other
* hardware.
*/
hw_init();
+#endif
}
char * __init pcibios_setup(char *str)
@@ -363,7 +404,17 @@ char * __init pcibios_setup(char *str)
return str;
}
-void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+/*
+ * Assign new address to PCI resource. We hope our resource information
+ * is complete.
+ *
+ * Expects start=0, end=size-1, flags=resource type.
+ */
+int pci_assign_resource(struct pci_dev *dev, int i)
+{
+ return 0;
+}
+
+void pcibios_align_resource(void *data, struct resource *res, unsigned long size)
{
}
diff --git a/arch/arm/kernel/bios32.h b/arch/arm/kernel/bios32.h
index fb3117452..9a4380732 100644
--- a/arch/arm/kernel/bios32.h
+++ b/arch/arm/kernel/bios32.h
@@ -7,3 +7,4 @@ struct hw_pci {
};
void __init dc21285_init(void);
+void __init plx90x0_init(void);
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index 51f3dcde2..d8d416c4e 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -25,19 +25,19 @@
.long SYMBOL_NAME(sys_time)
.long SYMBOL_NAME(sys_mknod)
/* 15 */ .long SYMBOL_NAME(sys_chmod)
- .long SYMBOL_NAME(sys_lchown)
+ .long SYMBOL_NAME(sys_lchown16)
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_break */
- .long SYMBOL_NAME(sys_stat)
+ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_stat */
.long SYMBOL_NAME(sys_lseek)
/* 20 */ .long SYMBOL_NAME(sys_getpid)
- .long SYMBOL_NAME(sys_mount_wrapper)
+ .long SYMBOL_NAME(sys_mount)
.long SYMBOL_NAME(sys_oldumount)
- .long SYMBOL_NAME(sys_setuid)
- .long SYMBOL_NAME(sys_getuid)
+ .long SYMBOL_NAME(sys_setuid16)
+ .long SYMBOL_NAME(sys_getuid16)
/* 25 */ .long SYMBOL_NAME(sys_stime)
.long SYMBOL_NAME(sys_ptrace)
.long SYMBOL_NAME(sys_alarm)
- .long SYMBOL_NAME(sys_fstat)
+ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_fstat */
.long SYMBOL_NAME(sys_pause)
/* 30 */ .long SYMBOL_NAME(sys_utime)
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_stty */
@@ -55,11 +55,11 @@
.long SYMBOL_NAME(sys_times)
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_prof */
/* 45 */ .long SYMBOL_NAME(sys_brk)
- .long SYMBOL_NAME(sys_setgid)
- .long SYMBOL_NAME(sys_getgid)
+ .long SYMBOL_NAME(sys_setgid16)
+ .long SYMBOL_NAME(sys_getgid16)
.long SYMBOL_NAME(sys_signal)
- .long SYMBOL_NAME(sys_geteuid)
-/* 50 */ .long SYMBOL_NAME(sys_getegid)
+ .long SYMBOL_NAME(sys_geteuid16)
+/* 50 */ .long SYMBOL_NAME(sys_getegid16)
.long SYMBOL_NAME(sys_acct)
.long SYMBOL_NAME(sys_umount)
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_lock */
@@ -79,8 +79,8 @@
.long SYMBOL_NAME(sys_sigaction)
.long SYMBOL_NAME(sys_sgetmask)
.long SYMBOL_NAME(sys_ssetmask)
-/* 70 */ .long SYMBOL_NAME(sys_setreuid)
- .long SYMBOL_NAME(sys_setregid)
+/* 70 */ .long SYMBOL_NAME(sys_setreuid16)
+ .long SYMBOL_NAME(sys_setregid16)
.long SYMBOL_NAME(sys_sigsuspend_wrapper)
.long SYMBOL_NAME(sys_sigpending)
.long SYMBOL_NAME(sys_sethostname)
@@ -89,11 +89,11 @@
.long SYMBOL_NAME(sys_getrusage)
.long SYMBOL_NAME(sys_gettimeofday)
.long SYMBOL_NAME(sys_settimeofday)
-/* 80 */ .long SYMBOL_NAME(sys_getgroups)
- .long SYMBOL_NAME(sys_setgroups)
+/* 80 */ .long SYMBOL_NAME(sys_getgroups16)
+ .long SYMBOL_NAME(sys_setgroups16)
.long SYMBOL_NAME(old_select)
.long SYMBOL_NAME(sys_symlink)
- .long SYMBOL_NAME(sys_lstat)
+ .long SYMBOL_NAME(sys_ni_syscall) /* was sys_lstat */
/* 85 */ .long SYMBOL_NAME(sys_readlink)
.long SYMBOL_NAME(sys_uselib)
.long SYMBOL_NAME(sys_swapon)
@@ -104,7 +104,7 @@
.long SYMBOL_NAME(sys_truncate)
.long SYMBOL_NAME(sys_ftruncate)
.long SYMBOL_NAME(sys_fchmod)
-/* 95 */ .long SYMBOL_NAME(sys_fchown)
+/* 95 */ .long SYMBOL_NAME(sys_fchown16)
.long SYMBOL_NAME(sys_getpriority)
.long SYMBOL_NAME(sys_setpriority)
.long SYMBOL_NAME(sys_ni_syscall) /* was sys_profil */
@@ -132,7 +132,7 @@
/* 120 */ .long SYMBOL_NAME(sys_clone_wapper)
.long SYMBOL_NAME(sys_setdomainname)
.long SYMBOL_NAME(sys_newuname)
- .long SYMBOL_NAME(sys_ni_syscall) /* .long SYMBOL_NAME(sys_modify_ldt) */
+ .long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_adjtimex)
/* 125 */ .long SYMBOL_NAME(sys_mprotect)
.long SYMBOL_NAME(sys_sigprocmask)
@@ -147,9 +147,9 @@
/* 135 */ .long SYMBOL_NAME(sys_sysfs)
.long SYMBOL_NAME(sys_personality)
.long SYMBOL_NAME(sys_ni_syscall) /* .long _sys_afs_syscall */
- .long SYMBOL_NAME(sys_setfsuid)
- .long SYMBOL_NAME(sys_setfsgid)
-/* 140 */ .long SYMBOL_NAME(sys_llseek_wrapper)
+ .long SYMBOL_NAME(sys_setfsuid16)
+ .long SYMBOL_NAME(sys_setfsgid16)
+/* 140 */ .long SYMBOL_NAME(sys_llseek)
.long SYMBOL_NAME(sys_getdents)
.long SYMBOL_NAME(sys_select)
.long SYMBOL_NAME(sys_flock)
@@ -173,14 +173,14 @@
.long SYMBOL_NAME(sys_sched_rr_get_interval)
.long SYMBOL_NAME(sys_nanosleep)
.long SYMBOL_NAME(sys_mremap)
- .long SYMBOL_NAME(sys_setresuid)
-/* 165 */ .long SYMBOL_NAME(sys_getresuid)
+ .long SYMBOL_NAME(sys_setresuid16)
+/* 165 */ .long SYMBOL_NAME(sys_getresuid16)
.long SYMBOL_NAME(sys_ni_syscall)
.long SYMBOL_NAME(sys_query_module)
.long SYMBOL_NAME(sys_poll)
.long SYMBOL_NAME(sys_nfsservctl)
-/* 170 */ .long SYMBOL_NAME(sys_setresgid)
- .long SYMBOL_NAME(sys_getresgid)
+/* 170 */ .long SYMBOL_NAME(sys_setresgid16)
+ .long SYMBOL_NAME(sys_getresgid16)
.long SYMBOL_NAME(sys_prctl)
.long SYMBOL_NAME(sys_rt_sigreturn_wrapper)
.long SYMBOL_NAME(sys_rt_sigaction)
@@ -191,7 +191,7 @@
.long SYMBOL_NAME(sys_rt_sigsuspend_wrapper)
/* 180 */ .long SYMBOL_NAME(sys_pread)
.long SYMBOL_NAME(sys_pwrite)
- .long SYMBOL_NAME(sys_chown)
+ .long SYMBOL_NAME(sys_chown16)
.long SYMBOL_NAME(sys_getcwd)
.long SYMBOL_NAME(sys_capget)
/* 185 */ .long SYMBOL_NAME(sys_capset)
@@ -207,8 +207,27 @@
/* 195 */ .long SYMBOL_NAME(sys_stat64)
.long SYMBOL_NAME(sys_lstat64)
.long SYMBOL_NAME(sys_fstat64)
+ .long SYMBOL_NAME(sys_lchown)
+ .long SYMBOL_NAME(sys_getuid)
+/* 200 */ .long SYMBOL_NAME(sys_getgid)
+ .long SYMBOL_NAME(sys_geteuid)
+ .long SYMBOL_NAME(sys_getegid)
+ .long SYMBOL_NAME(sys_setreuid)
+ .long SYMBOL_NAME(sys_setregid)
+/* 205 */ .long SYMBOL_NAME(sys_getgroups)
+ .long SYMBOL_NAME(sys_setgroups)
+ .long SYMBOL_NAME(sys_fchown)
+ .long SYMBOL_NAME(sys_setresuid)
+ .long SYMBOL_NAME(sys_getresuid)
+/* 210 */ .long SYMBOL_NAME(sys_setresgid)
+ .long SYMBOL_NAME(sys_getresgid)
+ .long SYMBOL_NAME(sys_chown)
+ .long SYMBOL_NAME(sys_setuid)
+ .long SYMBOL_NAME(sys_setgid)
+/* 215 */ .long SYMBOL_NAME(sys_setfsuid)
+ .long SYMBOL_NAME(sys_setfsgid)
- .rept NR_syscalls-197
+ .rept NR_syscalls-216
.long SYMBOL_NAME(sys_ni_syscall)
.endr
#endif
diff --git a/arch/arm/kernel/debug-armv.S b/arch/arm/kernel/debug-armv.S
index fef1489b7..5802dac70 100644
--- a/arch/arm/kernel/debug-armv.S
+++ b/arch/arm/kernel/debug-armv.S
@@ -134,19 +134,26 @@
#elif defined(CONFIG_ARCH_SA1100)
.macro addruart,rx
mov \rx, #0xf8000000
- add \rx, \rx, #0x00050000
+ add \rx, \rx, #0x00050000 @ Ser3
+ @add \rx, \rx, #0x00010000 @ Ser1
.endm
.macro senduart,rd,rx
- str \rd, [\rx, #0x14] @ UARTDR
+ str \rd, [\rx, #0x14] @ UTDR
.endm
- .macro busyuart,rd,rx
+ .macro waituart,rd,rx
1001: ldr \rd, [\rx, #0x20] @ UTSR1
- tst \rd, #1 << 2
+ tst \rd, #1 << 2 @ UTSR1_TNF
beq 1001b
.endm
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #0x20] @ UTSR1
+ tst \rd, #1 << 0 @ UTSR1_TBY
+ bne 1001b
+ .endm
+
#else
#error Unknown architecture
#endif
diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c
index dc7cc054e..6158e995a 100644
--- a/arch/arm/kernel/dec21285.c
+++ b/arch/arm/kernel/dec21285.c
@@ -220,7 +220,9 @@ void __init dc21285_init(void)
#ifdef CONFIG_HOST_FOOTBRIDGE
csrio.flags = IORESOURCE_IO;
+ csrio.name = "DC21285";
csrmem.flags = IORESOURCE_MEM;
+ csrmem.name = "DC21285";
allocate_resource(&ioport_resource, &csrio, 128,
0xff00, 0xffff, 128, NULL, NULL);
@@ -244,7 +246,7 @@ void __init dc21285_init(void)
(1 << 31) | (1 << 29) | (1 << 28) | (1 << 24);
#endif
- printk(KERN_DEBUG"PCI: DC21285 footbridge, revision %02lX\n",
+ printk(KERN_DEBUG "PCI: DC21285 footbridge, revision %02lX\n",
*CSR_CLASSREV & 0xff);
pci_scan_bus(0, &dc21285_ops, NULL);
diff --git a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S
index 5d9ce0ac6..f2dc9e36c 100644
--- a/arch/arm/kernel/entry-armo.S
+++ b/arch/arm/kernel/entry-armo.S
@@ -535,7 +535,6 @@ Ldata_unknown: @ Part of jumptable
mov r0, r1
mov r1, r4
mov r2, r3
- mov r3, lr
b baddataabort
Ldata_ldrstr_post:
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 6d4107ede..f4f03ee93 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -429,7 +429,10 @@ __und_invalid: sub sp, sp, #S_FRAME_SIZE
and r2, r6, #31 @ int mode
b SYMBOL_NAME(bad_mode)
-
+#ifdef CONFIG_NWFPE
+ /* The FPE is always present */
+ .equ fpe_not_present, 0
+#else
wfs_mask_data: .word 0x0e200110 @ WFS/RFS
.word 0x0fef0fff
.word 0x0d0d0100 @ LDF [sp]/STF [sp]
@@ -466,6 +469,7 @@ fpe_not_present:
add r5, r5, r4, lsl #2
str r5, [sp, r6, lsr #14] @ Save reg
mov pc, r9
+#endif
/*
* SVC mode handlers
@@ -685,11 +689,11 @@ ENTRY(__switch_to)
stmfd sp!, {r4 - sl, fp, lr} @ Store most regs on stack
mrs ip, cpsr
stmfd sp!, {ip} @ Save cpsr_SVC
- ldr r2, [r1, #TSS_DOMAIN]
str sp, [r0, #TSS_SAVE] @ Save sp_SVC
ldr sp, [r1, #TSS_SAVE] @ Get saved sp_SVC
- mcr p15, 0, r2, c3, c0 @ Set domain register
+ ldr r2, [r1, #TSS_DOMAIN]
ldmfd sp!, {ip}
+ mcr p15, 0, r2, c3, c0 @ Set domain register
msr spsr, ip @ Save tasks CPSR into SPSR for this return
ldmfd sp!, {r4 - sl, fp, pc}^ @ Load all regs saved previously
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index bdf6de6b3..2be1a6012 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -3,6 +3,9 @@
* All exits to user mode from the kernel go through this code.
*/
+#define S_OFF 8
+#define SYSCALL_REGS r4, r5
+
/*
* Define to favour ARM8, ARM9 and StrongARM cpus. This says that it is
* cheaper to use two LDR instructions than a two-register LDM, if the
@@ -16,9 +19,9 @@
.align 5
fast_syscall_return:
- str r0, [sp, #S_R0 + 4] @ returned r0
+ str r0, [sp, #S_R0 + S_OFF] @ returned r0
slow_syscall_return:
- add sp, sp, #4
+ add sp, sp, #S_OFF
ret_from_sys_call:
#ifdef HARVARD_CACHE
ldr r0, bh_data
@@ -74,65 +77,71 @@ ret_from_exception:
/*=============================================================================
* SWI handler
*-----------------------------------------------------------------------------
- *
- * We now handle sys-call tracing, and the errno in the task structure.
- * Still have a problem with >4 arguments for functions. Theres only
- * a couple of functions in the code that have 5 arguments, so Im not
- * too worried.
*/
+/*
+ * Create some aliases for some registers. These should allow
+ * us to have in theory up to 7 arguments to a function.
+ */
+scno .req r9 @ syscall number
+tbl .req r8 @ syscall table pointer
+tip .req r7 @ temporary IP
+
.align 5
vector_swi: save_user_regs
mask_pc lr, lr
mov fp, #0
- ldr r6, [lr, #-4] @ get SWI instruction
- arm700_bug_check r6, r7
+ ldr scno, [lr, #-4] @ get SWI instruction
+ arm700_bug_check scno, ip
#ifdef CONFIG_ALIGNMENT_TRAP
- ldr r7, .LCswi
- ldr r7, [r7]
- mcr p15, 0, r7, c1, c0
+ ldr ip, .LCswi
+ ldr ip, [ip]
+ mcr p15, 0, ip, c1, c0
#endif
- enable_irqs r7
+ enable_irqs ip
- str r4, [sp, #-4]! @ new style: (r0 = arg1, r4 = arg5)
+ stmdb sp!, {SYSCALL_REGS} @ new style: (r0 = arg1, r4 = arg5, r5 = arg6)
+ @ Note that we dont have to handle
+ @ sys_syscalls arg7 here
adrsvc al, lr, fast_syscall_return
- bic r6, r6, #0xff000000 @ mask off SWI op-code
- eor r6, r6, #OS_NUMBER<<20 @ check OS number
- cmp r6, #NR_syscalls @ check upper syscall limit
+ bic scno, scno, #0xff000000 @ mask off SWI op-code
+ eor scno, scno, #OS_NUMBER<<20 @ check OS number
+ cmp scno, #NR_syscalls @ check upper syscall limit
bcs 2f
- get_current_task r7
- ldr ip, [r7, #TSK_FLAGS] @ check for syscall tracing
- adr r5, SYMBOL_NAME(sys_call_table)
+ get_current_task ip
+ ldr ip, [ip, #TSK_FLAGS] @ check for syscall tracing
+ adr tbl, SYMBOL_NAME(sys_call_table)
tst ip, #PF_TRACESYS
- ldreq pc, [r5, r6, lsl #2] @ call sys routine
+ ldreq pc, [tbl, scno, lsl #2] @ call sys routine
- ldr r7, [sp, #S_IP + 4] @ save old IP
- mov r0, #0
- str r0, [sp, #S_IP + 4] @ trace entry [IP = 0]
+ ldr tip, [sp, #S_IP + S_OFF] @ save old IP
+ mov ip, #0
+ str ip, [sp, #S_IP + S_OFF] @ trace entry [IP = 0]
bl SYMBOL_NAME(syscall_trace)
- str r7, [sp, #S_IP + 4]
+ str tip, [sp, #S_IP + S_OFF]
- ldmib sp, {r0 - r3} @ have to reload r0 - r3
+ add ip, sp, #S_OFF
+ ldmia ip, {r0 - r3} @ have to reload r0 - r3
mov lr, pc
- ldr pc, [r5, r6, lsl #2] @ call sys routine
- str r0, [sp, #S_R0 + 4] @ returned r0
+ ldr pc, [tbl, scno, lsl #2] @ call sys routine
+ str r0, [sp, #S_R0 + S_OFF] @ returned r0
- mov r0, #1
- str r0, [sp, #S_IP + 4] @ trace exit [IP = 1]
+ mov ip, #1
+ str ip, [sp, #S_IP + S_OFF] @ trace exit [IP = 1]
bl SYMBOL_NAME(syscall_trace)
- str r7, [sp, #S_IP + 4]
+ str tip, [sp, #S_IP + S_OFF]
b slow_syscall_return
-2: add r1, sp, #4
- tst r6, #0x00f00000 @ is it a Unix SWI?
+2: add r1, sp, #S_OFF
+ tst scno, #0x00f00000 @ is it a Unix SWI?
bne 3f
- subs r0, r6, #(KSWI_SYS_BASE - KSWI_BASE)
+ subs r0, scno, #(KSWI_SYS_BASE - KSWI_BASE)
bcs SYMBOL_NAME(arm_syscall)
b SYMBOL_NAME(sys_ni_syscall) @ not private func
-3: eor r0, r6, #OS_NUMBER <<20 @ Put OS number back
+3: eor r0, scno, #OS_NUMBER <<20 @ Put OS number back
adrsvc al, lr, slow_syscall_return
b SYMBOL_NAME(deferred)
@@ -150,67 +159,49 @@ ENTRY(sys_call_table)
@ r0 = syscall number
@ r5 = syscall table
SYMBOL_NAME(sys_syscall):
- eor r6, r0, #OS_NUMBER << 20
- cmp r6, #NR_syscalls @ check range
- add ip, sp, #4
- ldmleib ip, {r0 - r4} @ get our args
- strle r4, [sp] @ Put our arg on the stack
- ldrle pc, [r5, r6, lsl #2]
+ eor scno, r0, #OS_NUMBER << 20
+ cmp scno, #NR_syscalls @ check range
+ add ip, sp, #S_OFF
+ ldmleib ip, {r0 - r3, SYSCALL_REGS} @ get our args
+ stmleia sp, {SYSCALL_REGS} @ Put our arg on the stack
+ ldrle pc, [tbl, scno, lsl #2]
mov r0, #-ENOSYS
- mov pc, lr
+ RETINSTR(mov,pc,lr)
sys_fork_wrapper:
- add r0, sp, #4
+ add r0, sp, #S_OFF
b SYMBOL_NAME(sys_fork)
sys_vfork_wrapper:
- add r0, sp, #4
+ add r0, sp, #S_OFF
b SYMBOL_NAME(sys_vfork)
sys_execve_wrapper:
- add r3, sp, #4
+ add r3, sp, #S_OFF
b SYMBOL_NAME(sys_execve)
-sys_mount_wrapper:
- mov r6, lr
- add r5, sp, #4
- str r5, [sp]
- str r4, [sp, #-4]!
- bl SYMBOL_NAME(sys_compat_mount)
- add sp, sp, #4
- RETINSTR(mov,pc,r6)
-
sys_clone_wapper:
- add r2, sp, #4
+ add r2, sp, #S_OFF
b SYMBOL_NAME(sys_clone)
-sys_llseek_wrapper:
- mov r6, lr
- add r5, sp, #4
- str r5, [sp]
- str r4, [sp, #-4]!
- bl SYMBOL_NAME(sys_compat_llseek)
- add sp, sp, #4
- RETINSTR(mov,pc,r6)
-
sys_sigsuspend_wrapper:
- add r3, sp, #4
+ add r3, sp, #S_OFF
b SYMBOL_NAME(sys_sigsuspend)
sys_rt_sigsuspend_wrapper:
- add r2, sp, #4
+ add r2, sp, #S_OFF
b SYMBOL_NAME(sys_rt_sigsuspend)
sys_sigreturn_wrapper:
- add r0, sp, #4
+ add r0, sp, #S_OFF
b SYMBOL_NAME(sys_sigreturn)
sys_rt_sigreturn_wrapper:
- add r0, sp, #4
+ add r0, sp, #S_OFF
b SYMBOL_NAME(sys_rt_sigreturn)
sys_sigaltstack_wrapper:
- ldr r2, [sp, #4 + S_SP]
+ ldr r2, [sp, #S_OFF + S_SP]
b do_sigaltstack
.data
diff --git a/arch/arm/kernel/head-armv.S b/arch/arm/kernel/head-armv.S
index 2996d89af..35e71a4a9 100644
--- a/arch/arm/kernel/head-armv.S
+++ b/arch/arm/kernel/head-armv.S
@@ -69,7 +69,7 @@ ENTRY(_stext)
* r1 contains the unique architecture number. See
* linux/arch/arm/kernel/setup.c machine_desc[] array for the complete
* list. If you require a new number, please follow the instructions
- * given in Documentation/ARM-README.
+ * given in Documentation/arm/README.
*/
__entry: teq r0, #0
movne r0, #'i'
@@ -83,7 +83,7 @@ __entry: teq r0, #0
moveq r0, #'a'
beq __error
bl __create_page_tables
- adr lr, __aligned_call
+ adr lr, __ret
add pc, r10, #12 @ flush caches (returns ctrl reg)
__switch_data: .long __mmap_switched
@@ -94,16 +94,11 @@ __switch_data: .long __mmap_switched
.long SYMBOL_NAME(cr_alignment)
.long SYMBOL_NAME(init_task_union)+8192
- /*
- * This needs to be aligned to a cache line.
- */
- .align 5
-__aligned_call:
- ldr lr, __switch_data
-#ifdef CONFIG_ALIGNMENT_TRAP
- orr r0, r0, #2 @ ...........A.
-#endif
+__ret: ldr lr, __switch_data
mcr p15, 0, r0, c1, c0
+ mov r0, r0
+ mov r0, r0
+ mov r0, r0
mov pc, lr
/*
@@ -126,6 +121,9 @@ __mmap_switched:
str r9, [r6] @ Save processor ID
str r1, [r7] @ Save machine type
+#ifdef CONFIG_ALIGNMENT_TRAP
+ orr r0, r0, #2 @ ...........A.
+#endif
bic r2, r0, #2 @ Clear 'A' bit
stmia r8, {r0, r2} @ Save control register values
b SYMBOL_NAME(start_kernel)
@@ -137,16 +135,16 @@ __mmap_switched:
* amount which are required to get the kernel running, which
* generally means mapping in the kernel code.
*
- * We only map in 2MB of RAM, which should be sufficient in
+ * We only map in 4MB of RAM, which should be sufficient in
* all cases.
*
- * r4 = physical address of page tables
* r5 = physical address of start of RAM
* r6 = physical IO address
* r7 = byte offset into page tables for IO
* r8 = page table flags
*/
__create_page_tables:
+ add r4, r5, #SWAPPER_PGDIR_OFFSET
mov r0, r4
mov r3, #0
add r2, r0, #0x4000 @ Clear page table
@@ -157,13 +155,22 @@ __create_page_tables:
teq r0, r2
bne 1b
/*
- * map in two sections (2MB) for kernel.
+ * Create identity mapping for first MB of kernel.
+ * map in four sections (4MB) for kernel.
* these are marked cacheable and bufferable.
+ *
+ * The identity mapping will be removed by paging_init()
*/
- add r0, r4, #(TEXTADDR - 0x8000) >> 18
mov r3, #0x0c
orr r3, r3, r8
add r3, r3, r5
+ add r0, r4, r5, lsr #18
+ str r3, [r0]
+ add r0, r4, #(TEXTADDR - 0x8000) >> 18
+ str r3, [r0], #4
+ add r3, r3, #1 << 20
+ str r3, [r0], #4
+ add r3, r3, #1 << 20
str r3, [r0], #4
add r3, r3, #1 << 20
str r3, [r0], #4
@@ -174,8 +181,11 @@ __create_page_tables:
* via a serial before paging_init.
*/
add r0, r4, r7
+ rsb r3, r7, #0x4000 @ PTRS_PER_PGD*sizeof(long)
+ cmp r3, #0x0800
+ addge r2, r0, #0x0800
+ addlt r2, r0, r3
orr r3, r6, r8
- add r2, r0, #0x0800
1: str r3, [r0], #4
add r3, r3, #1 << 20
teq r0, r2
@@ -273,7 +283,7 @@ __lookup_processor_type:
* Lookup machine architecture
* r1 = machine architecture number
* Returns:
- * r4 = physical address of page tables
+ * r4 = unused word
* r5 = physical start address of RAM
* r6 = physical address of IO
* r7 = byte offset into page tables for IO
@@ -284,7 +294,6 @@ __lookup_architecture_type:
adr r4, __arch_types_start
add r4, r4, r1, lsl #4
ldmia r4, {r4, r5, r6, r7}
- add r4, r5, #SWAPPER_PGDIR_OFFSET
mov r7, r7, lsr #18
mov pc, lr
1: mov r7, #0
@@ -330,20 +339,20 @@ __arch_types_start:
@ 0x04 - DEC EBSA285
.long 0
.long 0
- .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000)
- .long 0xe0000000
+ .long DC21285_ARMCSR_BASE
+ .long 0xfe000000
@ 0x05 - Rebel.com NetWinder
.long 0
.long 0
- .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000)
- .long 0xe0000000
+ .long DC21285_ARMCSR_BASE
+ .long 0xfe000000
@ 0x06 - CATS
.long 0
.long 0
- .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000)
- .long 0xe0000000
+ .long DC21285_ARMCSR_BASE
+ .long 0xfe000000
@ 0x07 - tbox
.long 0
@@ -398,9 +407,16 @@ __arch_types_start:
.long 0
.long 0
.long 0
-__arch_types_end:
- @ unknown - SA1100
+
+ @ 0x10 - SA1100
.long 0
.long 0xc0000000
.long 0x80000000
- .long 0xe0000000
+ .long 0xf8000000
+
+ /*
+ * Don't add anything here unless you have an
+ * architecture number allocated - see
+ * Documentation/arm/README
+ */
+__arch_types_end:
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 9afacbde3..46afd5938 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -50,13 +50,13 @@ void enable_hlt(void)
static int __init nohlt_setup(char *__unused)
{
hlt_counter = 1;
- return 0;
+ return 1;
}
static int __init hlt_setup(char *__unused)
{
hlt_counter = 0;
- return 0;
+ return 1;
}
__setup("nohlt", nohlt_setup);
@@ -114,6 +114,7 @@ void machine_halt(void)
void machine_power_off(void)
{
+ arch_power_off();
}
void show_regs(struct pt_regs * regs)
@@ -284,7 +285,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
{
if (current->used_math)
- memcpy(fp, &current->thread.fpstate.soft, sizeof (fp));
+ memcpy(fp, &current->thread.fpstate.soft, sizeof (*fp));
return current->used_math;
}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index a060bf4d9..a2f7292f6 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -54,13 +54,13 @@ struct meminfo meminfo;
struct machine_desc {
const char *name; /* architecture name */
unsigned int param_offset; /* parameter page */
+ unsigned int video_start; /* start of video RAM */
+ unsigned int video_end; /* end of video RAM */
unsigned int reserve_lp0 :1; /* never has lp0 */
unsigned int reserve_lp1 :1; /* never has lp1 */
unsigned int reserve_lp2 :1; /* never has lp2 */
unsigned int broken_hlt :1; /* hlt is broken */
unsigned int soft_reboot :1; /* soft reboot */
- unsigned int video_start; /* start of video RAM */
- unsigned int video_end; /* end of video RAM */
void (*fixup)(struct machine_desc *,
struct param_struct *, char **);
};
@@ -201,7 +201,7 @@ parse_cmdline(char **cmdline_p, char *from)
meminfo.nr_banks = 0;
}
- start = 0;
+ start = PHYS_OFFSET;
size = memparse(from + 4, &from);
if (*from == '@')
start = memparse(from + 1, &from);
@@ -250,17 +250,18 @@ static void __init setup_initrd(unsigned int start, unsigned int size)
}
#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT)
-#define P_PFN_DOWN(x) O_PFN_DOWN((x) - PHYS_OFFSET)
#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x))
#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT)
-#define P_PFN_UP(x) O_PFN_UP((x) - PHYS_OFFSET)
#define V_PFN_UP(x) O_PFN_UP(__pa(x))
#define PFN_SIZE(x) ((x) >> PAGE_SHIFT)
#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
(((unsigned long)(s)) & PAGE_MASK))
+/*
+ * FIXME: These can be removed when Ingo's cleanup patch goes in
+ */
#define free_bootmem(s,sz) free_bootmem((s)<<PAGE_SHIFT, (sz)<<PAGE_SHIFT)
#define reserve_bootmem(s,sz) reserve_bootmem((s)<<PAGE_SHIFT, (sz)<<PAGE_SHIFT)
@@ -277,10 +278,10 @@ static unsigned int __init find_bootmap_pfn(unsigned int bootmap_pages)
*/
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start) {
- if (__pa(initrd_end) > (meminfo.end + PHYS_OFFSET)) {
+ if (__pa(initrd_end) > meminfo.end) {
printk ("initrd extends beyond end of memory "
"(0x%08lx > 0x%08lx) - disabling initrd\n",
- __pa(initrd_end), meminfo.end + PHYS_OFFSET);
+ __pa(initrd_end), meminfo.end);
initrd_start = 0;
initrd_end = 0;
}
@@ -373,7 +374,7 @@ static void __init setup_bootmem(void)
#endif
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start)
- reserve_bootmem(O_PFN_DOWN(initrd_start),
+ reserve_bootmem(V_PFN_DOWN(initrd_start),
PFN_RANGE(initrd_start, initrd_end));
#endif
}
@@ -528,16 +529,66 @@ fixup_coebsa285(struct machine_desc *desc, struct param_struct *params,
char **cmdline)
{
#if 0
- if (machine_is_co285()) {
- extern unsigned long boot_memory_end;
- extern char boot_command_line[];
+ extern unsigned long boot_memory_end;
+ extern char boot_command_line[];
- meminfo.nr_banks = 1;
- meminfo.bank[0].start = PHYS_OFFSET;
- meminfo.bank[0].size = boot_memory_end;
+ meminfo.nr_banks = 1;
+ meminfo.bank[0].start = PHYS_OFFSET;
+ meminfo.bank[0].size = boot_memory_end;
+
+ *cmdline = boot_command_line;
+#endif
+}
- *cmdline = boot_command_line;
+static void __init
+fixup_sa1100(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline)
+{
+#ifdef CONFIG_ARCH_SA1100
+ int i;
+ extern struct mem_desc {
+ unsigned long phys_start;
+ unsigned long length;
+ } mem_desc[];
+ extern unsigned int mem_desc_size;
+
+ for( i = 0; i < mem_desc_size; i++ ) {
+ if( i >= NR_BANKS ) {
+ printk( __FUNCTION__
+ ": mem_desc too large for meminfo structure\n");
+ break;
+ }
+ meminfo.bank[i].start = mem_desc[i].phys_start;
+ meminfo.bank[i].size = mem_desc[i].length;
}
+ meminfo.nr_banks = i;
+
+#if defined(CONFIG_SA1100_BRUTUS)
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk( 1, 0, 0, 8192 );
+ setup_initrd( __phys_to_virt(0xd8000000), 0x00400000 );
+#elif defined(CONFIG_SA1100_EMPEG)
+ ROOT_DEV = MKDEV( 3, 1 ); /* /dev/hda1 */
+ setup_ramdisk( 1, 0, 0, 4096 );
+ setup_initrd( 0xd0000000+((1024-320)*1024), (320*1024) );
+#elif defined(CONFIG_SA1100_TIFON)
+ ROOT_DEV = MKDEV(UNNAMED_MAJOR, 0);
+ setup_ramdisk(1, 0, 0, 4096);
+ setup_initrd( 0xd0000000 + 0x1100004, 0x140000 );
+#elif defined(CONFIG_SA1100_VICTOR)
+ ROOT_DEV = MKDEV( 60, 2 );
+
+ /* Get command line parameters passed from the loader (if any) */
+ if( *((char*)0xc0000000) )
+ strcpy( default_command_line, ((char *)0xc0000000) );
+
+ /* power off if any problem */
+ strcat( default_command_line, " panic=1" );
+#elif defined(CONFIG_SA1100_LART)
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk(1, 0, 0, 8192);
+ setup_initrd(0xc0400000, 0x00400000);
+#endif
#endif
}
@@ -565,7 +616,7 @@ static struct machine_desc machine_desc[] __initdata = {
NO_VIDEO,
0, 0, 0, 0, 0,
NULL
- }, { "Nexus-FTV/PCI", /* Philip Blundell */
+ }, { "FTV/PCI", /* Philip Blundell */
NO_PARAMS,
NO_VIDEO,
0, 0, 0, 0, 0,
@@ -627,9 +678,15 @@ static struct machine_desc machine_desc[] __initdata = {
NULL
}, { "Shark", /* Alexander Schulz */
NO_PARAMS,
- NO_VIDEO,
+ /* do you really mean 0x200000? */
+ 0x06000000, 0x06000000+0x00200000,
0, 0, 0, 0, 0,
NULL
+ }, { "SA1100-based", /* Nicolas Pitre */
+ NO_PARAMS,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ fixup_sa1100
}
};
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 852bbfac1..f9fbd2536 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -18,6 +18,7 @@
#include <linux/stddef.h>
#include <linux/binfmts.h>
#include <linux/tty.h>
+#include <linux/highuid.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
@@ -277,6 +278,7 @@ setup_sigcontext(struct sigcontext *sc, /*struct _fpstate *fpstate,*/
err |= __put_user (current->thread.trap_no, &sc->trap_no);
err |= __put_user (current->thread.error_code, &sc->error_code);
+ err |= __put_user (current->thread.address, &sc->fault_address);
err |= __put_user (mask, &sc->oldmask);
return err;
@@ -500,6 +502,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
info.si_code = SI_USER;
info.si_pid = current->p_pptr->pid;
info.si_uid = current->p_pptr->uid;
+ info.si_uid16 = high2lowuid(current->p_pptr->uid);
}
/* If the (new) signal is now blocked, requeue it. */
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 408149bc5..5e989663b 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -79,12 +79,26 @@ out:
return error;
}
+#define PGOFF_SHIFT (PAGE_SHIFT - 12)
+#define PGOFF_MASK (~((1 << PGOFF_SHIFT) - 1))
+
/*
- * Perform the select(nd, in, out, ex, tv) and mmap() system
- * calls. ARM Linux didn't use to be able to handle more than
- * 4 system call parameters, so these system calls used a memory
- * block for parameter passing..
+ * Note: off_4k is always units of 4K. If we can't do the requested
+ * offset, we return EINVAL.
*/
+asmlinkage long
+sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+ unsigned long flags, unsigned long fd, unsigned long off_4k)
+{
+ unsigned long pgoff;
+
+ if (off_4k & ~PGOFF_MASK)
+ return -EINVAL;
+
+ pgoff = off_4k >> PGOFF_SHIFT;
+
+ return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
struct mmap_arg_struct {
unsigned long addr;
@@ -112,6 +126,10 @@ out:
return error;
}
+/*
+ * Perform the select(nd, in, out, ex, tv) and mmap() system
+ * calls.
+ */
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
struct sel_arg_struct {
@@ -251,48 +269,11 @@ out:
return error;
}
-/*
- * Detect the old function calling standard
- */
-static inline unsigned long old_calling_standard (struct pt_regs *regs)
-{
- unsigned long instr, *pcv = (unsigned long *)(instruction_pointer(regs) - 8);
- return (!get_user (instr, pcv) && instr == 0xe1a0300d);
-}
-
/* Compatability functions - we used to pass 5 parameters as r0, r1, r2, *r3, *(r3+4)
* We now use r0 - r4, and return an error if the old style calling standard is used.
* Eventually these functions will disappear.
*/
-asmlinkage int
-sys_compat_llseek (unsigned int fd, unsigned long offset_high, unsigned long offset_low,
- loff_t *result, unsigned int origin, struct pt_regs *regs)
-{
- extern int sys_llseek (unsigned int, unsigned long, unsigned long, loff_t *, unsigned int);
-
- if (old_calling_standard (regs)) {
- printk (KERN_NOTICE "%s (%d): unsupported llseek call standard\n",
- current->comm, current->pid);
- return -EINVAL;
- }
- return sys_llseek (fd, offset_high, offset_low, result, origin);
-}
-
-asmlinkage int
-sys_compat_mount (char *devname, char *dirname, char *type, unsigned long flags, void *data,
- struct pt_regs *regs)
-{
- extern int sys_mount (char *, char *, char *, unsigned long, void *);
-
- if (old_calling_standard (regs)) {
- printk (KERN_NOTICE "%s (%d): unsupported mount call standard\n",
- current->comm, current->pid);
- return -EINVAL;
- }
- return sys_mount (devname, dirname, type, flags, data);
-}
-
-asmlinkage int sys_uname (struct old_utsname * name)
+asmlinkage int sys_uname(struct old_utsname * name)
{
static int warned = 0;
int err;
@@ -331,15 +312,15 @@ asmlinkage int sys_olduname(struct oldold_utsname * name)
down(&uts_sem);
error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
- error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
- error -= __put_user(0,name->nodename+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
- error -= __put_user(0,name->release+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
- error -= __put_user(0,name->version+__OLD_UTS_LEN);
- error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
- error -= __put_user(0,name->machine+__OLD_UTS_LEN);
+ error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
+ error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
+ error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
+ error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
+ error |= __put_user(0,name->release+__OLD_UTS_LEN);
+ error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
+ error |= __put_user(0,name->version+__OLD_UTS_LEN);
+ error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
+ error |= __put_user(0,name->machine+__OLD_UTS_LEN);
up(&uts_sem);
@@ -354,4 +335,3 @@ asmlinkage int sys_pause(void)
schedule();
return -ERESTARTNOHAND;
}
-
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index c48c62108..67c2597e6 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -112,7 +112,7 @@ void do_gettimeofday(struct timeval *tv)
/*
* xtime is atomically updated in timer_bh. lost_ticks is
- * nonzero if the tiemr bottom half hasnt executed yet.
+ * nonzero if the timer bottom half hasnt executed yet.
*/
if (lost_ticks)
tv->tv_usec += USECS_PER_JIFFY;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 26ecfa194..ac15651d3 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -187,10 +187,11 @@ void die(const char *str, struct pt_regs *regs, int err)
dump_instr(instruction_pointer(regs), 0);
}
- spin_unlock_irq(&die_lock);
+ spin_unlock_irq(&die_lock);
+ do_exit(SIGSEGV);
}
-static void die_if_kernel(const char *str, struct pt_regs *regs, int err)
+void die_if_kernel(const char *str, struct pt_regs *regs, int err)
{
if (user_mode(regs))
return;
@@ -241,11 +242,10 @@ asmlinkage void do_unexp_fiq (struct pt_regs *regs)
}
/*
- * bad_mode handles the impossible case in the vectors.
- * If you see one of these, then it's extremely serious,
- * and could mean you have buggy hardware. It never
- * returns, and never tries to sync. We hope that we
- * can dump out some state information...
+ * bad_mode handles the impossible case in the vectors. If you see one of
+ * these, then it's extremely serious, and could mean you have buggy hardware.
+ * It never returns, and never tries to sync. We hope that we can at least
+ * dump out some state information...
*/
asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
{
@@ -255,7 +255,8 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode)
handler[reason], processor_modes[proc_mode]);
/*
- * Dump out the vectors and stub routines
+ * Dump out the vectors and stub routines. Maybe a better solution
+ * would be to dump them out only if we detect that they are corrupted.
*/
printk(KERN_CRIT "Vectors:\n");
dump_mem(0, 0x40);
@@ -279,6 +280,9 @@ asmlinkage void math_state_restore (void)
current->used_math = 1;
}
+/*
+ * Handle some more esoteric system calls
+ */
asmlinkage int arm_syscall (int no, struct pt_regs *regs)
{
switch (no) {
@@ -295,7 +299,7 @@ asmlinkage int arm_syscall (int no, struct pt_regs *regs)
case 2: /* sys_cacheflush */
#ifdef CONFIG_CPU_32
- /* r0 = start, r1 = length, r2 = flags */
+ /* r0 = start, r1 = end, r2 = flags */
cpu_flush_cache_area(regs->ARM_r0, regs->ARM_r1, 1);
#endif
break;
@@ -308,7 +312,7 @@ asmlinkage int arm_syscall (int no, struct pt_regs *regs)
if (no <= 0x7ff)
return -ENOSYS;
#ifdef CONFIG_DEBUG_USER
- /* experiance shows that these seem to indicate that
+ /* experience shows that these seem to indicate that
* something catastrophic has happened
*/
printk("[%d] %s: arm syscall %d\n", current->pid, current->comm, no);
@@ -357,16 +361,19 @@ asmlinkage void arm_invalidptr(const char *function, int size)
function, __builtin_return_address(0), size);
}
-#ifdef CONFIG_CPU_26
-asmlinkage void baddataabort(int code, unsigned long instr, struct pt_regs *regs)
+/*
+ * A data abort trap was taken, but the instruction was not an instruction
+ * which should cause the trap to be taken. Try to abort it. Note that
+ * the while(1) is there because we cannot currently handle returning from
+ * this function.
+ */
+asmlinkage void
+baddataabort(int code, unsigned long instr, struct pt_regs *regs)
{
unsigned long phys, addr = instruction_pointer(regs);
#ifdef CONFIG_DEBUG_ERRORS
- printk("pid=%d\n", current->pid);
-
- show_regs(regs);
- dump_instr(instruction_pointer(regs), 1);
+ dump_instr(addr, 1);
{
pgd_t *pgd;
@@ -385,10 +392,10 @@ asmlinkage void baddataabort(int code, unsigned long instr, struct pt_regs *regs
printk ("\n");
}
#endif
- panic("unknown data abort code %d [pc=%08lx *pc=%08lx lr=%08lx sp=%08lx]",
- code, regs->ARM_pc, instr, regs->ARM_lr, regs->ARM_sp);
+ force_sig(SIGILL, current);
+ die_if_kernel("unknown data abort code", regs, instr);
+ while (1);
}
-#endif
void __bug(const char *file, int line, void *data)
{
@@ -425,6 +432,19 @@ asmlinkage void __div0(void)
__backtrace();
}
+void abort(void)
+{
+ void *lr = __builtin_return_address(0);
+
+ printk(KERN_CRIT "abort() called from %p! (Please "
+ "report to rmk@arm.linux.org.uk)\n", lr);
+
+ *(int *)0 = 0;
+
+ /* if that doesn't kill us, halt */
+ panic("Oops failed to kill thread");
+}
+
void __init trap_init(void)
{
extern void __trap_init(void);
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 9a22fe08f..5046a3377 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -5,8 +5,14 @@
#
L_TARGET := lib.a
-L_OBJS := backtrace.o bitops.o checksum.o delay.o \
- string.o system.o uaccess.o
+L_OBJS := changebit.o csumipv6.o csumpartial.o csumpartialcopy.o \
+ csumpartialcopyuser.o clearbit.o copy_page.o findbit.o \
+ memchr.o memcpy.o memset.o memzero.o setbit.o strchr.o \
+ strrchr.o testchangebit.o testclearbit.o testsetbit.o \
+ uaccess.o
+
+O_TARGET := lib.o
+O_OBJS := backtrace.o delay.o
ifeq ($(PROCESSOR),armo)
L_OBJS += uaccess-armo.o
@@ -25,13 +31,21 @@ endif
ifeq ($(MACHINE),ebsa110)
L_OBJS += io-ebsa110.o
else
- LX_OBJS += io.o
+ OX_OBJS += io.o
endif
ifeq ($(MACHINE),footbridge)
L_OBJS += io-footbridge.o
endif
+#
+# SA1100 IO routines happen to be the
+# same as the footbridge routines
+#
+ifeq ($(MACHINE),sa1100)
+ L_OBJS += io-footbridge.o
+endif
+
include $(TOPDIR)/Rules.make
.S.o:
@@ -42,5 +56,3 @@ constants.h: getconsdata.o extractconstants.pl
getconsdata.o: getconsdata.c
$(CC) $(CFLAGS) -c getconsdata.c
-
-checksum.o string.o: constants.h
diff --git a/arch/arm/lib/bitops.S b/arch/arm/lib/bitops.S
deleted file mode 100644
index 4c1f4b0aa..000000000
--- a/arch/arm/lib/bitops.S
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * linux/arch/arm/lib/bitops.S
- *
- * Copyright (C) 1995, 1996 Russell King
- */
-
-#include <linux/linkage.h>
-#include <asm/assembler.h>
- .text
-
-@ Purpose : Function to set a bit
-@ Prototype: int set_bit(int bit,int *addr)
-
-ENTRY(set_bit)
- and r2, r0, #7
- mov r3, #1
- mov r3, r3, lsl r2
- SAVEIRQS(ip)
- DISABLEIRQS(ip)
- ldrb r2, [r1, r0, lsr #3]
- orr r2, r2, r3
- strb r2, [r1, r0, lsr #3]
- RESTOREIRQS(ip)
- RETINSTR(mov,pc,lr)
-
-ENTRY(test_and_set_bit)
- add r1, r1, r0, lsr #3 @ Get byte offset
- and r3, r0, #7 @ Get bit offset
- mov r0, #1
- SAVEIRQS(ip)
- DISABLEIRQS(ip)
- ldrb r2, [r1]
- tst r2, r0, lsl r3
- orr r2, r2, r0, lsl r3
- moveq r0, #0
- strb r2, [r1]
- RESTOREIRQS(ip)
- RETINSTR(mov,pc,lr)
-
-@ Purpose : Function to clear a bit
-@ Prototype: int clear_bit(int bit,int *addr)
-
-ENTRY(clear_bit)
- and r2, r0, #7
- mov r3, #1
- mov r3, r3, lsl r2
- SAVEIRQS(ip)
- DISABLEIRQS(ip)
- ldrb r2, [r1, r0, lsr #3]
- bic r2, r2, r3
- strb r2, [r1, r0, lsr #3]
- RESTOREIRQS(ip)
- RETINSTR(mov,pc,lr)
-
-ENTRY(test_and_clear_bit)
- add r1, r1, r0, lsr #3 @ Get byte offset
- and r3, r0, #7 @ Get bit offset
- mov r0, #1
- SAVEIRQS(ip)
- DISABLEIRQS(ip)
- ldrb r2, [r1]
- tst r2, r0, lsl r3
- bic r2, r2, r0, lsl r3
- moveq r0, #0
- strb r2, [r1]
- RESTOREIRQS(ip)
- RETINSTR(mov,pc,lr)
-
-/* Purpose : Function to change a bit
- * Prototype: int change_bit(int bit,int *addr)
- */
-ENTRY(change_bit)
- and r2, r0, #7
- mov r3, #1
- mov r3, r3, lsl r2
- SAVEIRQS(ip)
- DISABLEIRQS(ip)
- ldrb r2, [r1, r0, lsr #3]
- eor r2, r2, r3
- strb r2, [r1, r0, lsr #3]
- RESTOREIRQS(ip)
- RETINSTR(mov,pc,lr)
-
-ENTRY(test_and_change_bit)
- add r1, r1, r0, lsr #3
- and r3, r0, #7
- mov r0, #1
- SAVEIRQS(ip)
- DISABLEIRQS(ip)
- ldrb r2, [r1]
- tst r2, r0, lsl r3
- eor r2, r2, r0, lsl r3
- moveq r0, #0
- strb r2, [r1]
- RESTOREIRQS(ip)
- RETINSTR(mov,pc,lr)
-
-@ Purpose : Find a 'zero' bit
-@ Prototype: int find_first_zero_bit(char *addr,int maxbit);
-
-ENTRY(find_first_zero_bit)
- mov r2, #0 @ Initialise bit position
-Lfindzbit1lp: ldrb r3, [r0, r2, lsr #3] @ Check byte, if 0xFF, then all bits set
- teq r3, #0xFF
- bne Lfoundzbit
- add r2, r2, #8
- cmp r2, r1 @ Check to see if we have come to the end
- bcc Lfindzbit1lp
- add r0, r1, #1 @ Make sure that we flag an error
- RETINSTR(mov,pc,lr)
-Lfoundzbit: tst r3, #1 @ Check individual bits
- moveq r0, r2
- RETINSTR(moveq,pc,lr)
- tst r3, #2
- addeq r0, r2, #1
- RETINSTR(moveq,pc,lr)
- tst r3, #4
- addeq r0, r2, #2
- RETINSTR(moveq,pc,lr)
- tst r3, #8
- addeq r0, r2, #3
- RETINSTR(moveq,pc,lr)
- tst r3, #16
- addeq r0, r2, #4
- RETINSTR(moveq,pc,lr)
- tst r3, #32
- addeq r0, r2, #5
- RETINSTR(moveq,pc,lr)
- tst r3, #64
- addeq r0, r2, #6
- RETINSTR(moveq,pc,lr)
- add r0, r2, #7
- RETINSTR(mov,pc,lr)
-
-@ Purpose : Find next 'zero' bit
-@ Prototype: int find_next_zero_bit(char *addr,int maxbit,int offset)
-
-ENTRY(find_next_zero_bit)
- tst r2, #7
- beq Lfindzbit1lp @ If new byte, goto old routine
- ldrb r3, [r0, r2, lsr#3]
- orr r3, r3, #0xFF00 @ Set top bits so we wont get confused
- stmfd sp!, {r4}
- and r4, r2, #7
- mov r3, r3, lsr r4 @ Shift right by no. of bits
- ldmfd sp!, {r4}
- and r3, r3, #0xFF
- teq r3, #0xFF
- orreq r2, r2, #7
- addeq r2, r2, #1
- beq Lfindzbit1lp @ If all bits are set, goto old routine
- b Lfoundzbit
diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S
new file mode 100644
index 000000000..8005fd49a
--- /dev/null
+++ b/arch/arm/lib/changebit.S
@@ -0,0 +1,26 @@
+/*
+ * linux/arch/arm/lib/changebit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+/* Purpose : Function to change a bit
+ * Prototype: int change_bit(int bit,int *addr)
+ */
+ENTRY(change_bit)
+ and r2, r0, #7
+ mov r3, #1
+ mov r3, r3, lsl r2
+ SAVEIRQS(ip)
+ DISABLEIRQS(ip)
+ ldrb r2, [r1, r0, lsr #3]
+ eor r2, r2, r3
+ strb r2, [r1, r0, lsr #3]
+ RESTOREIRQS(ip)
+ RETINSTR(mov,pc,lr)
+
+
diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S
new file mode 100644
index 000000000..d936ab549
--- /dev/null
+++ b/arch/arm/lib/clearbit.S
@@ -0,0 +1,26 @@
+/*
+ * linux/arch/arm/lib/clearbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+@ Purpose : Function to clear a bit
+@ Prototype: int clear_bit(int bit,int *addr)
+
+ENTRY(clear_bit)
+ and r2, r0, #7
+ mov r3, #1
+ mov r3, r3, lsl r2
+ SAVEIRQS(ip)
+ DISABLEIRQS(ip)
+ ldrb r2, [r1, r0, lsr #3]
+ bic r2, r2, r3
+ strb r2, [r1, r0, lsr #3]
+ RESTOREIRQS(ip)
+ RETINSTR(mov,pc,lr)
+
+
diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S
new file mode 100644
index 000000000..16c43268a
--- /dev/null
+++ b/arch/arm/lib/copy_page.S
@@ -0,0 +1,35 @@
+/*
+ * linux/arch/arm/lib/copypage.S
+ *
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * ASM optimised string functions
+ *
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "constants.h"
+
+ .text
+/*
+ * StrongARM optimised copy_page routine
+ * now 1.72bytes/cycle, was 1.60 bytes/cycle
+ * (50MHz bus -> 86MB/s)
+ */
+
+ENTRY(copy_page)
+ stmfd sp!, {r4, lr} @ 2
+ mov r2, #PAGE_SZ/64 @ 1
+1: ldmia r1!, {r3, r4, ip, lr} @ 4
+ subs r2, r2, #1 @ 1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmia r1!, {r3, r4, ip, lr} @ 4+1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmia r1!, {r3, r4, ip, lr} @ 4+1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmia r1!, {r3, r4, ip, lr} @ 4+1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ bne 1b @ 1
+ LOADREGS(fd, sp!, {r4, pc}) @ 3
+
+
diff --git a/arch/arm/lib/csumipv6.S b/arch/arm/lib/csumipv6.S
new file mode 100644
index 000000000..76e7d26d8
--- /dev/null
+++ b/arch/arm/lib/csumipv6.S
@@ -0,0 +1,28 @@
+/*
+ * linux/arch/arm/lib/csumipv6.S
+ *
+ * Copyright (C) 1995-1998 Russell King
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+
+ENTRY(__csum_ipv6_magic)
+ str lr, [sp, #-4]!
+ adds ip, r2, r3
+ ldmia r1, {r1 - r3, lr}
+ adcs ip, ip, r1
+ adcs ip, ip, r2
+ adcs ip, ip, r3
+ adcs ip, ip, lr
+ ldmia r0, {r0 - r3}
+ adcs r0, ip, r0
+ adcs r0, r0, r1
+ adcs r0, r0, r2
+ ldr r2, [sp, #4]
+ adcs r0, r0, r3
+ adcs r0, r0, r2
+ adcs r0, r0, #0
+ LOADREGS(fd, sp!, {pc})
+
diff --git a/arch/arm/lib/csumpartial.S b/arch/arm/lib/csumpartial.S
new file mode 100644
index 000000000..2406dfb38
--- /dev/null
+++ b/arch/arm/lib/csumpartial.S
@@ -0,0 +1,64 @@
+/*
+ * linux/arch/arm/lib/csumpartial.S
+ *
+ * Copyright (C) 1995-1998 Russell King
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+
+/* Function: __u32 csum_partial(const char *src, int len, __u32)
+ * Params : r0 = buffer, r1 = len, r2 = checksum
+ * Returns : r0 = new checksum
+ */
+
+ENTRY(csum_partial)
+ tst r0, #2
+ beq 1f
+ subs r1, r1, #2
+ addmi r1, r1, #2
+ bmi 3f
+ bic r0, r0, #3
+ ldr r3, [r0], #4
+ adds r2, r2, r3, lsr #16
+ adcs r2, r2, #0
+1: adds r2, r2, #0
+ bics ip, r1, #31
+ beq 3f
+ stmfd sp!, {r4 - r6}
+2: ldmia r0!, {r3 - r6}
+ adcs r2, r2, r3
+ adcs r2, r2, r4
+ adcs r2, r2, r5
+ adcs r2, r2, r6
+ ldmia r0!, {r3 - r6}
+ adcs r2, r2, r3
+ adcs r2, r2, r4
+ adcs r2, r2, r5
+ adcs r2, r2, r6
+ sub ip, ip, #32
+ teq ip, #0
+ bne 2b
+ adcs r2, r2, #0
+ ldmfd sp!, {r4 - r6}
+3: ands ip, r1, #0x1c
+ beq 5f
+4: ldr r3, [r0], #4
+ sub ip, ip, #4
+ adcs r2, r2, r3
+ teq ip, #0
+ bne 4b
+ adcs r2, r2, #0
+5: ands ip, r1, #3
+ moveq r0, r2
+ RETINSTR(moveq,pc,lr)
+ mov ip, ip, lsl #3
+ ldr r3, [r0]
+ rsb ip, ip, #32
+ mov r3, r3, lsl ip
+ adds r2, r2, r3, lsr ip
+ adc r0, r2, #0
+ RETINSTR(mov,pc,lr)
+
+
diff --git a/arch/arm/lib/csumpartialcopy.S b/arch/arm/lib/csumpartialcopy.S
new file mode 100644
index 000000000..7289619da
--- /dev/null
+++ b/arch/arm/lib/csumpartialcopy.S
@@ -0,0 +1,257 @@
+/*
+ * linux/arch/arm/lib/csumpartialcopy.S
+ *
+ * Copyright (C) 1995-1998 Russell King
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+ .text
+
+/* Function: __u32 csum_partial_copy_nocheck(const char *src, char *dst, int len, __u32 sum)
+ * Params : r0 = src, r1 = dst, r2 = len, r3 = checksum
+ * Returns : r0 = new checksum
+ */
+ENTRY(csum_partial_copy_nocheck)
+ mov ip, sp
+ stmfd sp!, {r4 - r8, fp, ip, lr, pc}
+ sub fp, ip, #4
+ cmp r2, #4
+ blt Ltoo_small
+ tst r1, #2 @ Test destination alignment
+ beq Ldst_aligned
+ ldrb ip, [r0], #1
+ ldrb r8, [r0], #1
+ subs r2, r2, #2 @ We do not know if SRC is aligned...
+ orr ip, ip, r8, lsl #8
+ adds r3, r3, ip
+ adcs r3, r3, #0
+ strb ip, [r1], #1
+ mov ip, ip, lsr #8
+ strb ip, [r1], #1 @ Destination now aligned
+Ldst_aligned: tst r0, #3
+ bne Lsrc_not_aligned
+ adds r3, r3, #0
+ bics ip, r2, #15 @ Routine for src & dst aligned
+ beq 3f
+1: ldmia r0!, {r4, r5, r6, r7}
+ stmia r1!, {r4, r5, r6, r7}
+ adcs r3, r3, r4
+ adcs r3, r3, r5
+ adcs r3, r3, r6
+ adcs r3, r3, r7
+ sub ip, ip, #16
+ teq ip, #0
+ bne 1b
+3: ands ip, r2, #12
+ beq 5f
+ tst ip, #8
+ beq 4f
+ ldmia r0!, {r4, r5}
+ stmia r1!, {r4, r5}
+ adcs r3, r3, r4
+ adcs r3, r3, r5
+ tst ip, #4
+ beq 5f
+4: ldr r4, [r0], #4
+ str r4, [r1], #4
+ adcs r3, r3, r4
+5: ands r2, r2, #3
+ adceq r0, r3, #0
+ LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
+ ldr r4, [r0], #4
+ tst r2, #2
+ beq Lexit_r4
+ adcs r3, r3, r4, lsl #16
+ strb r4, [r1], #1
+ mov r4, r4, lsr #8
+ strb r4, [r1], #1
+ mov r4, r4, lsr #8
+ b Lexit_r4
+
+Ltoo_small: teq r2, #0
+ LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
+ cmp r2, #2
+ blt Ltoo_small1
+ ldrb ip, [r0], #1
+ ldrb r8, [r0], #1
+ orr ip, ip, r8, lsl #8
+ adds r3, r3, ip
+ strb ip, [r1], #1
+ strb r8, [r1], #1
+ tst r2, #1
+Ltoo_small1: ldrneb r4, [r0], #1
+Lexit_r4: tst r2, #1
+ strneb r4, [r1], #1
+ andne r4, r4, #255
+ adcnes r3, r3, r4
+ adcs r0, r3, #0
+ LOADREGS(ea,fp,{r4 - r8, fp, sp, pc})
+
+Lsrc_not_aligned:
+ cmp r2, #4
+ blt Ltoo_small
+ and ip, r0, #3
+ bic r0, r0, #3
+ ldr r4, [r0], #4
+ cmp ip, #2
+ beq Lsrc2_aligned
+ bhi Lsrc3_aligned
+ mov r4, r4, lsr #8
+ adds r3, r3, #0
+ bics ip, r2, #15
+ beq 2f
+1: ldmia r0!, {r5, r6, r7, r8}
+ orr r4, r4, r5, lsl #24
+ mov r5, r5, lsr #8
+ orr r5, r5, r6, lsl #24
+ mov r6, r6, lsr #8
+ orr r6, r6, r7, lsl #24
+ mov r7, r7, lsr #8
+ orr r7, r7, r8, lsl #24
+ stmia r1!, {r4, r5, r6, r7}
+ adcs r3, r3, r4
+ adcs r3, r3, r5
+ adcs r3, r3, r6
+ adcs r3, r3, r7
+ mov r4, r8, lsr #8
+ sub ip, ip, #16
+ teq ip, #0
+ bne 1b
+2: ands ip, r2, #12
+ beq 4f
+ tst ip, #8
+ beq 3f
+ ldmia r0!, {r5, r6}
+ orr r4, r4, r5, lsl #24
+ mov r5, r5, lsr #8
+ orr r5, r5, r6, lsl #24
+ stmia r1!, {r4, r5}
+ adcs r3, r3, r4
+ adcs r3, r3, r5
+ mov r4, r6, lsr #8
+ tst ip, #4
+ beq 4f
+3: ldr r5, [r0], #4
+ orr r4, r4, r5, lsl #24
+ str r4, [r1], #4
+ adcs r3, r3, r4
+ mov r4, r5, lsr #8
+4: ands r2, r2, #3
+ adceq r0, r3, #0
+ LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
+ tst r2, #2
+ beq Lexit_r4
+ adcs r3, r3, r4, lsl #16
+ strb r4, [r1], #1
+ mov r4, r4, lsr #8
+ strb r4, [r1], #1
+ mov r4, r4, lsr #8
+ b Lexit_r4
+
+Lsrc2_aligned: mov r4, r4, lsr #16
+ adds r3, r3, #0
+ bics ip, r2, #15
+ beq 2f
+1: ldmia r0!, {r5, r6, r7, r8}
+ orr r4, r4, r5, lsl #16
+ mov r5, r5, lsr #16
+ orr r5, r5, r6, lsl #16
+ mov r6, r6, lsr #16
+ orr r6, r6, r7, lsl #16
+ mov r7, r7, lsr #16
+ orr r7, r7, r8, lsl #16
+ stmia r1!, {r4, r5, r6, r7}
+ adcs r3, r3, r4
+ adcs r3, r3, r5
+ adcs r3, r3, r6
+ adcs r3, r3, r7
+ mov r4, r8, lsr #16
+ sub ip, ip, #16
+ teq ip, #0
+ bne 1b
+2: ands ip, r2, #12
+ beq 4f
+ tst ip, #8
+ beq 3f
+ ldmia r0!, {r5, r6}
+ orr r4, r4, r5, lsl #16
+ mov r5, r5, lsr #16
+ orr r5, r5, r6, lsl #16
+ stmia r1!, {r4, r5}
+ adcs r3, r3, r4
+ adcs r3, r3, r5
+ mov r4, r6, lsr #16
+ tst ip, #4
+ beq 4f
+3: ldr r5, [r0], #4
+ orr r4, r4, r5, lsl #16
+ str r4, [r1], #4
+ adcs r3, r3, r4
+ mov r4, r5, lsr #16
+4: ands r2, r2, #3
+ adceq r0, r3, #0
+ LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
+ tst r2, #2
+ beq Lexit_r4
+ adcs r3, r3, r4, lsl #16
+ strb r4, [r1], #1
+ mov r4, r4, lsr #8
+ strb r4, [r1], #1
+ ldrb r4, [r0], #1
+ b Lexit_r4
+
+Lsrc3_aligned: mov r4, r4, lsr #24
+ adds r3, r3, #0
+ bics ip, r2, #15
+ beq 2f
+1: ldmia r0!, {r5, r6, r7, r8}
+ orr r4, r4, r5, lsl #8
+ mov r5, r5, lsr #24
+ orr r5, r5, r6, lsl #8
+ mov r6, r6, lsr #24
+ orr r6, r6, r7, lsl #8
+ mov r7, r7, lsr #24
+ orr r7, r7, r8, lsl #8
+ stmia r1!, {r4, r5, r6, r7}
+ adcs r3, r3, r4
+ adcs r3, r3, r5
+ adcs r3, r3, r6
+ adcs r3, r3, r7
+ mov r4, r8, lsr #24
+ sub ip, ip, #16
+ teq ip, #0
+ bne 1b
+2: ands ip, r2, #12
+ beq 4f
+ tst ip, #8
+ beq 3f
+ ldmia r0!, {r5, r6}
+ orr r4, r4, r5, lsl #8
+ mov r5, r5, lsr #24
+ orr r5, r5, r6, lsl #8
+ stmia r1!, {r4, r5}
+ adcs r3, r3, r4
+ adcs r3, r3, r5
+ mov r4, r6, lsr #24
+ tst ip, #4
+ beq 4f
+3: ldr r5, [r0], #4
+ orr r4, r4, r5, lsl #8
+ str r4, [r1], #4
+ adcs r3, r3, r4
+ mov r4, r5, lsr #24
+4: ands r2, r2, #3
+ adceq r0, r3, #0
+ LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
+ tst r2, #2
+ beq Lexit_r4
+ adcs r3, r3, r4, lsl #16
+ strb r4, [r1], #1
+ ldr r4, [r0], #4
+ strb r4, [r1], #1
+ adcs r3, r3, r4, lsl #24
+ mov r4, r4, lsr #8
+ b Lexit_r4
+
+
diff --git a/arch/arm/lib/checksum.S b/arch/arm/lib/csumpartialcopyuser.S
index ae78b657a..f698c0d26 100644
--- a/arch/arm/lib/checksum.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -1,7 +1,7 @@
/*
- * linux/arch/arm/lib/checksum.S
+ * linux/arch/arm/lib/csumpartialcopyuser.S
*
- * Copyright (C) 1995, 1996, 1997, 1998 Russell King
+ * Copyright (C) 1995-1998 Russell King
*/
#include <linux/config.h>
#include <linux/linkage.h>
@@ -11,59 +11,6 @@
.text
-/* Function: __u32 csum_partial(const char *src, int len, __u32)
- * Params : r0 = buffer, r1 = len, r2 = checksum
- * Returns : r0 = new checksum
- */
-
-ENTRY(csum_partial)
- tst r0, #2
- beq 1f
- subs r1, r1, #2
- addmi r1, r1, #2
- bmi 3f
- bic r0, r0, #3
- ldr r3, [r0], #4
- adds r2, r2, r3, lsr #16
- adcs r2, r2, #0
-1: adds r2, r2, #0
- bics ip, r1, #31
- beq 3f
- stmfd sp!, {r4 - r6}
-2: ldmia r0!, {r3 - r6}
- adcs r2, r2, r3
- adcs r2, r2, r4
- adcs r2, r2, r5
- adcs r2, r2, r6
- ldmia r0!, {r3 - r6}
- adcs r2, r2, r3
- adcs r2, r2, r4
- adcs r2, r2, r5
- adcs r2, r2, r6
- sub ip, ip, #32
- teq ip, #0
- bne 2b
- adcs r2, r2, #0
- ldmfd sp!, {r4 - r6}
-3: ands ip, r1, #0x1c
- beq 5f
-4: ldr r3, [r0], #4
- adcs r2, r2, r3
- sub ip, ip, #4
- teq ip, #0
- bne 4b
- adcs r2, r2, #0
-5: ands ip, r1, #3
- moveq r0, r2
- RETINSTR(moveq,pc,lr)
- mov ip, ip, lsl #3
- rsb ip, ip, #32
- ldr r3, [r0]
- mov r3, r3, lsl ip
- adds r2, r2, r3, lsr ip
- adc r0, r2, #0
- RETINSTR(mov,pc,lr)
-
/* Function: __u32 csum_partial_copy_from_user (const char *src, char *dst, int len, __u32 sum, int *err_ptr)
* Params : r0 = src, r1 = dst, r2 = len, r3 = sum, [sp, #0] = &err
* Returns : r0 = checksum, [[sp, #0], #0] = 0 or -EFAULT
@@ -209,8 +156,8 @@ ENTRY(csum_partial_copy_from_user)
blt .too_small_user
tst r1, #2 @ Test destination alignment
beq .dst_aligned_user
- subs r2, r2, #2 @ We do not know if SRC is aligned...
load2b ip, r8
+ subs r2, r2, #2 @ We do not know if SRC is aligned...
orr ip, ip, r8, lsl #8
adds r3, r3, ip
adcs r3, r3, #0
@@ -393,6 +340,9 @@ ENTRY(csum_partial_copy_from_user)
strb r4, [r1], #1
mov r4, r4, lsr #8
strb r4, [r1], #1
+ tst r2, #1
+ adceq r0, r3, #0
+ load_regs eqea
load1b r4
b .exit
@@ -467,268 +417,3 @@ ENTRY(csum_partial_copy_from_user)
#if defined(CONFIG_CPU_32)
.previous
#endif
-
-/* Function: __u32 csum_partial_copy (const char *src, char *dst, int len, __u32 sum)
- * Params : r0 = src, r1 = dst, r2 = len, r3 = checksum
- * Returns : r0 = new checksum
- */
-ENTRY(csum_partial_copy_nocheck)
-ENTRY(csum_partial_copy)
- mov ip, sp
- stmfd sp!, {r4 - r8, fp, ip, lr, pc}
- sub fp, ip, #4
- cmp r2, #4
- blt Ltoo_small
- tst r1, #2 @ Test destination alignment
- beq Ldst_aligned
- subs r2, r2, #2 @ We do not know if SRC is aligned...
- ldrb ip, [r0], #1
- ldrb r8, [r0], #1
- orr ip, ip, r8, lsl #8
- adds r3, r3, ip
- adcs r3, r3, #0
- strb ip, [r1], #1
- mov ip, ip, lsr #8
- strb ip, [r1], #1 @ Destination now aligned
-Ldst_aligned: tst r0, #3
- bne Lsrc_not_aligned
- adds r3, r3, #0
- bics ip, r2, #15 @ Routine for src & dst aligned
- beq 3f
-1: ldmia r0!, {r4, r5, r6, r7}
- stmia r1!, {r4, r5, r6, r7}
- adcs r3, r3, r4
- adcs r3, r3, r5
- adcs r3, r3, r6
- adcs r3, r3, r7
- sub ip, ip, #16
- teq ip, #0
- bne 1b
-3: ands ip, r2, #12
- beq 5f
- tst ip, #8
- beq 4f
- ldmia r0!, {r4, r5}
- stmia r1!, {r4, r5}
- adcs r3, r3, r4
- adcs r3, r3, r5
- tst ip, #4
- beq 5f
-4: ldr r4, [r0], #4
- str r4, [r1], #4
- adcs r3, r3, r4
-5: ands r2, r2, #3
- adceq r0, r3, #0
- LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
- ldr r4, [r0], #4
- tst r2, #2
- beq Lexit_r4
- adcs r3, r3, r4, lsl #16
- strb r4, [r1], #1
- mov r4, r4, lsr #8
- strb r4, [r1], #1
- mov r4, r4, lsr #8
- b Lexit_r4
-
-Ltoo_small: teq r2, #0
- LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
- cmp r2, #2
- blt Ltoo_small1
- ldrb ip, [r0], #1
- ldrb r8, [r0], #1
- orr ip, ip, r8, lsl #8
- adds r3, r3, ip
- strb ip, [r1], #1
- strb r8, [r1], #1
- tst r2, #1
-Ltoo_small1: ldrneb r4, [r0], #1
-Lexit_r4: tst r2, #1
- strneb r4, [r1], #1
- andne r4, r4, #255
- adcnes r3, r3, r4
- adcs r0, r3, #0
- LOADREGS(ea,fp,{r4 - r8, fp, sp, pc})
-
-Lsrc_not_aligned:
- cmp r2, #4
- blt Ltoo_small
- and ip, r0, #3
- bic r0, r0, #3
- ldr r4, [r0], #4
- cmp ip, #2
- beq Lsrc2_aligned
- bhi Lsrc3_aligned
- mov r4, r4, lsr #8
- adds r3, r3, #0
- bics ip, r2, #15
- beq 2f
-1: ldmia r0!, {r5, r6, r7, r8}
- orr r4, r4, r5, lsl #24
- mov r5, r5, lsr #8
- orr r5, r5, r6, lsl #24
- mov r6, r6, lsr #8
- orr r6, r6, r7, lsl #24
- mov r7, r7, lsr #8
- orr r7, r7, r8, lsl #24
- stmia r1!, {r4, r5, r6, r7}
- adcs r3, r3, r4
- adcs r3, r3, r5
- adcs r3, r3, r6
- adcs r3, r3, r7
- mov r4, r8, lsr #8
- sub ip, ip, #16
- teq ip, #0
- bne 1b
-2: ands ip, r2, #12
- beq 4f
- tst ip, #8
- beq 3f
- ldmia r0!, {r5, r6}
- orr r4, r4, r5, lsl #24
- mov r5, r5, lsr #8
- orr r5, r5, r6, lsl #24
- stmia r1!, {r4, r5}
- adcs r3, r3, r4
- adcs r3, r3, r5
- mov r4, r6, lsr #8
- tst ip, #4
- beq 4f
-3: ldr r5, [r0], #4
- orr r4, r4, r5, lsl #24
- str r4, [r1], #4
- adcs r3, r3, r4
- mov r4, r5, lsr #8
-4: ands r2, r2, #3
- adceq r0, r3, #0
- LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
- tst r2, #2
- beq Lexit_r4
- adcs r3, r3, r4, lsl #16
- strb r4, [r1], #1
- mov r4, r4, lsr #8
- strb r4, [r1], #1
- mov r4, r4, lsr #8
- b Lexit_r4
-
-Lsrc2_aligned: mov r4, r4, lsr #16
- adds r3, r3, #0
- bics ip, r2, #15
- beq 2f
-1: ldmia r0!, {r5, r6, r7, r8}
- orr r4, r4, r5, lsl #16
- mov r5, r5, lsr #16
- orr r5, r5, r6, lsl #16
- mov r6, r6, lsr #16
- orr r6, r6, r7, lsl #16
- mov r7, r7, lsr #16
- orr r7, r7, r8, lsl #16
- stmia r1!, {r4, r5, r6, r7}
- adcs r3, r3, r4
- adcs r3, r3, r5
- adcs r3, r3, r6
- adcs r3, r3, r7
- mov r4, r8, lsr #16
- sub ip, ip, #16
- teq ip, #0
- bne 1b
-2: ands ip, r2, #12
- beq 4f
- tst ip, #8
- beq 3f
- ldmia r0!, {r5, r6}
- orr r4, r4, r5, lsl #16
- mov r5, r5, lsr #16
- orr r5, r5, r6, lsl #16
- stmia r1!, {r4, r5}
- adcs r3, r3, r4
- adcs r3, r3, r5
- mov r4, r6, lsr #16
- tst ip, #4
- beq 4f
-3: ldr r5, [r0], #4
- orr r4, r4, r5, lsl #16
- str r4, [r1], #4
- adcs r3, r3, r4
- mov r4, r5, lsr #16
-4: ands r2, r2, #3
- adceq r0, r3, #0
- LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
- tst r2, #2
- beq Lexit_r4
- adcs r3, r3, r4, lsl #16
- strb r4, [r1], #1
- mov r4, r4, lsr #8
- strb r4, [r1], #1
- ldrb r4, [r0], #1
- b Lexit_r4
-
-Lsrc3_aligned: mov r4, r4, lsr #24
- adds r3, r3, #0
- bics ip, r2, #15
- beq 2f
-1: ldmia r0!, {r5, r6, r7, r8}
- orr r4, r4, r5, lsl #8
- mov r5, r5, lsr #24
- orr r5, r5, r6, lsl #8
- mov r6, r6, lsr #24
- orr r6, r6, r7, lsl #8
- mov r7, r7, lsr #24
- orr r7, r7, r8, lsl #8
- stmia r1!, {r4, r5, r6, r7}
- adcs r3, r3, r4
- adcs r3, r3, r5
- adcs r3, r3, r6
- adcs r3, r3, r7
- mov r4, r8, lsr #24
- sub ip, ip, #16
- teq ip, #0
- bne 1b
-2: ands ip, r2, #12
- beq 4f
- tst ip, #8
- beq 3f
- ldmia r0!, {r5, r6}
- orr r4, r4, r5, lsl #8
- mov r5, r5, lsr #24
- orr r5, r5, r6, lsl #8
- stmia r1!, {r4, r5}
- adcs r3, r3, r4
- adcs r3, r3, r5
- mov r4, r6, lsr #24
- tst ip, #4
- beq 4f
-3: ldr r5, [r0], #4
- orr r4, r4, r5, lsl #8
- str r4, [r1], #4
- adcs r3, r3, r4
- mov r4, r5, lsr #24
-4: ands r2, r2, #3
- adceq r0, r3, #0
- LOADREGS(eqea,fp,{r4 - r8, fp, sp, pc})
- tst r2, #2
- beq Lexit_r4
- adcs r3, r3, r4, lsl #16
- strb r4, [r1], #1
- ldr r4, [r0], #4
- strb r4, [r1], #1
- adcs r3, r3, r4, lsl #24
- mov r4, r4, lsr #8
- b Lexit_r4
-
-ENTRY(__csum_ipv6_magic)
- stmfd sp!, {lr}
- adds ip, r2, r3
- ldmia r1, {r1 - r3, lr}
- adcs ip, ip, r1
- adcs ip, ip, r2
- adcs ip, ip, r3
- adcs ip, ip, lr
- ldmia r0, {r0 - r3}
- adcs r0, ip, r0
- adcs r0, r0, r1
- adcs r0, r0, r2
- adcs r0, r0, r3
- ldr r3, [sp, #4]
- adcs r0, r0, r3
- adcs r0, r0, #0
- LOADREGS(fd, sp!, {pc})
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
new file mode 100644
index 000000000..e1651904f
--- /dev/null
+++ b/arch/arm/lib/findbit.S
@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/lib/bitops.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+@ Purpose : Find a 'zero' bit
+@ Prototype: int find_first_zero_bit(char *addr,int maxbit);
+
+ENTRY(find_first_zero_bit)
+ mov r2, #0 @ Initialise bit position
+Lfindzbit1lp: ldrb r3, [r0, r2, lsr #3] @ Check byte, if 0xFF, then all bits set
+ teq r3, #0xFF
+ bne Lfoundzbit
+ add r2, r2, #8
+ cmp r2, r1 @ Check to see if we have come to the end
+ bcc Lfindzbit1lp
+ add r0, r1, #1 @ Make sure that we flag an error
+ RETINSTR(mov,pc,lr)
+Lfoundzbit: tst r3, #1 @ Check individual bits
+ moveq r0, r2
+ RETINSTR(moveq,pc,lr)
+ tst r3, #2
+ addeq r0, r2, #1
+ RETINSTR(moveq,pc,lr)
+ tst r3, #4
+ addeq r0, r2, #2
+ RETINSTR(moveq,pc,lr)
+ tst r3, #8
+ addeq r0, r2, #3
+ RETINSTR(moveq,pc,lr)
+ tst r3, #16
+ addeq r0, r2, #4
+ RETINSTR(moveq,pc,lr)
+ tst r3, #32
+ addeq r0, r2, #5
+ RETINSTR(moveq,pc,lr)
+ tst r3, #64
+ addeq r0, r2, #6
+ RETINSTR(moveq,pc,lr)
+ add r0, r2, #7
+ RETINSTR(mov,pc,lr)
+
+@ Purpose : Find next 'zero' bit
+@ Prototype: int find_next_zero_bit(char *addr,int maxbit,int offset)
+
+ENTRY(find_next_zero_bit)
+ tst r2, #7
+ beq Lfindzbit1lp @ If new byte, goto old routine
+ ldrb r3, [r0, r2, lsr#3]
+ orr r3, r3, #0xFF00 @ Set top bits so we wont get confused
+ stmfd sp!, {r4}
+ and r4, r2, #7
+ mov r3, r3, lsr r4 @ Shift right by no. of bits
+ ldmfd sp!, {r4}
+ and r3, r3, #0xFF
+ teq r3, #0xFF
+ orreq r2, r2, #7
+ addeq r2, r2, #1
+ beq Lfindzbit1lp @ If all bits are set, goto old routine
+ b Lfoundzbit
diff --git a/arch/arm/lib/getconsdata.c b/arch/arm/lib/getconsdata.c
index 5b46baad0..aaa7a7ad2 100644
--- a/arch/arm/lib/getconsdata.c
+++ b/arch/arm/lib/getconsdata.c
@@ -10,6 +10,16 @@
#include <asm/pgtable.h>
#include <asm/uaccess.h>
+/*
+ * Make sure that the compiler and target are compatible
+ */
+#if (defined(__APCS_32__) && defined(CONFIG_CPU_26))
+#error Your compiler targets APCS-32 but this kernel requires APCS-26.
+#endif
+#if (defined(__APCS_26__) && defined(CONFIG_CPU_32))
+#error Your compiler targets APCS-26 but this kernel requires APCS-32.
+#endif
+
#undef PAGE_READONLY
#define OFF_TSK(n) (unsigned long)&(((struct task_struct *)0)->n)
diff --git a/arch/arm/lib/io-footbridge.S b/arch/arm/lib/io-footbridge.S
index 0734c6042..98f751258 100644
--- a/arch/arm/lib/io-footbridge.S
+++ b/arch/arm/lib/io-footbridge.S
@@ -6,7 +6,9 @@
.macro ioaddr, rd,rn
add \rd, \rn, #pcio_high
+ .if pcio_low
add \rd, \rd, #pcio_low
+ .endif
.endm
ENTRY(insl)
diff --git a/arch/arm/lib/memchr.S b/arch/arm/lib/memchr.S
new file mode 100644
index 000000000..d52abe57f
--- /dev/null
+++ b/arch/arm/lib/memchr.S
@@ -0,0 +1,24 @@
+/*
+ * linux/arch/arm/lib/memchr.S
+ *
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * ASM optimised string functions
+ *
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "constants.h"
+
+ .text
+ENTRY(memchr)
+ str lr, [sp, #-4]!
+1: ldrb r3, [r0], #1
+ teq r3, r1
+ beq 2f
+ subs r2, r2, #1
+ bpl 1b
+2: movne r0, #0
+ subeq r0, r0, #1
+ LOADREGS(fd, sp!, {pc})
+
diff --git a/arch/arm/lib/string.S b/arch/arm/lib/memcpy.S
index ff809fd51..ae5307d4b 100644
--- a/arch/arm/lib/string.S
+++ b/arch/arm/lib/memcpy.S
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/lib/string.S
+ * linux/arch/arm/lib/memcpy.S
*
* Copyright (C) 1995-1999 Russell King
*
@@ -12,207 +12,6 @@
.text
-/*
- * Prototype: void memzero(void *d, size_t n)
- */
-1: @ 4 <= r1
- cmp ip, #2 @ 1
- strltb r2, [r0], #1 @ 1
- strleb r2, [r0], #1 @ 1
- strb r2, [r0], #1 @ 1
- rsb ip, ip, #4 @ 1
- sub r1, r1, ip @ 1
- cmp r1, #3 @ 1
- bgt 2f @ 1 @ +8
- b 4f @ 1 @ +9
-
- .align 5
-
-ENTRY(__memzero)
- mov r2, #0 @ 1
- cmp r1, #4 @ 1
- blt 4f @ 1 @ = 3
-
- @ r1 >= 4
-
- ands ip, r0, #3 @ 1
- bne 1b @ 1 @ = 5
-
-2: @ r1 >= 4 && (r0 & 3) = 0 @ = 5 or 11
-
- str lr, [sp, #-4]! @ 1
- mov r3, #0 @ 1
- mov ip, #0 @ 1
- mov lr, #0 @ 1
-
- @ 4 <= r1 <= 32 @ = 9 or 15
-
-3: subs r1, r1, #32 @ 1
- stmgeia r0!, {r2, r3, ip, lr} @ 4
- stmgeia r0!, {r2, r3, ip, lr} @ 4
- bgt 3b @ 1
- LOADREGS(eqfd, sp!, {pc}) @ 1/2
-
- @ -28 <= r1 <= -1
-
- cmp r1, #-16 @ 1
- stmgeia r0!, {r2, r3, ip, lr} @ 4
- ldr lr, [sp], #4 @ 1
- addlts r1, r1, #16 @ 1
- RETINSTR(moveq,pc,lr) @ 1
-
- @ -12 <= r1 <= -1
-
- cmp r1, #-8 @ 1
- stmgeia r0!, {r2, r3} @ 2
- addlts r1, r1, #8 @ 1
- RETINSTR(moveq,pc,lr) @ 1
-
- @ -4 <= r1 <= -1
-
- cmp r1, #-4 @ 1
- strge r2, [r0], #4 @ 1
- adds r1, r1, #4 @ 1
- RETINSTR(moveq,pc,lr) @ 1
-
-4: @ 1 <= r1 <= 3
- cmp r1, #2 @ 1
- strgtb r2, [r0], #1 @ 1
- strgeb r2, [r0], #1 @ 1
- strb r2, [r0], #1 @ 1
- RETINSTR(mov,pc,lr) @ 1
-
-/*
- * StrongARM optimised copy_page routine
- * now 1.72bytes/cycle, was 1.60 bytes/cycle
- * (50MHz bus -> 86MB/s)
- */
-
-ENTRY(copy_page)
- stmfd sp!, {r4, lr} @ 2
- mov r2, #PAGE_SZ/64 @ 1
-1: ldmia r1!, {r3, r4, ip, lr} @ 4
- subs r2, r2, #1 @ 1
- stmia r0!, {r3, r4, ip, lr} @ 4
- ldmia r1!, {r3, r4, ip, lr} @ 4+1
- stmia r0!, {r3, r4, ip, lr} @ 4
- ldmia r1!, {r3, r4, ip, lr} @ 4+1
- stmia r0!, {r3, r4, ip, lr} @ 4
- ldmia r1!, {r3, r4, ip, lr} @ 4+1
- stmia r0!, {r3, r4, ip, lr} @ 4
- bne 1b @ 1
- LOADREGS(fd, sp!, {r4, pc}) @ 3
-
- .align 5
-ENTRY(memset) /* needed for some versions of gcc */
-ENTRY(__memset)
- mov r3, r0
- cmp r2, #16
- blt 6f
- ands ip, r3, #3
- beq 1f
- cmp ip, #2
- strltb r1, [r3], #1 @ Align destination
- strleb r1, [r3], #1
- strb r1, [r3], #1
- rsb ip, ip, #4
- sub r2, r2, ip
-1: orr r1, r1, r1, lsl #8
- orr r1, r1, r1, lsl #16
- cmp r2, #256
- blt 4f
- stmfd sp!, {r4, r5, lr}
- mov r4, r1
- mov r5, r1
- mov lr, r1
- mov ip, r2, lsr #6
- sub r2, r2, ip, lsl #6
-2: stmia r3!, {r1, r4, r5, lr} @ 64 bytes at a time.
- stmia r3!, {r1, r4, r5, lr}
- stmia r3!, {r1, r4, r5, lr}
- stmia r3!, {r1, r4, r5, lr}
- subs ip, ip, #1
- bne 2b
- teq r2, #0
- LOADREGS(eqfd, sp!, {r4, r5, pc}) @ Now <64 bytes to go.
- tst r2, #32
- stmneia r3!, {r1, r4, r5, lr}
- stmneia r3!, {r1, r4, r5, lr}
- tst r2, #16
- stmneia r3!, {r1, r4, r5, lr}
- ldmia sp!, {r4, r5}
-3: tst r2, #8
- stmneia r3!, {r1, lr}
- tst r2, #4
- strne r1, [r3], #4
- tst r2, #2
- strneb r1, [r3], #1
- strneb r1, [r3], #1
- tst r2, #1
- strneb r1, [r3], #1
- LOADREGS(fd, sp!, {pc})
-
-4: movs ip, r2, lsr #3
- beq 3b
- sub r2, r2, ip, lsl #3
- stmfd sp!, {lr}
- mov lr, r1
- subs ip, ip, #4
-5: stmgeia r3!, {r1, lr}
- stmgeia r3!, {r1, lr}
- stmgeia r3!, {r1, lr}
- stmgeia r3!, {r1, lr}
- subges ip, ip, #4
- bge 5b
- tst ip, #2
- stmneia r3!, {r1, lr}
- stmneia r3!, {r1, lr}
- tst ip, #1
- stmneia r3!, {r1, lr}
- teq r2, #0
- LOADREGS(eqfd, sp!, {pc})
- b 3b
-
-6: subs r2, r2, #1
- strgeb r1, [r3], #1
- bgt 6b
- RETINSTR(mov, pc, lr)
-
-ENTRY(strrchr)
- stmfd sp!, {lr}
- mov r3, #0
-1: ldrb r2, [r0], #1
- teq r2, r1
- moveq r3, r0
- teq r2, #0
- bne 1b
- mov r0, r3
- LOADREGS(fd, sp!, {pc})
-
-ENTRY(strchr)
- stmfd sp!,{lr}
- mov r3, #0
-1: ldrb r2, [r0], #1
- teq r2, r1
- teqne r2, #0
- bne 1b
- teq r2, #0
- moveq r0, #0
- subne r0, r0, #1
- LOADREGS(fd, sp!, {pc})
-
-ENTRY(memchr)
- stmfd sp!, {lr}
-1: ldrb r3, [r0], #1
- teq r3, r1
- beq 2f
- subs r2, r2, #1
- bpl 1b
-2: movne r0, #0
- subeq r0, r0, #1
- LOADREGS(fd, sp!, {pc})
-
-
#define ENTER \
mov ip,sp ;\
stmfd sp!,{r4-r9,fp,ip,lr,pc} ;\
@@ -261,30 +60,30 @@ ENTRY(memmove)
blt 6f
subs r2, r2, #4
ldrlt r3, [r1], #4
+ ldmgeia r1!, {r4, r5}
strlt r3, [r0], #4
- ldmgeia r1!, {r3, r4}
- stmgeia r0!, {r3, r4}
+ stmgeia r0!, {r4, r5}
subge r2, r2, #4
6: adds r2, r2, #4
EXITEQ
cmp r2, #2
ldrb r3, [r1], #1
+ ldrgeb r4, [r1], #1
+ ldrgtb r5, [r1], #1
strb r3, [r0], #1
- ldrgeb r3, [r1], #1
- strgeb r3, [r0], #1
- ldrgtb r3, [r1], #1
- strgtb r3, [r0], #1
+ strgeb r4, [r0], #1
+ strgtb r5, [r0], #1
EXIT
7: rsb ip, ip, #4
cmp ip, #2
ldrb r3, [r1], #1
+ ldrgeb r4, [r1], #1
+ ldrgtb r5, [r1], #1
strb r3, [r0], #1
- ldrgeb r3, [r1], #1
- strgeb r3, [r0], #1
- ldrgtb r3, [r1], #1
- strgtb r3, [r0], #1
+ strgeb r4, [r0], #1
+ strgtb r5, [r0], #1
subs r2, r2, ip
blt 6b
ands ip, r1, #3
@@ -314,9 +113,9 @@ ENTRY(memmove)
blt 100f
10: mov r3, r7, lsr #8
ldr r7, [r1], #4
+ subs r2, r2, #4
orr r3, r3, r7, lsl #24
str r3, [r0], #4
- subs r2, r2, #4
bge 10b
100: sub r1, r1, #3
b 6b
@@ -340,9 +139,9 @@ ENTRY(memmove)
blt 14f
13: mov r3, r7, lsr #16
ldr r7, [r1], #4
+ subs r2, r2, #4
orr r3, r3, r7, lsl #16
str r3, [r0], #4
- subs r2, r2, #4
bge 13b
14: sub r1, r1, #2
b 6b
@@ -366,9 +165,9 @@ ENTRY(memmove)
blt 18f
17: mov r3, r7, lsr #24
ldr r7, [r1], #4
+ subs r2, r2, #4
orr r3, r3, r7, lsl#8
str r3, [r0], #4
- subs r2, r2, #4
bge 17b
18: sub r1, r1, #1
b 6b
@@ -403,29 +202,29 @@ ENTRY(memmove)
blt 24f
subs r2, r2, #4
ldrlt r3, [r1, #-4]!
+ ldmgedb r1!, {r4, r5}
strlt r3, [r0, #-4]!
- ldmgedb r1!, {r3, r4}
- stmgedb r0!, {r3, r4}
+ stmgedb r0!, {r4, r5}
subge r2, r2, #4
24: adds r2, r2, #4
EXITEQ
cmp r2, #2
ldrb r3, [r1, #-1]!
+ ldrgeb r4, [r1, #-1]!
+ ldrgtb r5, [r1, #-1]!
strb r3, [r0, #-1]!
- ldrgeb r3, [r1, #-1]!
- strgeb r3, [r0, #-1]!
- ldrgtb r3, [r1, #-1]!
- strgtb r3, [r0, #-1]!
+ strgeb r4, [r0, #-1]!
+ strgtb r5, [r0, #-1]!
EXIT
25: cmp ip, #2
ldrb r3, [r1, #-1]!
+ ldrgeb r4, [r1, #-1]!
+ ldrgtb r5, [r1, #-1]!
strb r3, [r0, #-1]!
- ldrgeb r3, [r1, #-1]!
- strgeb r3, [r0, #-1]!
- ldrgtb r3, [r1, #-1]!
- strgtb r3, [r0, #-1]!
+ strgeb r4, [r0, #-1]!
+ strgtb r5, [r0, #-1]!
subs r2, r2, ip
blt 24b
ands ip, r1, #3
@@ -455,9 +254,9 @@ ENTRY(memmove)
blt 29f
28: mov ip, r3, lsl #8
ldr r3, [r1, #-4]!
+ subs r2, r2, #4
orr ip, ip, r3, lsr #24
str ip, [r0, #-4]!
- subs r2, r2, #4
bge 28b
29: add r1, r1, #3
b 24b
@@ -481,9 +280,9 @@ ENTRY(memmove)
blt 33f
32: mov ip, r3, lsl #16
ldr r3, [r1, #-4]!
+ subs r2, r2, #4
orr ip, ip, r3, lsr #16
str ip, [r0, #-4]!
- subs r2, r2, #4
bge 32b
33: add r1, r1, #2
b 24b
@@ -507,9 +306,9 @@ ENTRY(memmove)
blt 37f
36: mov ip, r3, lsl #24
ldr r3, [r1, #-4]!
+ subs r2, r2, #4
orr ip, ip, r3, lsr #8
str ip, [r0, #-4]!
- subs r2, r2, #4
bge 36b
37: add r1, r1, #1
b 24b
diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
new file mode 100644
index 000000000..b7202e867
--- /dev/null
+++ b/arch/arm/lib/memset.S
@@ -0,0 +1,88 @@
+/*
+ * linux/arch/arm/lib/memset.S
+ *
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * ASM optimised string functions
+ *
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "constants.h"
+
+ .text
+ .align 5
+ENTRY(memset)
+ mov r3, r0
+ cmp r2, #16
+ blt 6f
+ ands ip, r3, #3
+ beq 1f
+ cmp ip, #2
+ strltb r1, [r3], #1 @ Align destination
+ strleb r1, [r3], #1
+ strb r1, [r3], #1
+ rsb ip, ip, #4
+ sub r2, r2, ip
+1: orr r1, r1, r1, lsl #8
+ orr r1, r1, r1, lsl #16
+ cmp r2, #256
+ blt 4f
+ stmfd sp!, {r4, r5, lr}
+ mov r4, r1
+ mov r5, r1
+ mov lr, r1
+ mov ip, r2, lsr #6
+ sub r2, r2, ip, lsl #6
+2: stmia r3!, {r1, r4, r5, lr} @ 64 bytes at a time.
+ stmia r3!, {r1, r4, r5, lr}
+ stmia r3!, {r1, r4, r5, lr}
+ stmia r3!, {r1, r4, r5, lr}
+ subs ip, ip, #1
+ bne 2b
+ teq r2, #0
+ LOADREGS(eqfd, sp!, {r4, r5, pc}) @ Now <64 bytes to go.
+ tst r2, #32
+ stmneia r3!, {r1, r4, r5, lr}
+ stmneia r3!, {r1, r4, r5, lr}
+ tst r2, #16
+ stmneia r3!, {r1, r4, r5, lr}
+ ldmia sp!, {r4, r5}
+3: tst r2, #8
+ stmneia r3!, {r1, lr}
+ tst r2, #4
+ strne r1, [r3], #4
+ tst r2, #2
+ strneb r1, [r3], #1
+ strneb r1, [r3], #1
+ tst r2, #1
+ strneb r1, [r3], #1
+ LOADREGS(fd, sp!, {pc})
+
+4: movs ip, r2, lsr #3
+ beq 3b
+ sub r2, r2, ip, lsl #3
+ str lr, [sp, #-4]!
+ mov lr, r1
+ subs ip, ip, #4
+5: stmgeia r3!, {r1, lr}
+ stmgeia r3!, {r1, lr}
+ stmgeia r3!, {r1, lr}
+ stmgeia r3!, {r1, lr}
+ subges ip, ip, #4
+ bge 5b
+ tst ip, #2
+ stmneia r3!, {r1, lr}
+ stmneia r3!, {r1, lr}
+ tst ip, #1
+ stmneia r3!, {r1, lr}
+ teq r2, #0
+ LOADREGS(eqfd, sp!, {pc})
+ b 3b
+
+6: subs r2, r2, #1
+ strgeb r1, [r3], #1
+ bgt 6b
+ RETINSTR(mov, pc, lr)
+
+
diff --git a/arch/arm/lib/memzero.S b/arch/arm/lib/memzero.S
new file mode 100644
index 000000000..59ec36574
--- /dev/null
+++ b/arch/arm/lib/memzero.S
@@ -0,0 +1,80 @@
+/*
+ * linux/arch/arm/lib/memzero.S
+ *
+ * Copyright (C) 1995-1999 Russell King
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "constants.h"
+
+ .text
+
+/*
+ * Prototype: void memzero(void *d, size_t n)
+ */
+1: @ 4 <= r1
+ cmp ip, #2 @ 1
+ strltb r2, [r0], #1 @ 1
+ strleb r2, [r0], #1 @ 1
+ strb r2, [r0], #1 @ 1
+ rsb ip, ip, #4 @ 1
+ sub r1, r1, ip @ 1
+ cmp r1, #3 @ 1
+ bgt 2f @ 1 @ +8
+ b 4f @ 1 @ +9
+
+ .align 5
+
+ENTRY(__memzero)
+ mov r2, #0 @ 1
+ cmp r1, #4 @ 1
+ blt 4f @ 1 @ = 3
+
+ @ r1 >= 4
+
+ ands ip, r0, #3 @ 1
+ bne 1b @ 1 @ = 5
+
+2: @ r1 >= 4 && (r0 & 3) = 0 @ = 5 or 11
+
+ str lr, [sp, #-4]! @ 1
+ mov r3, #0 @ 1
+ mov ip, #0 @ 1
+ mov lr, #0 @ 1
+
+ @ 4 <= r1 <= 32 @ = 9 or 15
+
+3: subs r1, r1, #32 @ 1
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ bgt 3b @ 1
+ LOADREGS(eqfd, sp!, {pc}) @ 1/2
+
+ @ -28 <= r1 <= -1
+
+ cmp r1, #-16 @ 1
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ ldr lr, [sp], #4 @ 1
+ addlts r1, r1, #16 @ 1
+ RETINSTR(moveq,pc,lr) @ 1
+
+ @ -12 <= r1 <= -1
+
+ cmp r1, #-8 @ 1
+ stmgeia r0!, {r2, r3} @ 2
+ addlts r1, r1, #8 @ 1
+ RETINSTR(moveq,pc,lr) @ 1
+
+ @ -4 <= r1 <= -1
+
+ cmp r1, #-4 @ 1
+ strge r2, [r0], #4 @ 1
+ adds r1, r1, #4 @ 1
+ RETINSTR(moveq,pc,lr) @ 1
+
+4: @ 1 <= r1 <= 3
+ cmp r1, #2 @ 1
+ strgtb r2, [r0], #1 @ 1
+ strgeb r2, [r0], #1 @ 1
+ strb r2, [r0], #1 @ 1
+ RETINSTR(mov,pc,lr) @ 1
diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S
new file mode 100644
index 000000000..b4319b4c3
--- /dev/null
+++ b/arch/arm/lib/setbit.S
@@ -0,0 +1,26 @@
+/*
+ * linux/arch/arm/lib/setbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+@ Purpose : Function to set a bit
+@ Prototype: int set_bit(int bit,int *addr)
+
+ENTRY(set_bit)
+ and r2, r0, #7
+ mov r3, #1
+ mov r3, r3, lsl r2
+ SAVEIRQS(ip)
+ DISABLEIRQS(ip)
+ ldrb r2, [r1, r0, lsr #3]
+ orr r2, r2, r3
+ strb r2, [r1, r0, lsr #3]
+ RESTOREIRQS(ip)
+ RETINSTR(mov,pc,lr)
+
+
diff --git a/arch/arm/lib/strchr.S b/arch/arm/lib/strchr.S
new file mode 100644
index 000000000..fbde2483f
--- /dev/null
+++ b/arch/arm/lib/strchr.S
@@ -0,0 +1,26 @@
+/*
+ * linux/arch/arm/lib/strchr.S
+ *
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * ASM optimised string functions
+ *
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "constants.h"
+
+ .text
+ENTRY(strchr)
+ str lr, [sp, #-4]!
+ mov r3, #0
+1: ldrb r2, [r0], #1
+ teq r2, r1
+ teqne r2, #0
+ bne 1b
+ teq r2, #0
+ moveq r0, #0
+ subne r0, r0, #1
+ LOADREGS(fd, sp!, {pc})
+
+
diff --git a/arch/arm/lib/strrchr.S b/arch/arm/lib/strrchr.S
new file mode 100644
index 000000000..ad5a46089
--- /dev/null
+++ b/arch/arm/lib/strrchr.S
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/arm/lib/strrchr.S
+ *
+ * Copyright (C) 1995-1999 Russell King
+ *
+ * ASM optimised string functions
+ *
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include "constants.h"
+
+ .text
+ENTRY(strrchr)
+ stmfd sp!, {lr}
+ mov r3, #0
+1: ldrb r2, [r0], #1
+ teq r2, r1
+ moveq r3, r0
+ teq r2, #0
+ bne 1b
+ mov r0, r3
+ LOADREGS(fd, sp!, {pc})
+
+
diff --git a/arch/arm/lib/system.c b/arch/arm/lib/system.c
deleted file mode 100644
index f3b32cd82..000000000
--- a/arch/arm/lib/system.c
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * linux/arch/arm/lib/system.c
- *
- * Copyright (C) 1999 Russell King
- *
- * Converted from ASM version 04/09/1999
- */
-#include <linux/kernel.h>
-
-extern void abort(void)
-{
- void *lr = __builtin_return_address(0);
-
- printk(KERN_CRIT "kernel abort from %p! (Please report to rmk@arm.linux.org.uk)\n",
- lr);
-
- /* force an oops */
- *(int *)0 = 0;
-
- /* if that doesn't kill us, halt */
- panic("Oops failed to kill thread");
-}
diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S
new file mode 100644
index 000000000..d3dd48216
--- /dev/null
+++ b/arch/arm/lib/testchangebit.S
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/arm/lib/testchangebit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+ENTRY(test_and_change_bit)
+ add r1, r1, r0, lsr #3
+ and r3, r0, #7
+ mov r0, #1
+ SAVEIRQS(ip)
+ DISABLEIRQS(ip)
+ ldrb r2, [r1]
+ tst r2, r0, lsl r3
+ eor r2, r2, r0, lsl r3
+ moveq r0, #0
+ strb r2, [r1]
+ RESTOREIRQS(ip)
+ RETINSTR(mov,pc,lr)
+
+
diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S
new file mode 100644
index 000000000..431865302
--- /dev/null
+++ b/arch/arm/lib/testclearbit.S
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/arm/lib/testclearbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+ENTRY(test_and_clear_bit)
+ add r1, r1, r0, lsr #3 @ Get byte offset
+ and r3, r0, #7 @ Get bit offset
+ mov r0, #1
+ SAVEIRQS(ip)
+ DISABLEIRQS(ip)
+ ldrb r2, [r1]
+ tst r2, r0, lsl r3
+ bic r2, r2, r0, lsl r3
+ moveq r0, #0
+ strb r2, [r1]
+ RESTOREIRQS(ip)
+ RETINSTR(mov,pc,lr)
+
+
diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S
new file mode 100644
index 000000000..760b6649d
--- /dev/null
+++ b/arch/arm/lib/testsetbit.S
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/arm/lib/testsetbit.S
+ *
+ * Copyright (C) 1995-1996 Russell King
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+ .text
+
+ENTRY(test_and_set_bit)
+ add r1, r1, r0, lsr #3 @ Get byte offset
+ and r3, r0, #7 @ Get bit offset
+ mov r0, #1
+ SAVEIRQS(ip)
+ DISABLEIRQS(ip)
+ ldrb r2, [r1]
+ tst r2, r0, lsl r3
+ orr r2, r2, r0, lsl r3
+ moveq r0, #0
+ strb r2, [r1]
+ RESTOREIRQS(ip)
+ RETINSTR(mov,pc,lr)
+
+
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index 898d2ef77..00f987b5f 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -12,21 +12,13 @@
#include <asm/errno.h>
.text
-#ifdef ENTRY
+
#define USER(x...) \
9999: x; \
.section __ex_table,"a"; \
.align 3; \
.long 9999b,9001f; \
.previous
-#else
-#define USER(x...) \
- x
-#define ENTRY(x...) \
- .globl _##x; \
-_##x:
-#define TESTING
-#endif
#define PAGE_SHIFT 12
@@ -285,12 +277,10 @@ USER( strgebt r3, [r0], #1) @ May fault
USER( strgtbt r3, [r0], #1) @ May fault
b .c2u_finished
-#ifndef TESTING
.section .fixup,"ax"
.align 0
9001: LOADREGS(fd,sp!, {r0, r4 - r7, pc})
.previous
-#endif
/* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n);
* Purpose : copy a block from user memory to kernel memory
@@ -546,7 +536,6 @@ USER( ldrget r3, [r1], #0) @ May fault
strgtb r3, [r0], #1
b .cfu_finished
-#ifndef TESTING
.section .fixup,"ax"
.align 0
/* We took an exception. Zero out the buffer and pretend no
@@ -557,7 +546,6 @@ USER( ldrget r3, [r1], #0) @ May fault
blne SYMBOL_NAME(__memzero)
LOADREGS(fd,sp!, {r0, r4 - r7, pc})
.previous
-#endif
/* Prototype: int __arch_clear_user(void *addr, size_t sz)
* Purpose : clear some user memory
@@ -592,7 +580,6 @@ USER( strnebt r2, [r0], #1)
mov r0, #0
LOADREGS(fd,sp!, {r1, pc})
-#ifndef TESTING
.section .fixup,"ax"
.align 0
9001: LOADREGS(fd,sp!, {r0, pc})
@@ -656,5 +643,4 @@ USER( ldrbt r3, [r1], #1)
.previous
.align
-#endif
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 8715ea271..5151591b8 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -29,6 +29,8 @@
#define DO_COW(m) (!((m) & FAULT_CODE_READ))
#define READ_FAULT(m) ((m) & FAULT_CODE_READ)
+extern void die_if_kernel(const char *str, struct pt_regs *regs, int err);
+
#include "fault-common.c"
#ifdef DEBUG
@@ -118,17 +120,18 @@ static int proc_alignment_read(char *page, char **start, off_t off,
* This needs to be done after sysctl_init, otherwise sys/
* will be overwritten.
*/
-void __init alignment_init(void)
+static int __init alignment_init(void)
{
create_proc_read_entry("sys/debug/alignment", 0, NULL,
- proc_alignment_read);
+ proc_alignment_read, NULL);
+ return 0;
}
__initcall(alignment_init);
#endif /* CONFIG_SYSCTL */
static int
-do_alignment_exception(struct pt_regs *regs)
+do_alignment(unsigned long addr, int error_code, struct pt_regs *regs)
{
unsigned int instr, rd, rn, correction, nr_regs, regbits;
unsigned long eaddr;
@@ -308,116 +311,99 @@ do_alignment_exception(struct pt_regs *regs)
return 0;
}
+#else
+
+#define do_alignment NULL
+
#endif
-#define BUG_PROC_MSG \
- "Buggy processor (%08X), trying to continue.\n" \
- "Please read http://www.arm.linux.org.uk/state.html for more information"
+#ifdef CONFIG_DEBUG_USER
-asmlinkage void
-do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
+static int
+do_sect_fault(unsigned long addr, int error_code, struct pt_regs *regs)
{
if (user_mode(regs)) {
- if (addr == regs->ARM_pc) {
- static int first = 1;
- if (first) {
- /*
- * I want statistical information on this problem!
- */
- printk(KERN_ERR BUG_PROC_MSG, fsr);
- first = 0;
+ printk("%s: permission fault on section, "
+ "address=0x%08lx, code %d\n",
+ current->comm, addr, error_code);
+#ifdef DEBUG
+ {
+ unsigned int i, j;
+ unsigned long *sp;
+
+ sp = (unsigned long *) (regs->ARM_sp - 128);
+ for (j = 0; j < 20 && sp_valid(sp); j++) {
+ printk("%p: ", sp);
+ for (i = 0; i < 8 && sp_valid(sp); i += 1, sp++)
+ printk("%08lx ", *sp);
+ printk("\n");
}
- return;
+ show_regs(regs);
+ c_backtrace(regs->ARM_fp, regs->ARM_cpsr);
}
+#endif
}
+ return 1; /* not fixed up */
+}
+#else
-#define DIE(signr,nam)\
- force_sig(signr, current);\
- die(nam, regs, fsr);\
- do_exit(signr);\
- break
-
- switch (fsr & 15) {
- /*
- * 0 - vector exception
- */
- case 0:
- force_sig(SIGSEGV, current);
- if (!user_mode(regs)) {
- die("vector exception", regs, fsr);
- do_exit(SIGSEGV);
- }
- break;
-
- /*
- * 15 - permission fault on page
- * 5 - page-table entry descriptor fault
- * 7 - first-level descriptor fault
- */
- case 15: case 5: case 7:
- do_page_fault(addr, error_code, regs);
- break;
+#define do_sect_fault NULL
- /*
- * 13 - permission fault on section
- */
- case 13:
- force_sig(SIGSEGV, current);
- if (!user_mode(regs)) {
- die("section permission fault", regs, fsr);
- do_exit(SIGSEGV);
- } else {
-#ifdef CONFIG_DEBUG_USER
- printk("%s: permission fault on section, "
- "address=0x%08lx, code %d\n",
- current->comm, addr, error_code);
-#ifdef DEBUG
- {
- unsigned int i, j;
- unsigned long *sp;
-
- sp = (unsigned long *) (regs->ARM_sp - 128);
- for (j = 0; j < 20 && sp_valid(sp); j++) {
- printk("%p: ", sp);
- for (i = 0; i < 8 && sp_valid(sp); i += 1, sp++)
- printk("%08lx ", *sp);
- printk("\n");
- }
- show_regs(regs);
- c_backtrace(regs->ARM_fp, regs->ARM_cpsr);
- }
-#endif
#endif
+
+static struct fsr_info {
+ int (*fn)(unsigned long addr, int error_code, struct pt_regs *regs);
+ int sig;
+ char *name;
+} fsr_info[] = {
+ { NULL, SIGSEGV, "vector exception" },
+ { do_alignment, SIGBUS, "alignment exception" },
+ { NULL, SIGKILL, "terminal exception" },
+ { do_alignment, SIGBUS, "alignment exception" },
+ { NULL, SIGBUS, "external abort on linefetch" },
+ { do_page_fault, SIGSEGV, "page fault" },
+ { NULL, SIGBUS, "external abort on linefetch" },
+ { do_page_fault, SIGSEGV, "page fault" },
+ { NULL, SIGBUS, "external abort on non-linefetch" },
+ { NULL, SIGSEGV, "domain fault" },
+ { NULL, SIGBUS, "external abort on non-linefetch" },
+ { NULL, SIGSEGV, "domain fault" },
+ { NULL, SIGBUS, "external abort on translation" },
+ { do_sect_fault, SIGSEGV, "section permission fault" },
+ { NULL, SIGBUS, "external abort on translation" },
+ { do_page_fault, SIGSEGV, "page permission fault" }
+};
+
+/*
+ * Currently dropped down to debug level
+ */
+#define BUG_PROC_MSG \
+ KERN_DEBUG "Weird data abort (%08X).\n" \
+ KERN_DEBUG "Please see http://www.arm.linux.org.uk/state.html for more information"
+
+asmlinkage void
+do_DataAbort(unsigned long addr, int fsr, int error_code, struct pt_regs *regs)
+{
+ struct fsr_info *inf;
+
+ if (user_mode(regs) && addr == regs->ARM_pc) {
+ static int first = 1;
+ if (first) {
+ /*
+ * I want statistical information on this problem,
+ * but we don't want to hastle the users too much.
+ */
+ printk(BUG_PROC_MSG, fsr);
+ first = 0;
}
- break;
+ return;
+ }
- case 1:
- case 3:
-#ifdef CONFIG_ALIGNMENT_TRAP
- if (!do_alignment_exception(regs))
- break;
-#endif
- /*
- * this should never happen
- */
- DIE(SIGBUS, "Alignment exception");
- break;
+ inf = fsr_info + (fsr & 15);
- case 2:
- DIE(SIGKILL, "Terminal exception");
- case 12:
- case 14:
- DIE(SIGBUS, "External abort on translation");
- case 9:
- case 11:
- DIE(SIGSEGV, "Domain fault");
-
- case 4:
- case 6:
- DIE(SIGBUS, "External abort on linefetch");
- case 8:
- case 10:
- DIE(SIGBUS, "External abort on non-linefetch");
+ if (!inf->fn || inf->fn(addr, error_code, regs)) {
+ force_sig(inf->sig, current);
+ die_if_kernel(inf->name, regs, fsr);
}
}
diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c
index e516261ed..d04808ffa 100644
--- a/arch/arm/mm/fault-common.c
+++ b/arch/arm/mm/fault-common.c
@@ -6,7 +6,7 @@
*/
#include <linux/config.h>
-extern void die(char *msg, struct pt_regs *regs, unsigned int err);
+extern void die(const char *msg, struct pt_regs *regs, unsigned int err);
/*
* This is useful to dump out the page tables associated with
@@ -79,7 +79,7 @@ kernel_page_fault(unsigned long addr, int write_access, struct pt_regs *regs,
do_exit(SIGKILL);
}
-static void do_page_fault(unsigned long addr, int mode, struct pt_regs *regs)
+static int do_page_fault(unsigned long addr, int mode, struct pt_regs *regs)
{
struct task_struct *tsk;
struct mm_struct *mm;
@@ -127,7 +127,7 @@ good_area:
goto do_sigbus;
up(&mm->mmap_sem);
- return;
+ return 0;
/*
* Something tried to access memory that isn't in our memory map..
@@ -138,6 +138,7 @@ bad_area:
/* User mode accesses just cause a SIGSEGV */
if (user_mode(regs)) {
+ tsk->thread.address = addr;
tsk->thread.error_code = mode;
tsk->thread.trap_no = 14;
#ifdef CONFIG_DEBUG_USER
@@ -145,7 +146,7 @@ bad_area:
tsk->comm, regs->ARM_pc, regs->ARM_lr, addr, mode);
#endif
force_sig(SIGSEGV, tsk);
- return;
+ return 0;
}
no_context:
@@ -156,11 +157,11 @@ no_context:
tsk->comm, regs->ARM_pc, addr, fixup);
#endif
regs->ARM_pc = fixup;
- return;
+ return 0;
}
kernel_page_fault(addr, mode, regs, tsk, mm);
- return;
+ return 0;
do_sigbus:
/*
@@ -173,6 +174,7 @@ do_sigbus:
* Send a sigbus, regardless of whether we were in kernel
* or user mode.
*/
+ tsk->thread.address = addr;
tsk->thread.error_code = mode;
tsk->thread.trap_no = 14;
force_sig(SIGBUS, tsk);
@@ -180,6 +182,7 @@ do_sigbus:
/* Kernel mode? Handle exceptions or die */
if (!user_mode(regs))
goto no_context;
+ return 0;
}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 17972e427..bc4cf1ed1 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -168,7 +168,8 @@ void show_mem(void)
void __init paging_init(void)
{
void *zero_page, *bad_page, *bad_table;
- unsigned int zone_size[3];
+ unsigned int zone_size[MAX_NR_ZONES];
+ int i;
#ifdef CONFIG_CPU_32
#define TABLE_OFFSET (PTRS_PER_PTE)
@@ -193,7 +194,24 @@ void __init paging_init(void)
/*
* Initialise the zones and mem_map
*/
- zonesize_init(zone_size);
+ for (i = 0; i < MAX_NR_ZONES; i++)
+ zone_size[i] = 0;
+
+ /*
+ * Calculate the size of the zones. On ARM, we don't have
+ * any problems with DMA or highmem, so all memory is
+ * allocated to the DMA zone.
+ */
+ for (i = 0; i < meminfo.nr_banks; i++) {
+ if (meminfo.bank[i].size) {
+ unsigned int end;
+
+ end = (meminfo.bank[i].start - PHYS_OFFSET +
+ meminfo.bank[i].size) >> PAGE_SHIFT;
+ if (zone_size[0] < end)
+ zone_size[0] = end;
+ }
+ }
free_area_init(zone_size);
/*
@@ -339,10 +357,11 @@ void free_initmem(void)
#ifdef CONFIG_BLK_DEV_INITRD
void free_initrd_mem(unsigned long start, unsigned long end)
{
- for (; start < end; start += PAGE_SIZE) {
- ClearPageReserved(mem_map + MAP_NR(start));
- set_page_count(mem_map+MAP_NR(start), 1);
- free_page(start);
+ unsigned long addr;
+ for (addr = start; addr < end; addr += PAGE_SIZE) {
+ ClearPageReserved(mem_map + MAP_NR(addr));
+ set_page_count(mem_map+MAP_NR(addr), 1);
+ free_page(addr);
totalram_pages++;
}
printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
diff --git a/arch/arm/mm/mm-armo.c b/arch/arm/mm/mm-armo.c
index 680a52948..a5d4cdfe8 100644
--- a/arch/arm/mm/mm-armo.c
+++ b/arch/arm/mm/mm-armo.c
@@ -135,20 +135,6 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
}
/*
- * Calculate the size of the DMA, normal and highmem zones.
- * On 26-bit ARMs, we don't have any real DMA or highmem,
- * so we allocate the whole memory as being DMA-capable.
- */
-void __init zonesize_init(unsigned int *zone_size)
-{
- int i;
-
- zone_size[0] = max_low_pfn;
- zone_size[1] = 0;
- zone_size[2] = 0;
-}
-
-/*
* This contains the code to setup the memory map on an ARM2/ARM250/ARM3
* machine. This is both processor & architecture specific, and requires
* some more work to get it to fit into our separate processor and
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index ee4750c62..76d101507 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -46,6 +46,15 @@ static int __init nowrite_setup(char *__unused)
return 1;
}
+static int __init noalign_setup(char *__unused)
+{
+ cr_alignment &= ~2;
+ cr_no_alignment &= ~2;
+ set_cr(cr_alignment);
+ return 1;
+}
+
+__setup("noalign", noalign_setup);
__setup("nocache", nocache_setup);
__setup("nowb", nowrite_setup);
@@ -218,7 +227,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, int domain, int prot)
* the clearance is done by the middle-level functions (pmd)
* rather than the top-level (pgd) functions.
*/
-static inline void free_init_section(unsigned long virt)
+static inline void clear_mapping(unsigned long virt)
{
pmd_clear(pmd_offset(pgd_offset_k(virt), virt));
}
@@ -273,73 +282,76 @@ static void __init create_mapping(struct map_desc *md)
}
}
-/*
- * Initial boot-time mapping. This covers just the zero page, kernel and
- * the flush area. NB: it must be sorted by virtual address, and no
- * virtual address overlaps.
- * init_map[2..4] are for architectures with banked memory.
- */
-static struct map_desc init_map[] __initdata = {
- { 0, 0, PAGE_SIZE, DOMAIN_USER, 0, 0, 1, 0 }, /* zero page */
- { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, /* kernel memory */
- { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, /* (4 banks) */
- { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 },
- { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 },
- { 0, 0, PGDIR_SIZE, DOMAIN_KERNEL, 1, 0, 1, 1 }, /* cache flush 1 */
- { 0, 0, 0, DOMAIN_KERNEL, 1, 0, 1, 0 } /* cache flush 2 */
-};
-
-#define NR_INIT_MAPS (sizeof(init_map) / sizeof(init_map[0]))
-
-/*
- * Calculate the size of the DMA, normal and highmem zones.
- * On ARM, we don't have any problems with DMA, so all memory
- * is allocated to the DMA zone. We also don't have any
- * highmem either.
- */
-void __init zonesize_init(unsigned int *zone_size)
+void __init pagetable_init(void)
{
+ struct map_desc *init_maps, *p;
+ unsigned long address = 0;
int i;
- zone_size[0] = 0;
- zone_size[1] = 0;
- zone_size[2] = 0;
+ /*
+ * Setup initial mappings. We use the page we allocated
+ * for zero page to hold the mappings, which will get
+ * overwritten by the vectors in traps_init(). The
+ * mappings must be in virtual address order.
+ */
+ init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE);
+
+ p->physical = virt_to_phys(init_maps);
+ p->virtual = 0;
+ p->length = PAGE_SIZE;
+ p->domain = DOMAIN_USER;
+ p->prot_read = 0;
+ p->prot_write = 0;
+ p->cacheable = 1;
+ p->bufferable = 0;
+
+ p ++;
for (i = 0; i < meminfo.nr_banks; i++) {
- if (meminfo.bank[i].size) {
- unsigned int end;
+ if (meminfo.bank[i].size == 0)
+ continue;
- end = (meminfo.bank[i].start - PHYS_OFFSET +
- meminfo.bank[i].size) >> PAGE_SHIFT;
- if (end > zone_size[0])
- zone_size[0] = end;
- }
+ p->physical = meminfo.bank[i].start;
+ p->virtual = __phys_to_virt(p->physical);
+ p->length = meminfo.bank[i].size;
+ p->domain = DOMAIN_KERNEL;
+ p->prot_read = 0;
+ p->prot_write = 1;
+ p->cacheable = 1;
+ p->bufferable = 1;
+
+ p ++;
}
-}
-void __init pagetable_init(void)
-{
- unsigned long address = 0;
- int i;
+ p->physical = FLUSH_BASE_PHYS;
+ p->virtual = FLUSH_BASE;
+ p->length = PGDIR_SIZE;
+ p->domain = DOMAIN_KERNEL;
+ p->prot_read = 1;
+ p->prot_write = 0;
+ p->cacheable = 1;
+ p->bufferable = 1;
+
+ p ++;
- /*
- * Setup the above mappings
- */
- init_map[0].physical = virt_to_phys(alloc_bootmem_low_pages(PAGE_SIZE));
- init_map[5].physical = FLUSH_BASE_PHYS;
- init_map[5].virtual = FLUSH_BASE;
#ifdef FLUSH_BASE_MINICACHE
- init_map[6].physical = FLUSH_BASE_PHYS + PGDIR_SIZE;
- init_map[6].virtual = FLUSH_BASE_MINICACHE;
- init_map[6].length = PGDIR_SIZE;
+ p->physical = FLUSH_BASE_PHYS + PGDIR_SIZE;
+ p->virtual = FLUSH_BASE_MINICACHE;
+ p->length = PGDIR_SIZE;
+ p->domain = DOMAIN_KERNEL;
+ p->prot_read = 1;
+ p->prot_write = 0;
+ p->cacheable = 1;
+ p->bufferable = 0;
+
+ p ++;
#endif
- for (i = 0; i < meminfo.nr_banks; i++) {
- init_map[i+1].physical = meminfo.bank[i].start;
- init_map[i+1].virtual = meminfo.bank[i].start +
- PAGE_OFFSET - PHYS_OFFSET;
- init_map[i+1].length = meminfo.bank[i].size;
- }
+ /*
+ * We may have a mapping in virtual address 0.
+ * Clear it out.
+ */
+ clear_mapping(0);
/*
* Go through the initial mappings, but clear out any
@@ -347,18 +359,16 @@ void __init pagetable_init(void)
*/
i = 0;
do {
- if (address < init_map[i].virtual || i == NR_INIT_MAPS) {
- free_init_section(address);
+ if (address < init_maps->virtual || init_maps == p) {
+ clear_mapping(address);
address += PGDIR_SIZE;
} else {
- create_mapping(init_map + i);
+ create_mapping(init_maps);
- address = init_map[i].virtual + init_map[i].length;
+ address = init_maps->virtual + init_maps->length;
address = (address + PGDIR_SIZE - 1) & PGDIR_MASK;
- do {
- i += 1;
- } while (init_map[i].length == 0 && i < NR_INIT_MAPS);
+ init_maps ++;
}
} while (address != 0);
@@ -382,6 +392,7 @@ void __init create_memmap_holes(void)
unsigned int i;
#define PFN(x) (((x) - PHYS_OFFSET) >> PAGE_SHIFT)
+#define free_bootmem(s,sz) free_bootmem(((s)<<PAGE_SHIFT)+PHYS_OFFSET, (sz)<<PAGE_SHIFT)
for (i = 0; i < meminfo.nr_banks; i++) {
if (meminfo.bank[i].size == 0)
@@ -409,7 +420,7 @@ void __init create_memmap_holes(void)
end_pfn = PFN(meminfo.bank[i].start + meminfo.bank[i].size);
- if (end_pfn != meminfo.end >> PAGE_SHIFT)
+ if (end_pfn != PFN(meminfo.end))
pg = mem_map + end_pfn;
}
diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c
index eba2984b6..c6f9f2e8b 100644
--- a/arch/arm/mm/mm-sa1100.c
+++ b/arch/arm/mm/mm-sa1100.c
@@ -6,11 +6,11 @@
* Copyright (C) 1998-1999 Russell King
* Copyright (C) 1999 Hugo Fiennes
*
- * 1999/09/12 Nicolas Pitre <nico@visuaide.com>
- * Specific RAM implementation details are in
- * linux/include/asm/arch-sa1100/memory.h now.
- * Allows for better macro optimisations when possible.
+ * 1999/12/04 Nicolas Pitre <nico@cam.org>
+ * Converted memory definition for struct meminfo initialisations.
+ * Memory is listed physically now.
*/
+
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/init.h>
@@ -22,33 +22,37 @@
#define SIZE(x) (sizeof(x) / sizeof(x[0]))
+
/*
- * These are the memory size mappings for the
- * SA1100. Note that LART is a special case -
- * it doesn't use physical address A23 on the
- * DRAM, so we effectively have 4 * 8MB in
- * two banks.
+ * These are the RAM memory mappings for SA1100 implementations.
+ * Note that LART is a special case - it doesn't use physical
+ * address line A23 on the DRAM, so we effectively have 4 * 8MB
+ * in two banks.
*/
-struct mem_desc mem_desc[] __initdata = {
- /* virt start virt end */
+struct mem_desc {
+ unsigned long phys_start;
+ unsigned long length;
+} mem_desc[] __initdata = {
#if defined(CONFIG_SA1100_BRUTUS)
- { 0xc0000000, 0xc0400000 }, /* 4MB */
- { 0xc1000000, 0xc1400000 }, /* 4MB */
- { 0xc2000000, 0xc2400000 }, /* 4MB */
- { 0xc3000000, 0xc3400000 } /* 4MB */
+ { 0xc0000000, 0x00400000 }, /* 4MB */
+ { 0xc8000000, 0x00400000 }, /* 4MB */
+#if 0 /* only two banks until the bootmem stuff is fixed... */
+ { 0xd0000000, 0x00400000 }, /* 4MB */
+ { 0xd8000000, 0x00400000 } /* 4MB */
+#endif
#elif defined(CONFIG_SA1100_EMPEG)
- { 0xc0000000, 0xc0400000 }, /* 4MB */
- { 0xc1000000, 0xc1400000 } /* 4MB */
+ { 0xc0000000, 0x00400000 }, /* 4MB */
+ { 0xc8000000, 0x00400000 } /* 4MB */
#elif defined(CONFIG_SA1100_LART)
- { 0xc0000000, 0xc0800000 }, /* 16MB */
- { 0xc1000000, 0xc1800000 },
- { 0xc2000000, 0xc2800000 }, /* 16MB */
- { 0xc3000000, 0xc3800000 }
+ { 0xc0000000, 0x00800000 }, /* 8MB */
+ { 0xc1000000, 0x00800000 }, /* 8MB */
+ { 0xc8000000, 0x00800000 }, /* 8MB */
+ { 0xc9000000, 0x00800000 } /* 8MB */
#elif defined(CONFIG_SA1100_VICTOR)
- { 0xc0000000, 0xc0400000 } /* 4MB */
+ { 0xc0000000, 0x00400000 } /* 4MB */
#elif defined(CONFIG_SA1100_TIFON)
- { 0xc0000000, 0xc1000000 }, /* 16MB */
- { 0xc1000000, 0xc2000000 } /* 16MB */
+ { 0xc0000000, 0x01000000 }, /* 16MB */
+ { 0xc8000000, 0x01000000 } /* 16MB */
#else
#error missing memory configuration
#endif
@@ -56,6 +60,7 @@ struct mem_desc mem_desc[] __initdata = {
unsigned int __initdata mem_desc_size = SIZE(mem_desc);
+
struct map_desc io_desc[] __initdata = {
/* virtual physical length domain r w c b */
#if defined(CONFIG_SA1100_VICTOR)
diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S
index d453269d2..23508c197 100644
--- a/arch/arm/mm/proc-arm6,7.S
+++ b/arch/arm/mm/proc-arm6,7.S
@@ -134,14 +134,10 @@ ENTRY(cpu_arm7_data_abort)
b Ldata_simple @ ldc rd, [rn, #m]
b Ldata_unknown
Ldata_unknown: @ Part of jumptable
- ldr r3, [sp, #15 * 4] @ Get PC
- str r3, [sp, #-4]!
- mov r1, r1, lsr #2
- mov r3, r4
- mov r2, r0
- adr r0, Lukabttxt
- bl SYMBOL_NAME(panic)
-Lstop: b Lstop
+ mov r0, r1
+ mov r1, r4
+ mov r2, r3
+ b baddataabort
Ldata_ldmstm: tst r4, #1 << 21 @ check writeback bit
beq Ldata_simple
@@ -468,7 +464,7 @@ ENTRY(arm6_processor_functions)
.word cpu_arm6_cache_wback_area
.word cpu_arm6_cache_purge_area
.word cpu_arm6_flush_tlb_page
- .word cpu_arm7_do_idle
+ .word cpu_arm6_do_idle
.size arm6_processor_functions, . - arm6_processor_functions
/*
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 2d57b1030..5431f14a0 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -16,6 +16,7 @@
* is larger than this, then we flush the whole cache
*/
#define MAX_AREA_SIZE 32768
+#define FLUSH_OFFSET 32768
.macro flush_110_dcache rd, ra, re
add \re, \ra, #16384 @ only necessary for 16k
@@ -56,7 +57,7 @@ cpu_sa110_flush_cache_all_r2:
ands r1, r1, #1
eor r1, r1, #1
str r1, [r3]
- addne ip, ip, #32768
+ addne ip, ip, #FLUSH_OFFSET
flush_110_dcache r3, ip, r1
mov ip, #0
teq r2, #0
@@ -74,7 +75,7 @@ cpu_sa1100_flush_cache_all_r2:
ands r1, r1, #1
eor r1, r1, #1
str r1, [r3]
- addne ip, ip, #32768
+ addne ip, ip, #FLUSH_OFFSET
flush_1100_dcache r3, ip, r1
mov ip, #0
teq r2, #0
@@ -321,7 +322,7 @@ ENTRY(cpu_sa110_set_pgd)
ands r2, r2, #1
eor r2, r2, #1
str r2, [r3]
- addne ip, ip, #32768
+ addne ip, ip, #FLUSH_OFFSET
flush_110_dcache r3, ip, r1
mov r1, #0
mcr p15, 0, r1, c7, c5, 0 @ flush I cache
@@ -338,7 +339,7 @@ ENTRY(cpu_sa1100_set_pgd)
ands r2, r2, #1
eor r2, r2, #1
str r2, [r3]
- addne ip, ip, #32768
+ addne ip, ip, #FLUSH_OFFSET
flush_1100_dcache r3, ip, r1
mov r1, #0
mcr p15, 0, r1, c7, c5, 0 @ flush I cache
@@ -430,8 +431,12 @@ ENTRY(cpu_sa110_do_idle)
ENTRY(cpu_sa1100_do_idle)
mov r0, #0
mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
- @ load from uncacheable loc?
- mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt
+ ldr r1, =FLUSH_BASE+FLUSH_OFFSET*2 @ load from uncacheable loc
+ ldr r1, [r1, #0]
+ b 1f
+
+ .align 5
+1: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt
mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching
mov pc, lr
diff --git a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in
index f83109875..93b8946e7 100644
--- a/arch/arm/vmlinux-armv.lds.in
+++ b/arch/arm/vmlinux-armv.lds.in
@@ -6,82 +6,84 @@ OUTPUT_ARCH(arm)
ENTRY(stext)
SECTIONS
{
- . = TEXTADDR;
- .text : { } /* Set text start address */
-
- __init_begin = .; /* Init code and data */
- .text.init : { *(.text.init) }
- __proc_info_begin = .;
- .proc.info : { *(.proc.info) }
- __proc_info_end = .;
- .data.init : { *(.data.init) }
- . = ALIGN(16);
- __setup_start = .;
- .setup.init : { *(.setup.init) }
- __setup_end = .;
- __initcall_start = .;
- .initcall.init : { *(.initcall.init) }
- __initcall_end = .;
- . = ALIGN(4096);
- __init_end = .;
-
- __ebsa285_begin = .;
- .text.ebsa285 : { *(.text.ebsa285) }
- .data.ebsa285 : { *(.data.ebsa285) }
- . = ALIGN(4096);
- __ebsa285_end = .;
-
- __netwinder_begin = .;
- .text.netwinder : { *(.text.netwinder) }
- .data.netwinder : { *(.data.netwinder) }
- . = ALIGN(4096);
- __netwinder_end = .;
-
- _text = .; /* Text and read-only data */
- .text.real : { /* Real text segment */
- *(.text)
- *(.fixup)
- *(.gnu.warning)
+ . = TEXTADDR;
+ .init : { /* Init code and data */
+ __init_begin = .;
+ *(.text.init)
+ __proc_info_begin = .;
+ *(.proc.info)
+ __proc_info_end = .;
+ *(.data.init)
+ . = ALIGN(16);
+ __setup_start = .;
+ *(.setup.init)
+ __setup_end = .;
+ __initcall_start = .;
+ *(.initcall.init)
+ __initcall_end = .;
+ . = ALIGN(4096);
+ __init_end = .;
}
- .text.lock : { *(.text.lock) } /* out-of-line lock text */
- .rodata : { *(.rodata) }
- .kstrtab : { *(.kstrtab) }
+ .ebsa285 : {
+ __ebsa285_begin = .;
+ *(.text.ebsa285)
+ *(.data.ebsa285)
+ . = ALIGN(4096);
+ __ebsa285_end = .;
+ }
- . = ALIGN(16); /* Exception table */
- __start___ex_table = .;
- __ex_table : { *(__ex_table) }
- __stop___ex_table = .;
+ .netwinder : {
+ __netwinder_begin = .;
+ *(.text.netwinder)
+ *(.data.netwinder)
+ . = ALIGN(4096);
+ __netwinder_end = .;
+ }
- __start___ksymtab = .; /* Kernel symbol table */
- __ksymtab : { *(__ksymtab) }
- __stop___ksymtab = .;
+ .text : { /* Real text segment */
+ _text = .; /* Text and read-only data */
+ *(.text)
+ *(.fixup)
+ *(.gnu.warning)
+ *(.text.lock) /* out-of-line lock text */
+ *(.rodata)
+ *(.kstrtab)
+ . = ALIGN(16); /* Exception table */
+ __start___ex_table = .;
+ *(__ex_table)
+ __stop___ex_table = .;
- .got : { *(.got) } /* Global offset table */
+ __start___ksymtab = .; /* Kernel symbol table */
+ *(__ksymtab)
+ __stop___ksymtab = .;
- _etext = .; /* End of text section */
+ *(.got) /* Global offset table */
- . = ALIGN(8192);
- .data : { /* Data */
- *(.init.task)
- *(.data)
- CONSTRUCTORS
+ _etext = .; /* End of text section */
}
- _edata = .; /* End of data section */
+ . = ALIGN(8192);
- __bss_start = .; /* BSS */
- .bss : {
- *(.bss)
+ .data : { /* Data */
+ *(.init.task)
+ *(.data)
+ CONSTRUCTORS
+ _edata = .; /* End of data section */
}
- _end = . ;
- /* Stabs debugging sections. */
- .stab 0 : { *(.stab) }
- .stabstr 0 : { *(.stabstr) }
- .stab.excl 0 : { *(.stab.excl) }
- .stab.exclstr 0 : { *(.stab.exclstr) }
- .stab.index 0 : { *(.stab.index) }
- .stab.indexstr 0 : { *(.stab.indexstr) }
- .comment 0 : { *(.comment) }
+ .bss : {
+ __bss_start = .; /* BSS */
+ *(.bss)
+ *(COMMON)
+ _end = . ;
+ }
+ /* Stabs debugging sections. */
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
}
diff --git a/arch/i386/config.in b/arch/i386/config.in
index 654602855..a32b43c65 100644
--- a/arch/i386/config.in
+++ b/arch/i386/config.in
@@ -7,6 +7,8 @@ mainmenu_name "Linux Kernel Configuration"
define_bool CONFIG_X86 y
define_bool CONFIG_ISA y
+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
@@ -35,6 +37,7 @@ if [ "$CONFIG_M686" = "y" -o "$CONFIG_M586TSC" = "y" ]; then
fi
if [ "$CONFIG_M686" = "y" ]; then
define_bool CONFIG_X86_GOOD_APIC y
+ define_bool CONFIG_X86_PGE y
fi
if [ "$CONFIG_MK7" = "y" ]; then
define_bool CONFIG_X86_TSC y
@@ -57,6 +60,13 @@ fi
bool 'Math emulation' CONFIG_MATH_EMULATION
bool 'MTRR (Memory Type Range Register) support' CONFIG_MTRR
bool 'Symmetric multi-processing support' CONFIG_SMP
+if [ "$CONFIG_SMP" != "y" ]; then
+ bool 'APIC and IO-APIC support on uniprocessors' CONFIG_X86_UP_IOAPIC
+ if [ "$CONFIG_X86_UP_IOAPIC" = "y" ]; then
+ define_bool CONFIG_X86_IO_APIC y
+ define_bool CONFIG_X86_LOCAL_APIC y
+ fi
+fi
endmenu
mainmenu_option next_comment
@@ -103,7 +113,11 @@ if [ "$CONFIG_VISWS" != "y" ]; then
bool 'MCA support' CONFIG_MCA
fi
-source drivers/pcmcia/Config.in
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
+if [ "$CONFIG_HOTPLUG" = "y" ] ; then
+ source drivers/pcmcia/Config.in
+fi
bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
@@ -163,6 +177,8 @@ if [ "$CONFIG_SCSI" != "n" ]; then
fi
endmenu
+source drivers/ieee1394/Config.in
+
source drivers/i2o/Config.in
if [ "$CONFIG_NET" = "y" ]; then
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 9b248a6be..91ca9739b 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -3,6 +3,7 @@
#
CONFIG_X86=y
CONFIG_ISA=y
+CONFIG_UID16=y
#
# Code maturity level options
@@ -24,6 +25,7 @@ CONFIG_X86_BSWAP=y
CONFIG_X86_POPAD_OK=y
CONFIG_X86_TSC=y
CONFIG_X86_GOOD_APIC=y
+CONFIG_X86_PGE=y
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
# CONFIG_HIGHMEM64G is not set
@@ -53,13 +55,13 @@ CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
CONFIG_PCI_NAMES=y
# CONFIG_MCA is not set
+CONFIG_HOTPLUG=y
#
# PCMCIA/CardBus support
#
CONFIG_PCMCIA=y
CONFIG_CARDBUS=y
-CONFIG_YENTA=y
# CONFIG_I82365 is not set
CONFIG_TCIC=y
CONFIG_SYSVIPC=y
@@ -102,11 +104,13 @@ CONFIG_BLK_DEV_IDECD=y
#
CONFIG_BLK_DEV_CMD640=y
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
CONFIG_BLK_DEV_RZ1000=y
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_BLK_DEV_IDEDMA_PCI is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
# CONFIG_BLK_DEV_AEC6210 is not set
+# CONFIG_BLK_DEV_CMD64X is not set
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_BLK_CPQ_DA is not set
@@ -314,6 +318,7 @@ CONFIG_PCMCIA_PCNET=y
# CONFIG_PCMCIA_SMC91C92 is not set
# CONFIG_PCMCIA_XIRC2PS is not set
# CONFIG_AIRONET4500_CS is not set
+# CONFIG_ARCNET_COM20020_CS is not set
# CONFIG_PCMCIA_3C575 is not set
# CONFIG_PCMCIA_TULIP is not set
# CONFIG_PCMCIA_EPIC100 is not set
@@ -397,6 +402,7 @@ CONFIG_PSMOUSE=y
CONFIG_DRM=y
CONFIG_DRM_TDFX=y
# CONFIG_DRM_GAMMA is not set
+CONFIG_PCMCIA_SERIAL=y
#
# PCMCIA character device support
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index e60e15620..a59e7c71b 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -55,8 +55,12 @@ ifdef CONFIG_SMP
O_OBJS += smp.o smpboot.o trampoline.o
endif
+ifdef CONFIG_X86_LOCAL_APIC
+O_OBJS += apic.o
+endif
+
ifdef CONFIG_X86_IO_APIC
-O_OBJS += io_apic.o
+O_OBJS += io_apic.o mpparse.o
endif
ifdef CONFIG_X86_VISWS_APIC
diff --git a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c
index 49444d258..3fd1704e3 100644
--- a/arch/i386/kernel/acpi.c
+++ b/arch/i386/kernel/acpi.c
@@ -172,6 +172,14 @@ static struct ctl_table acpi_table[] =
&acpi_p_lvl3_lat, sizeof(acpi_p_lvl3_lat),
0644, NULL, &acpi_do_ulong},
+ {ACPI_P_LVL2_LAT, "enter_lvl2_lat",
+ &acpi_enter_lvl2_lat, sizeof(acpi_enter_lvl2_lat),
+ 0644, NULL, &acpi_do_ulong},
+
+ {ACPI_ENTER_LVL3_LAT, "enter_lvl3_lat",
+ &acpi_enter_lvl3_lat, sizeof(acpi_enter_lvl3_lat),
+ 0644, NULL, &acpi_do_ulong},
+
{ACPI_S0_SLP_TYP, "s0_slp_typ",
&acpi_slp_typ[ACPI_S0], sizeof(acpi_slp_typ[ACPI_S0]),
0600, NULL, &acpi_do_ulong},
@@ -195,6 +203,17 @@ static struct ctl_table acpi_dir_table[] =
{0}
};
+static u32 FASTCALL(acpi_read_pm1_control(struct acpi_facp *));
+static u32 FASTCALL(acpi_read_pm1_status(struct acpi_facp *));
+static u32 FASTCALL(acpi_read_pm1_enable(struct acpi_facp *));
+static u32 FASTCALL(acpi_read_gpe_status(struct acpi_facp *));
+static u32 FASTCALL(acpi_read_gpe_enable(struct acpi_facp *));
+
+static void FASTCALL(acpi_write_pm1_control(struct acpi_facp *, u32));
+static void FASTCALL(acpi_write_pm1_status(struct acpi_facp *, u32));
+static void FASTCALL(acpi_write_pm1_enable(struct acpi_facp *, u32));
+static void FASTCALL(acpi_write_gpe_status(struct acpi_facp *, u32));
+static void FASTCALL(acpi_write_gpe_enable(struct acpi_facp *, u32));
/*
* Get the value of the PM1 control register (SCI_EN, ...)
@@ -643,43 +662,49 @@ static int acpi_disable(struct acpi_facp *facp)
return 0;
}
-static inline int bm_activity(void)
+static inline int bm_activity(struct acpi_facp *facp)
{
- return 0 && acpi_read_pm1_status(acpi_facp) & ACPI_BM;
+ return acpi_read_pm1_status(facp) & ACPI_BM;
}
-static inline void clear_bm_activity(void)
+static inline void clear_bm_activity(struct acpi_facp *facp)
{
- acpi_write_pm1_status(acpi_facp, ACPI_BM);
+ acpi_write_pm1_status(facp, ACPI_BM);
}
-static void sleep_on_busmaster(void)
+static void sleep_on_busmaster(struct acpi_facp *facp)
{
- u32 pm1_cntr = acpi_read_pm1_control(acpi_facp);
+ u32 pm1_cntr = acpi_read_pm1_control(facp);
if (pm1_cntr & ACPI_BM_RLD) {
pm1_cntr &= ~ACPI_BM_RLD;
- acpi_write_pm1_control(acpi_facp, pm1_cntr);
+ acpi_write_pm1_control(facp, pm1_cntr);
}
}
-static void wake_on_busmaster(void)
+static void wake_on_busmaster(struct acpi_facp *facp)
{
- u32 pm1_cntr = acpi_read_pm1_control(acpi_facp);
+ u32 pm1_cntr = acpi_read_pm1_control(facp);
if (!(pm1_cntr & ACPI_BM_RLD)) {
pm1_cntr |= ACPI_BM_RLD;
- acpi_write_pm1_control(acpi_facp, pm1_cntr);
+ acpi_write_pm1_control(facp, pm1_cntr);
}
- clear_bm_activity();
+ clear_bm_activity(facp);
}
+/* The ACPI timer is just the low 24 bits */
+#define TIME_BEGIN(tmr) inl(tmr)
+#define TIME_END(tmr, begin) ((inl(tmr) - (begin)) & 0x00ffffff)
+
+
/*
* Idle loop (uniprocessor only)
*/
static void acpi_idle_handler(void)
{
static int sleep_level = 1;
+ struct acpi_facp *facp = acpi_facp;
- if (!acpi_facp->pm_tmr || !acpi_p_blk)
+ if (!facp || !facp->pm_tmr || !acpi_p_blk)
goto not_initialized;
/*
@@ -687,7 +712,7 @@ static void acpi_idle_handler(void)
*/
if (sleep_level == 1)
goto sleep1;
- if (sleep_level == 2 || bm_activity())
+ if (sleep_level == 2)
goto sleep2;
sleep3:
sleep_level = 3;
@@ -695,37 +720,53 @@ sleep3:
printk("ACPI C3 works\n");
acpi_p_lvl3_tested = 1;
}
- wake_on_busmaster();
- if (acpi_facp->pm2_cnt)
+ wake_on_busmaster(facp);
+ if (facp->pm2_cnt)
goto sleep3_with_arbiter;
for (;;) {
unsigned long time;
+ unsigned int pm_tmr = facp->pm_tmr;
+
__cli();
if (current->need_resched)
goto out;
- time = inl(acpi_facp->pm_tmr);
+ if (bm_activity(facp))
+ goto sleep2;
+
+ time = TIME_BEGIN(pm_tmr);
inb(acpi_p_blk + ACPI_P_LVL3);
- time = inl(acpi_facp->pm_tmr) - time;
+ inl(pm_tmr); /* Dummy read, force synchronization with the PMU */
+ time = TIME_END(pm_tmr, time);
+
__sti();
- if (time > acpi_p_lvl3_lat || bm_activity())
+ if (time < acpi_p_lvl3_lat)
goto sleep2;
}
sleep3_with_arbiter:
for (;;) {
unsigned long time;
- unsigned int pm2_cntr = acpi_facp->pm2_cnt;
+ u8 arbiter;
+ unsigned int pm2_cntr = facp->pm2_cnt;
+ unsigned int pm_tmr = facp->pm_tmr;
+
__cli();
if (current->need_resched)
goto out;
- time = inl(acpi_facp->pm_tmr);
- outb(inb(pm2_cntr) | ACPI_ARB_DIS, pm2_cntr);
+ if (bm_activity(facp))
+ goto sleep2;
+
+ time = TIME_BEGIN(pm_tmr);
+ arbiter = inb(pm2_cntr) & ~ACPI_ARB_DIS;
+ outb(arbiter | ACPI_ARB_DIS, pm2_cntr); /* Disable arbiter, park on CPU */
inb(acpi_p_blk + ACPI_P_LVL3);
- outb(inb(pm2_cntr) & ~ACPI_ARB_DIS, pm2_cntr);
- time = inl(acpi_facp->pm_tmr) - time;
+ inl(pm_tmr); /* Dummy read, force synchronization with the PMU */
+ time = TIME_END(pm_tmr, time);
+ outb(arbiter, pm2_cntr); /* Enable arbiter again.. */
+
__sti();
- if (time > acpi_p_lvl3_lat || bm_activity())
+ if (time < acpi_p_lvl3_lat)
goto sleep2;
}
@@ -735,38 +776,45 @@ sleep2:
printk("ACPI C2 works\n");
acpi_p_lvl2_tested = 1;
}
- wake_on_busmaster(); /* Required to track BM activity.. */
+ wake_on_busmaster(facp); /* Required to track BM activity.. */
for (;;) {
unsigned long time;
+ unsigned int pm_tmr = facp->pm_tmr;
+
__cli();
if (current->need_resched)
goto out;
- time = inl(acpi_facp->pm_tmr);
+
+ time = TIME_BEGIN(pm_tmr);
inb(acpi_p_blk + ACPI_P_LVL2);
- time = inl(acpi_facp->pm_tmr) - time;
+ inl(pm_tmr); /* Dummy read, force synchronization with the PMU */
+ time = TIME_END(pm_tmr, time);
+
__sti();
- if (time > acpi_p_lvl2_lat)
+ if (time < acpi_p_lvl2_lat)
goto sleep1;
- if (bm_activity()) {
- clear_bm_activity();
+ if (bm_activity(facp)) {
+ clear_bm_activity(facp);
continue;
}
- if (time < acpi_enter_lvl3_lat)
+ if (time > acpi_enter_lvl3_lat)
goto sleep3;
}
sleep1:
sleep_level = 1;
- sleep_on_busmaster();
+ sleep_on_busmaster(facp);
for (;;) {
unsigned long time;
+ unsigned int pm_tmr = facp->pm_tmr;
+
__cli();
if (current->need_resched)
goto out;
- time = inl(acpi_facp->pm_tmr);
+ time = TIME_BEGIN(pm_tmr);
__asm__ __volatile__("sti ; hlt": : :"memory");
- time = inl(acpi_facp->pm_tmr) - time;
- if (time < acpi_enter_lvl2_lat)
+ time = TIME_END(pm_tmr, time);
+ if (time > acpi_enter_lvl2_lat)
goto sleep2;
}
@@ -1221,7 +1269,7 @@ static int __init acpi_init(void)
* do this with multiple CPU's, we'd need a per-CPU ACPI
* device..
*/
-#ifdef __SMP__
+#ifdef CONFIG_SMP
if (smp_num_cpus > 1)
return 0;
#endif
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
new file mode 100644
index 000000000..b8bca05c6
--- /dev/null
+++ b/arch/i386/kernel/apic.c
@@ -0,0 +1,656 @@
+/*
+ * Local APIC handling, local APIC timers
+ *
+ * (c) 1999, 2000 Ingo Molnar <mingo@redhat.com>
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+
+#include <linux/mm.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/smp_lock.h>
+#include <linux/interrupt.h>
+#include <linux/mc146818rtc.h>
+#include <linux/kernel_stat.h>
+
+#include <asm/smp.h>
+#include <asm/mtrr.h>
+#include <asm/mpspec.h>
+#include <asm/pgalloc.h>
+
+int prof_multiplier[NR_CPUS] = { 1, };
+int prof_old_multiplier[NR_CPUS] = { 1, };
+int prof_counter[NR_CPUS] = { 1, };
+
+/*
+ * IA s/w dev Vol 3, Section 7.4
+ */
+#define APIC_DEFAULT_PHYS_BASE 0xfee00000
+
+int get_maxlvt(void)
+{
+ unsigned int v, ver, maxlvt;
+
+ v = apic_read(APIC_LVR);
+ ver = GET_APIC_VERSION(v);
+ /* 82489DXs do not report # of LVT entries. */
+ maxlvt = APIC_INTEGRATED(ver) ? GET_APIC_MAXLVT(v) : 2;
+ return maxlvt;
+}
+
+void disable_local_APIC (void)
+{
+ unsigned long value;
+ int maxlvt;
+
+ /*
+ * Disable APIC
+ */
+ value = apic_read(APIC_SPIV);
+ value &= ~(1<<8);
+ apic_write(APIC_SPIV,value);
+
+ /*
+ * Clean APIC state for other OSs:
+ */
+ value = apic_read(APIC_SPIV);
+ value &= ~(1<<8);
+ apic_write(APIC_SPIV,value);
+ maxlvt = get_maxlvt();
+ apic_write_around(APIC_LVTT, 0x00010000);
+ apic_write_around(APIC_LVT0, 0x00010000);
+ apic_write_around(APIC_LVT1, 0x00010000);
+ if (maxlvt >= 3)
+ apic_write_around(APIC_LVTERR, 0x00010000);
+ if (maxlvt >= 4)
+ apic_write_around(APIC_LVTPC, 0x00010000);
+}
+
+extern void __error_in_apic_c (void);
+
+void __init setup_local_APIC (void)
+{
+ unsigned long value, ver, maxlvt;
+
+ if ((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f)
+ __error_in_apic_c();
+
+ /*
+ * Double-check wether this APIC is really registered.
+ */
+ if (!test_bit(GET_APIC_ID(apic_read(APIC_ID)), &phys_cpu_present_map))
+ BUG();
+
+ value = apic_read(APIC_SPIV);
+ /*
+ * Enable APIC
+ */
+ value |= (1<<8);
+
+ /*
+ * Some unknown Intel IO/APIC (or APIC) errata is biting us with
+ * certain networking cards. If high frequency interrupts are
+ * happening on a particular IOAPIC pin, plus the IOAPIC routing
+ * entry is masked/unmasked at a high rate as well then sooner or
+ * later IOAPIC line gets 'stuck', no more interrupts are received
+ * from the device. If focus CPU is disabled then the hang goes
+ * away, oh well :-(
+ *
+ * [ This bug can be reproduced easily with a level-triggered
+ * PCI Ne2000 networking cards and PII/PIII processors, dual
+ * BX chipset. ]
+ */
+#if 0
+ /* Enable focus processor (bit==0) */
+ value &= ~(1<<9);
+#else
+ /* Disable focus processor (bit==1) */
+ value |= (1<<9);
+#endif
+ /*
+ * Set spurious IRQ vector
+ */
+ value |= SPURIOUS_APIC_VECTOR;
+ apic_write(APIC_SPIV,value);
+
+ /*
+ * Set up LVT0, LVT1:
+ *
+ * set up through-local-APIC on the BP's LINT0. This is not
+ * strictly necessery in pure symmetric-IO mode, but sometimes
+ * we delegate interrupts to the 8259A.
+ */
+ if (!smp_processor_id()) {
+ value = 0x00000700;
+ printk("enabled ExtINT on CPU#%d\n", smp_processor_id());
+ } else {
+ value = 0x00010700;
+ printk("masked ExtINT on CPU#%d\n", smp_processor_id());
+ }
+ apic_write_around(APIC_LVT0,value);
+
+ /*
+ * only the BP should see the LINT1 NMI signal, obviously.
+ */
+ if (!smp_processor_id())
+ value = 0x00000400; // unmask NMI
+ else
+ value = 0x00010400; // mask NMI
+ apic_write_around(APIC_LVT1,value);
+
+ value = apic_read(APIC_LVR);
+ ver = GET_APIC_VERSION(value);
+ if (APIC_INTEGRATED(ver)) { /* !82489DX */
+ maxlvt = get_maxlvt();
+ /*
+ * Due to the Pentium erratum 3AP.
+ */
+ if (maxlvt > 3) {
+ apic_readaround(APIC_SPIV); // not strictly necessery
+ apic_write(APIC_ESR, 0);
+ }
+ value = apic_read(APIC_ESR);
+ printk("ESR value before enabling vector: %08lx\n", value);
+
+ value = apic_read(APIC_LVTERR);
+ value = ERROR_APIC_VECTOR; // enables sending errors
+ apic_write(APIC_LVTERR,value);
+ /*
+ * spec says clear errors after enabling vector.
+ */
+ if (maxlvt != 3) {
+ apic_readaround(APIC_SPIV);
+ apic_write(APIC_ESR, 0);
+ }
+ value = apic_read(APIC_ESR);
+ printk("ESR value after enabling vector: %08lx\n", value);
+ } else
+ printk("No ESR for 82489DX.\n");
+
+ /*
+ * Set Task Priority to 'accept all'. We never change this
+ * later on.
+ */
+ value = apic_read(APIC_TASKPRI);
+ value &= ~APIC_TPRI_MASK;
+ apic_write(APIC_TASKPRI,value);
+
+ /*
+ * Set up the logical destination ID and put the
+ * APIC into flat delivery mode.
+ */
+ value = apic_read(APIC_LDR);
+ value &= ~APIC_LDR_MASK;
+ value |= (1<<(smp_processor_id()+24));
+ apic_write(APIC_LDR,value);
+
+ value = apic_read(APIC_DFR);
+ value |= SET_APIC_DFR(0xf);
+ apic_write(APIC_DFR, value);
+}
+
+void __init init_apic_mappings(void)
+{
+ unsigned long apic_phys;
+
+ if (smp_found_config) {
+ apic_phys = mp_lapic_addr;
+ } else {
+ /*
+ * set up a fake all zeroes page to simulate the
+ * local APIC and another one for the IO-APIC. We
+ * could use the real zero-page, but it's safer
+ * this way if some buggy code writes to this page ...
+ */
+ apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
+ apic_phys = __pa(apic_phys);
+ }
+ set_fixmap_nocache(FIX_APIC_BASE, apic_phys);
+ Dprintk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys);
+
+#ifdef CONFIG_X86_IO_APIC
+ {
+ unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
+ int i;
+
+ for (i = 0; i < nr_ioapics; i++) {
+ if (smp_found_config) {
+ ioapic_phys = mp_ioapics[i].mpc_apicaddr;
+ } else {
+ ioapic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
+ ioapic_phys = __pa(ioapic_phys);
+ }
+ set_fixmap_nocache(idx, ioapic_phys);
+ Dprintk("mapped IOAPIC to %08lx (%08lx)\n",
+ __fix_to_virt(idx), ioapic_phys);
+ idx++;
+ }
+ }
+#endif
+}
+
+/*
+ * This part sets up the APIC 32 bit clock in LVTT1, with HZ interrupts
+ * per second. We assume that the caller has already set up the local
+ * APIC.
+ *
+ * The APIC timer is not exactly sync with the external timer chip, it
+ * closely follows bus clocks.
+ */
+
+/*
+ * The timer chip is already set up at HZ interrupts per second here,
+ * but we do not accept timer interrupts yet. We only allow the BP
+ * to calibrate.
+ */
+static unsigned int __init get_8254_timer_count(void)
+{
+ extern rwlock_t xtime_lock;
+ unsigned long flags;
+
+ unsigned int count;
+
+ write_lock_irqsave(&xtime_lock, flags);
+
+ outb_p(0x00, 0x43);
+ count = inb_p(0x40);
+ count |= inb_p(0x40) << 8;
+
+ write_unlock_irqrestore(&xtime_lock, flags);
+
+ return count;
+}
+
+void __init wait_8254_wraparound(void)
+{
+ unsigned int curr_count, prev_count=~0;
+ int delta;
+
+ curr_count = get_8254_timer_count();
+
+ do {
+ prev_count = curr_count;
+ curr_count = get_8254_timer_count();
+ delta = curr_count-prev_count;
+
+ /*
+ * This limit for delta seems arbitrary, but it isn't, it's
+ * slightly above the level of error a buggy Mercury/Neptune
+ * chipset timer can cause.
+ */
+
+ } while (delta<300);
+}
+
+/*
+ * This function sets up the local APIC timer, with a timeout of
+ * 'clocks' APIC bus clock. During calibration we actually call
+ * this function twice on the boot CPU, once with a bogus timeout
+ * value, second time for real. The other (noncalibrating) CPUs
+ * call this function only once, with the real, calibrated value.
+ *
+ * We do reads before writes even if unnecessary, to get around the
+ * P5 APIC double write bug.
+ */
+
+#define APIC_DIVISOR 16
+
+void __setup_APIC_LVTT(unsigned int clocks)
+{
+ unsigned int lvtt1_value, tmp_value;
+
+ tmp_value = apic_read(APIC_LVTT);
+ lvtt1_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) |
+ APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR;
+ apic_write(APIC_LVTT, lvtt1_value);
+
+ /*
+ * Divide PICLK by 16
+ */
+ tmp_value = apic_read(APIC_TDCR);
+ apic_write(APIC_TDCR, (tmp_value
+ & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
+ | APIC_TDR_DIV_16);
+
+ tmp_value = apic_read(APIC_TMICT);
+ apic_write(APIC_TMICT, clocks/APIC_DIVISOR);
+}
+
+void setup_APIC_timer(void * data)
+{
+ unsigned int clocks = (unsigned int) data, slice, t0, t1;
+ unsigned long flags;
+ int delta;
+
+ __save_flags(flags);
+ __sti();
+ /*
+ * ok, Intel has some smart code in their APIC that knows
+ * if a CPU was in 'hlt' lowpower mode, and this increases
+ * its APIC arbitration priority. To avoid the external timer
+ * IRQ APIC event being in synchron with the APIC clock we
+ * introduce an interrupt skew to spread out timer events.
+ *
+ * The number of slices within a 'big' timeslice is smp_num_cpus+1
+ */
+
+ slice = clocks / (smp_num_cpus+1);
+ printk("cpu: %d, clocks: %d, slice: %d\n",
+ smp_processor_id(), clocks, slice);
+
+ /*
+ * Wait for IRQ0's slice:
+ */
+ wait_8254_wraparound();
+
+ __setup_APIC_LVTT(clocks);
+
+ t0 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
+ do {
+ t1 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
+ delta = (int)(t0 - t1 - slice*(smp_processor_id()+1));
+ } while (delta < 0);
+
+ __setup_APIC_LVTT(clocks);
+
+ printk("CPU%d<C0:%d,C:%d,D:%d,S:%d,C:%d>\n",
+ smp_processor_id(), t0, t1, delta, slice, clocks);
+
+ __restore_flags(flags);
+}
+
+/*
+ * In this function we calibrate APIC bus clocks to the external
+ * timer. Unfortunately we cannot use jiffies and the timer irq
+ * to calibrate, since some later bootup code depends on getting
+ * the first irq? Ugh.
+ *
+ * We want to do the calibration only once since we
+ * want to have local timer irqs syncron. CPUs connected
+ * by the same APIC bus have the very same bus frequency.
+ * And we want to have irqs off anyways, no accidental
+ * APIC irq that way.
+ */
+
+int __init calibrate_APIC_clock(void)
+{
+ unsigned long long t1 = 0, t2 = 0;
+ long tt1, tt2;
+ long result;
+ int i;
+ const int LOOPS = HZ/10;
+
+ printk("calibrating APIC timer ... ");
+
+ /*
+ * Put whatever arbitrary (but long enough) timeout
+ * value into the APIC clock, we just want to get the
+ * counter running for calibration.
+ */
+ __setup_APIC_LVTT(1000000000);
+
+ /*
+ * The timer chip counts down to zero. Let's wait
+ * for a wraparound to start exact measurement:
+ * (the current tick might have been already half done)
+ */
+
+ wait_8254_wraparound();
+
+ /*
+ * We wrapped around just now. Let's start:
+ */
+ if (cpu_has_tsc)
+ rdtscll(t1);
+ tt1 = apic_read(APIC_TMCCT);
+
+ /*
+ * Let's wait LOOPS wraprounds:
+ */
+ for (i = 0; i < LOOPS; i++)
+ wait_8254_wraparound();
+
+ tt2 = apic_read(APIC_TMCCT);
+ if (cpu_has_tsc)
+ rdtscll(t2);
+
+ /*
+ * The APIC bus clock counter is 32 bits only, it
+ * might have overflown, but note that we use signed
+ * longs, thus no extra care needed.
+ *
+ * underflown to be exact, as the timer counts down ;)
+ */
+
+ result = (tt1-tt2)*APIC_DIVISOR/LOOPS;
+
+ if (cpu_has_tsc)
+ printk("\n..... CPU clock speed is %ld.%04ld MHz.\n",
+ ((long)(t2-t1)/LOOPS)/(1000000/HZ),
+ ((long)(t2-t1)/LOOPS)%(1000000/HZ));
+
+ printk("..... host bus clock speed is %ld.%04ld MHz.\n",
+ result/(1000000/HZ),
+ result%(1000000/HZ));
+
+ return result;
+}
+
+static unsigned int calibration_result;
+
+void __init setup_APIC_clocks (void)
+{
+ __cli();
+
+ calibration_result = calibrate_APIC_clock();
+ /*
+ * Now set up the timer for real.
+ */
+ setup_APIC_timer((void *)calibration_result);
+
+ __sti();
+
+ /* and update all other cpus */
+ smp_call_function(setup_APIC_timer, (void *)calibration_result, 1, 1);
+}
+
+/*
+ * the frequency of the profiling timer can be changed
+ * by writing a multiplier value into /proc/profile.
+ */
+int setup_profiling_timer(unsigned int multiplier)
+{
+ int i;
+
+ /*
+ * Sanity check. [at least 500 APIC cycles should be
+ * between APIC interrupts as a rule of thumb, to avoid
+ * irqs flooding us]
+ */
+ if ( (!multiplier) || (calibration_result/multiplier < 500))
+ return -EINVAL;
+
+ /*
+ * Set the new multiplier for each CPU. CPUs don't start using the
+ * new values until the next timer interrupt in which they do process
+ * accounting. At that time they also adjust their APIC timers
+ * accordingly.
+ */
+ for (i = 0; i < NR_CPUS; ++i)
+ prof_multiplier[i] = multiplier;
+
+ return 0;
+}
+
+#undef APIC_DIVISOR
+
+/*
+ * Local timer interrupt handler. It does both profiling and
+ * process statistics/rescheduling.
+ *
+ * We do profiling in every local tick, statistics/rescheduling
+ * happen only every 'profiling multiplier' ticks. The default
+ * multiplier is 1 and it can be changed by writing the new multiplier
+ * value into /proc/profile.
+ */
+
+inline void smp_local_timer_interrupt(struct pt_regs * regs)
+{
+ int user = (user_mode(regs) != 0);
+ int cpu = smp_processor_id();
+
+ /*
+ * The profiling function is SMP safe. (nothing can mess
+ * around with "current", and the profiling counters are
+ * updated with atomic operations). This is especially
+ * useful with a profiling multiplier != 1
+ */
+ if (!user)
+ x86_do_profile(regs->eip);
+
+ if (--prof_counter[cpu] <= 0) {
+ int system = 1 - user;
+ struct task_struct * p = current;
+
+ /*
+ * The multiplier may have changed since the last time we got
+ * to this point as a result of the user writing to
+ * /proc/profile. In this case we need to adjust the APIC
+ * timer accordingly.
+ *
+ * Interrupts are already masked off at this point.
+ */
+ prof_counter[cpu] = prof_multiplier[cpu];
+ if (prof_counter[cpu] != prof_old_multiplier[cpu]) {
+ __setup_APIC_LVTT(calibration_result/prof_counter[cpu]);
+ prof_old_multiplier[cpu] = prof_counter[cpu];
+ }
+
+ /*
+ * After doing the above, we need to make like
+ * a normal interrupt - otherwise timer interrupts
+ * ignore the global interrupt lock, which is the
+ * WrongThing (tm) to do.
+ */
+
+ irq_enter(cpu, 0);
+ update_one_process(p, 1, user, system, cpu);
+ if (p->pid) {
+ p->counter -= 1;
+ if (p->counter <= 0) {
+ p->counter = 0;
+ p->need_resched = 1;
+ }
+ if (p->priority < DEF_PRIORITY) {
+ kstat.cpu_nice += user;
+ kstat.per_cpu_nice[cpu] += user;
+ } else {
+ kstat.cpu_user += user;
+ kstat.per_cpu_user[cpu] += user;
+ }
+ kstat.cpu_system += system;
+ kstat.per_cpu_system[cpu] += system;
+
+ }
+ irq_exit(cpu, 0);
+ }
+
+ /*
+ * We take the 'long' return path, and there every subsystem
+ * grabs the apropriate locks (kernel lock/ irq lock).
+ *
+ * we might want to decouple profiling from the 'long path',
+ * and do the profiling totally in assembly.
+ *
+ * Currently this isn't too much of an issue (performance wise),
+ * we can take more than 100K local irqs per second on a 100 MHz P5.
+ */
+}
+
+/*
+ * Local APIC timer interrupt. This is the most natural way for doing
+ * local interrupts, but local timer interrupts can be emulated by
+ * broadcast interrupts too. [in case the hw doesnt support APIC timers]
+ *
+ * [ if a single-CPU system runs an SMP kernel then we call the local
+ * interrupt as well. Thus we cannot inline the local irq ... ]
+ */
+unsigned int apic_timer_irqs [NR_CPUS] = { 0, };
+
+void smp_apic_timer_interrupt(struct pt_regs * regs)
+{
+ /*
+ * the NMI deadlock-detector uses this.
+ */
+ apic_timer_irqs[smp_processor_id()]++;
+
+ /*
+ * NOTE! We'd better ACK the irq immediately,
+ * because timer handling can be slow.
+ */
+ ack_APIC_irq();
+ smp_local_timer_interrupt(regs);
+}
+
+/*
+ * This interrupt should _never_ happen with our APIC/SMP architecture
+ */
+asmlinkage void smp_spurious_interrupt(void)
+{
+ ack_APIC_irq();
+ /* see sw-dev-man vol 3, chapter 7.4.13.5 */
+ printk("spurious APIC interrupt on CPU#%d, should never happen.\n",
+ smp_processor_id());
+}
+
+/*
+ * This interrupt should never happen with our APIC/SMP architecture
+ */
+
+static spinlock_t err_lock = SPIN_LOCK_UNLOCKED;
+
+asmlinkage void smp_error_interrupt(void)
+{
+ unsigned long v;
+
+ spin_lock(&err_lock);
+
+ v = apic_read(APIC_ESR);
+ printk("APIC error interrupt on CPU#%d, should never happen.\n",
+ smp_processor_id());
+ printk("... APIC ESR0: %08lx\n", v);
+
+ apic_write(APIC_ESR, 0);
+ v |= apic_read(APIC_ESR);
+ printk("... APIC ESR1: %08lx\n", v);
+ /*
+ * Be a bit more verbose. (multiple bits can be set)
+ */
+ if (v & 0x01)
+ printk("... bit 0: APIC Send CS Error (hw problem).\n");
+ if (v & 0x02)
+ printk("... bit 1: APIC Receive CS Error (hw problem).\n");
+ if (v & 0x04)
+ printk("... bit 2: APIC Send Accept Error.\n");
+ if (v & 0x08)
+ printk("... bit 3: APIC Receive Accept Error.\n");
+ if (v & 0x10)
+ printk("... bit 4: Reserved!.\n");
+ if (v & 0x20)
+ printk("... bit 5: Send Illegal Vector (kernel bug).\n");
+ if (v & 0x40)
+ printk("... bit 6: Received Illegal Vector.\n");
+ if (v & 0x80)
+ printk("... bit 7: Illegal Register Address.\n");
+
+ ack_APIC_irq();
+
+ irq_err_count++;
+
+ spin_unlock(&err_lock);
+}
+
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index ecfe0697d..e91602aba 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -416,15 +416,15 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_time)
.long SYMBOL_NAME(sys_mknod)
.long SYMBOL_NAME(sys_chmod) /* 15 */
- .long SYMBOL_NAME(sys_lchown)
+ .long SYMBOL_NAME(sys_lchown16)
.long SYMBOL_NAME(sys_ni_syscall) /* old break syscall holder */
.long SYMBOL_NAME(sys_stat)
.long SYMBOL_NAME(sys_lseek)
.long SYMBOL_NAME(sys_getpid) /* 20 */
.long SYMBOL_NAME(sys_mount)
.long SYMBOL_NAME(sys_oldumount)
- .long SYMBOL_NAME(sys_setuid)
- .long SYMBOL_NAME(sys_getuid)
+ .long SYMBOL_NAME(sys_setuid16)
+ .long SYMBOL_NAME(sys_getuid16)
.long SYMBOL_NAME(sys_stime) /* 25 */
.long SYMBOL_NAME(sys_ptrace)
.long SYMBOL_NAME(sys_alarm)
@@ -446,11 +446,11 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_times)
.long SYMBOL_NAME(sys_ni_syscall) /* old prof syscall holder */
.long SYMBOL_NAME(sys_brk) /* 45 */
- .long SYMBOL_NAME(sys_setgid)
- .long SYMBOL_NAME(sys_getgid)
+ .long SYMBOL_NAME(sys_setgid16)
+ .long SYMBOL_NAME(sys_getgid16)
.long SYMBOL_NAME(sys_signal)
- .long SYMBOL_NAME(sys_geteuid)
- .long SYMBOL_NAME(sys_getegid) /* 50 */
+ .long SYMBOL_NAME(sys_geteuid16)
+ .long SYMBOL_NAME(sys_getegid16) /* 50 */
.long SYMBOL_NAME(sys_acct)
.long SYMBOL_NAME(sys_umount) /* recycled never used phys() */
.long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */
@@ -470,8 +470,8 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_sigaction)
.long SYMBOL_NAME(sys_sgetmask)
.long SYMBOL_NAME(sys_ssetmask)
- .long SYMBOL_NAME(sys_setreuid) /* 70 */
- .long SYMBOL_NAME(sys_setregid)
+ .long SYMBOL_NAME(sys_setreuid16) /* 70 */
+ .long SYMBOL_NAME(sys_setregid16)
.long SYMBOL_NAME(sys_sigsuspend)
.long SYMBOL_NAME(sys_sigpending)
.long SYMBOL_NAME(sys_sethostname)
@@ -480,8 +480,8 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_getrusage)
.long SYMBOL_NAME(sys_gettimeofday)
.long SYMBOL_NAME(sys_settimeofday)
- .long SYMBOL_NAME(sys_getgroups) /* 80 */
- .long SYMBOL_NAME(sys_setgroups)
+ .long SYMBOL_NAME(sys_getgroups16) /* 80 */
+ .long SYMBOL_NAME(sys_setgroups16)
.long SYMBOL_NAME(old_select)
.long SYMBOL_NAME(sys_symlink)
.long SYMBOL_NAME(sys_lstat)
@@ -495,7 +495,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_truncate)
.long SYMBOL_NAME(sys_ftruncate)
.long SYMBOL_NAME(sys_fchmod)
- .long SYMBOL_NAME(sys_fchown) /* 95 */
+ .long SYMBOL_NAME(sys_fchown16) /* 95 */
.long SYMBOL_NAME(sys_getpriority)
.long SYMBOL_NAME(sys_setpriority)
.long SYMBOL_NAME(sys_ni_syscall) /* old profil syscall holder */
@@ -538,8 +538,8 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_sysfs) /* 135 */
.long SYMBOL_NAME(sys_personality)
.long SYMBOL_NAME(sys_ni_syscall) /* for afs_syscall */
- .long SYMBOL_NAME(sys_setfsuid)
- .long SYMBOL_NAME(sys_setfsgid)
+ .long SYMBOL_NAME(sys_setfsuid16)
+ .long SYMBOL_NAME(sys_setfsgid16)
.long SYMBOL_NAME(sys_llseek) /* 140 */
.long SYMBOL_NAME(sys_getdents)
.long SYMBOL_NAME(sys_select)
@@ -564,14 +564,14 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_sched_rr_get_interval)
.long SYMBOL_NAME(sys_nanosleep)
.long SYMBOL_NAME(sys_mremap)
- .long SYMBOL_NAME(sys_setresuid)
- .long SYMBOL_NAME(sys_getresuid) /* 165 */
+ .long SYMBOL_NAME(sys_setresuid16)
+ .long SYMBOL_NAME(sys_getresuid16) /* 165 */
.long SYMBOL_NAME(sys_vm86)
.long SYMBOL_NAME(sys_query_module)
.long SYMBOL_NAME(sys_poll)
.long SYMBOL_NAME(sys_nfsservctl)
- .long SYMBOL_NAME(sys_setresgid) /* 170 */
- .long SYMBOL_NAME(sys_getresgid)
+ .long SYMBOL_NAME(sys_setresgid16) /* 170 */
+ .long SYMBOL_NAME(sys_getresgid16)
.long SYMBOL_NAME(sys_prctl)
.long SYMBOL_NAME(sys_rt_sigreturn)
.long SYMBOL_NAME(sys_rt_sigaction)
@@ -582,7 +582,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_rt_sigsuspend)
.long SYMBOL_NAME(sys_pread) /* 180 */
.long SYMBOL_NAME(sys_pwrite)
- .long SYMBOL_NAME(sys_chown)
+ .long SYMBOL_NAME(sys_chown16)
.long SYMBOL_NAME(sys_getcwd)
.long SYMBOL_NAME(sys_capget)
.long SYMBOL_NAME(sys_capset) /* 185 */
@@ -598,6 +598,25 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_stat64) /* 195 */
.long SYMBOL_NAME(sys_lstat64)
.long SYMBOL_NAME(sys_fstat64)
+ .long SYMBOL_NAME(sys_lchown)
+ .long SYMBOL_NAME(sys_getuid)
+ .long SYMBOL_NAME(sys_getgid) /* 200 */
+ .long SYMBOL_NAME(sys_geteuid)
+ .long SYMBOL_NAME(sys_getegid)
+ .long SYMBOL_NAME(sys_setreuid)
+ .long SYMBOL_NAME(sys_setregid)
+ .long SYMBOL_NAME(sys_getgroups) /* 205 */
+ .long SYMBOL_NAME(sys_setgroups)
+ .long SYMBOL_NAME(sys_fchown)
+ .long SYMBOL_NAME(sys_setresuid)
+ .long SYMBOL_NAME(sys_getresuid)
+ .long SYMBOL_NAME(sys_setresgid) /* 210 */
+ .long SYMBOL_NAME(sys_getresgid)
+ .long SYMBOL_NAME(sys_chown)
+ .long SYMBOL_NAME(sys_setuid)
+ .long SYMBOL_NAME(sys_setgid)
+ .long SYMBOL_NAME(sys_setfsuid) /* 215 */
+ .long SYMBOL_NAME(sys_setfsgid)
/*
@@ -606,6 +625,6 @@ ENTRY(sys_call_table)
* entries. Don't panic if you notice that this hasn't
* been shrunk every time we add a new system call.
*/
- .rept NR_syscalls-197
+ .rept NR_syscalls-216
.long SYMBOL_NAME(sys_ni_syscall)
.endr
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index 9f75d94bf..2df82ff21 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -23,7 +23,7 @@
extern void dump_thread(struct pt_regs *, struct user *);
extern int dump_fpu(elf_fpregset_t *);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
#endif
@@ -92,13 +92,10 @@ EXPORT_SYMBOL(mmx_clear_page);
EXPORT_SYMBOL(mmx_copy_page);
#endif
-#ifdef __SMP__
+#ifdef CONFIG_SMP
EXPORT_SYMBOL(cpu_data);
EXPORT_SYMBOL(kernel_flag);
-EXPORT_SYMBOL(cpu_number_map);
-EXPORT_SYMBOL(__cpu_logical_map);
EXPORT_SYMBOL(smp_num_cpus);
-EXPORT_SYMBOL(cpu_present_map);
EXPORT_SYMBOL(cpu_online_map);
EXPORT_SYMBOL_NOVERS(__write_lock_failed);
EXPORT_SYMBOL_NOVERS(__read_lock_failed);
diff --git a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
index 3e9097f06..c62e5c2d2 100644
--- a/arch/i386/kernel/i8259.c
+++ b/arch/i386/kernel/i8259.c
@@ -71,17 +71,16 @@ BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd)
#undef BI
-#ifdef __SMP__
/*
* The following vectors are part of the Linux architecture, there
* is no hardware IRQ pin equivalent for them, they are triggered
* through the ICC by us (IPIs)
*/
+#ifdef CONFIG_SMP
BUILD_SMP_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
BUILD_SMP_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)
BUILD_SMP_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
-BUILD_SMP_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
-BUILD_SMP_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
+#endif
/*
* every pentium local APIC has two 'local interrupts', with a
@@ -90,8 +89,10 @@ BUILD_SMP_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
* overflow. Linux uses the local APIC timer interrupt to get
* a much simpler SMP time architecture:
*/
+#ifdef CONFIG_X86_LOCAL_APIC
BUILD_SMP_TIMER_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
-
+BUILD_SMP_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
+BUILD_SMP_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
#endif
#define IRQ(x,y) \
@@ -428,8 +429,7 @@ void __init init_IRQ(void)
set_intr_gate(vector, interrupt[i]);
}
-#ifdef __SMP__
-
+#ifdef CONFIG_SMP
/*
* IRQ0 must be given a fixed assignment and initialized,
* because it's used before the IO-APIC is set up.
@@ -445,16 +445,18 @@ void __init init_IRQ(void)
/* IPI for invalidation */
set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);
- /* self generated IPI for local APIC timer */
- set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
-
/* IPI for generic function call */
set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
+#endif
+
+#ifdef CONFIG_X86_LOCAL_APIC
+ /* self generated IPI for local APIC timer */
+ set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);
/* IPI vectors for APIC spurious and error interrupts */
set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);
set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
-#endif
+#endif
/*
* Set the clock to HZ Hz, we already have a valid
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 5ed9255f6..fdd4ecda9 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -1,7 +1,7 @@
/*
* Intel IO-APIC support for multi-Pentium hosts.
*
- * Copyright (C) 1997, 1998, 1999 Ingo Molnar, Hajnalka Szabo
+ * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar, Hajnalka Szabo
*
* Many thanks to Stig Venaas for trying out countless experimental
* patches and reporting/debugging problems patiently!
@@ -13,142 +13,35 @@
* and Ingo Molnar <mingo@redhat.com>
*/
-#include <linux/sched.h>
-#include <linux/smp_lock.h>
+#include <linux/mm.h>
+#include <linux/irq.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/sched.h>
+#include <linux/config.h>
+#include <linux/smp_lock.h>
+
#include <asm/io.h>
+#include <asm/smp.h>
#include <asm/desc.h>
-#include <linux/irq.h>
-
-#undef __init
-#define __init
-
-/*
- * volatile is justified in this case, IO-APIC register contents
- * might change spontaneously, GCC should not cache it
- */
-#define IO_APIC_BASE(idx) ((volatile int *)__fix_to_virt(FIX_IO_APIC_BASE_0 + idx))
-
-extern int nmi_watchdog;
-
-/*
- * The structure of the IO-APIC:
- */
-
-struct IO_APIC_reg_00 {
- __u32 __reserved_2 : 24,
- ID : 4,
- __reserved_1 : 4;
-} __attribute__ ((packed));
-
-struct IO_APIC_reg_01 {
- __u32 version : 8,
- __reserved_2 : 8,
- entries : 8,
- __reserved_1 : 8;
-} __attribute__ ((packed));
-
-struct IO_APIC_reg_02 {
- __u32 __reserved_2 : 24,
- arbitration : 4,
- __reserved_1 : 4;
-} __attribute__ ((packed));
-
/*
* # of IO-APICs and # of IRQ routing registers
*/
int nr_ioapics = 0;
int nr_ioapic_registers[MAX_IO_APICS];
-enum ioapic_irq_destination_types {
- dest_Fixed = 0,
- dest_LowestPrio = 1,
- dest_SMI = 2,
- dest__reserved_1 = 3,
- dest_NMI = 4,
- dest_INIT = 5,
- dest__reserved_2 = 6,
- dest_ExtINT = 7
-};
-
-struct IO_APIC_route_entry {
- __u32 vector : 8,
- delivery_mode : 3, /* 000: FIXED
- * 001: lowest prio
- * 111: ExtINT
- */
- dest_mode : 1, /* 0: physical, 1: logical */
- delivery_status : 1,
- polarity : 1,
- irr : 1,
- trigger : 1, /* 0: edge, 1: level */
- mask : 1, /* 0: enabled, 1: disabled */
- __reserved_2 : 15;
-
- union { struct { __u32
- __reserved_1 : 24,
- physical_dest : 4,
- __reserved_2 : 4;
- } physical;
-
- struct { __u32
- __reserved_1 : 24,
- logical_dest : 8;
- } logical;
- } dest;
-
-} __attribute__ ((packed));
-
-/*
- * MP-BIOS irq configuration table structures:
- */
+/* I/O APIC entries */
+struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
-struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];/* I/O APIC entries */
-int mp_irq_entries = 0; /* # of MP IRQ source entries */
+/* # of MP IRQ source entries */
struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
- /* MP IRQ source entries */
-int mpc_default_type = 0; /* non-0 if default (table-less)
- MP configuration */
-
-
-/*
- * This is performance-critical, we want to do it O(1)
- *
- * the indexing order of this array favors 1:1 mappings
- * between pins and IRQs.
- */
-static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
-{
- *IO_APIC_BASE(apic) = reg;
- return *(IO_APIC_BASE(apic)+4);
-}
-
-static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value)
-{
- *IO_APIC_BASE(apic) = reg;
- *(IO_APIC_BASE(apic)+4) = value;
-}
-
-/*
- * Re-write a value: to be used for read-modify-write
- * cycles where the read already set up the index register.
- */
-static inline void io_apic_modify(unsigned int apic, unsigned int value)
-{
- *(IO_APIC_BASE(apic)+4) = value;
-}
+/* MP IRQ source entries */
+int mp_irq_entries = 0;
-/*
- * Synchronize the IO-APIC and the CPU by doing
- * a dummy read from the IO-APIC
- */
-static inline void io_apic_sync(unsigned int apic)
-{
- (void) *(IO_APIC_BASE(apic)+4);
-}
+/* non-0 if default (table-less) MP configuration */
+int mpc_default_type = 0;
/*
* Rough estimation of how many shared IRQs there are, can
@@ -157,6 +50,13 @@ static inline void io_apic_sync(unsigned int apic)
#define MAX_PLUS_SHARED_IRQS NR_IRQS
#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
+/*
+ * This is performance-critical, we want to do it O(1)
+ *
+ * the indexing order of this array favors 1:1 mappings
+ * between pins and IRQs.
+ */
+
static struct irq_pin_list {
int apic, pin, next;
} irq_2_pin[PIN_MAP_SIZE];
@@ -239,6 +139,7 @@ static void clear_IO_APIC (void)
#define MAX_PIRQS 8
int pirq_entries [MAX_PIRQS];
int pirqs_enabled;
+int skip_ioapic_setup = 0;
static int __init ioapic_setup(char *str)
{
@@ -997,7 +898,7 @@ void disable_IO_APIC(void)
}
}
-static void __init setup_ioapic_id(void)
+static void __init setup_ioapic_default_id(void)
{
struct IO_APIC_reg_00 reg_00;
@@ -1012,7 +913,7 @@ static void __init setup_ioapic_id(void)
* system must have a unique ID or we get lots of nice
* 'stuck on smp_invalidate_needed IPI wait' messages.
*/
- if (cpu_present_map & (1<<0x2))
+ if (phys_cpu_present_map & (1<<0x2))
panic("APIC ID 2 already used");
/*
@@ -1031,6 +932,47 @@ static void __init setup_ioapic_id(void)
panic("could not set ID");
}
+/*
+ * function to set the IO-APIC physical IDs based on the
+ * values stored in the MPC table.
+ *
+ * by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999
+ */
+
+static void __init setup_ioapic_ids_from_mpc (void)
+{
+ struct IO_APIC_reg_00 reg_00;
+ int apic;
+
+ /*
+ * Set the IOAPIC ID to the value stored in the MPC table.
+ */
+ for (apic = 0; apic < nr_ioapics; apic++) {
+
+ /* Read the register 0 value */
+ *(int *)&reg_00 = io_apic_read(apic, 0);
+
+ /*
+ * Read the right value from the MPC table and
+ * write it into the ID register.
+ */
+ printk("...changing IO-APIC physical APIC ID to %d ...",
+ mp_ioapics[apic].mpc_apicid);
+
+ reg_00.ID = mp_ioapics[apic].mpc_apicid;
+ io_apic_write(apic, 0, *(int *)&reg_00);
+
+ /*
+ * Sanity check
+ */
+ *(int *)&reg_00 = io_apic_read(apic, 0);
+ if (reg_00.ID != mp_ioapics[apic].mpc_apicid)
+ panic("could not set ID!\n");
+ else
+ printk(" ok.\n");
+ }
+}
+
static void __init construct_default_ISA_mptable(void)
{
int i, pos = 0;
@@ -1071,7 +1013,7 @@ static void __init construct_default_ISA_mptable(void)
mp_irqs[0].mpc_dstirq = 2;
}
- setup_ioapic_id();
+ setup_ioapic_default_id();
}
/*
@@ -1320,6 +1262,8 @@ static inline void check_timer(void)
pin1 = find_timer_pin(mp_INT);
pin2 = find_timer_pin(mp_ExtINT);
+ printk("..TIMER: vector=%d pin1=%d pin2=%d\n", vector, pin1, pin2);
+
/*
* Ok, does IRQ0 through the IOAPIC work?
*/
@@ -1405,8 +1349,8 @@ void __init setup_IO_APIC(void)
{
enable_IO_APIC();
- printk("ENABLING IO-APIC IRQs\n");
io_apic_irqs = ~PIC_IRQS;
+ printk("ENABLING IO-APIC IRQs\n");
/*
* If there are no explicit MP IRQ entries, it's either one of the
@@ -1422,8 +1366,25 @@ void __init setup_IO_APIC(void)
* Set up the IO-APIC IRQ routing table by parsing the MP-BIOS
* mptable:
*/
+ setup_ioapic_ids_from_mpc();
setup_IO_APIC_irqs();
init_IO_APIC_traps();
check_timer();
print_IO_APIC();
}
+
+#ifndef CONFIG_SMP
+/*
+ * This initializes the IO-APIC and APIC hardware if this is
+ * a UP kernel.
+ */
+void IO_APIC_init_uniprocessor (void)
+{
+ if (!smp_found_config)
+ return;
+ phys_cpu_present_map = 0xff;
+ setup_local_APIC();
+ setup_IO_APIC();
+ setup_APIC_clocks();
+}
+#endif
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index a111eb516..317d8a8d7 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -1,8 +1,3 @@
-/* mostly architecture independent
- some moved to i8259.c
- the beautiful visws architecture code needs to be updated too.
- and, finally, the BUILD_IRQ and SMP_BUILD macros in irq.h need fixed.
- */
/*
* linux/arch/i386/kernel/irq.c
*
@@ -16,6 +11,8 @@
*/
/*
+ * (mostly architecture independent, will move to kernel/irq.c in 2.5.)
+ *
* IRQs are in fact implemented a bit like signal handlers for the kernel.
* Naturally it's not a 1:1 relation, but there are similarities.
*/
@@ -33,15 +30,16 @@
#include <linux/smp_lock.h>
#include <linux/init.h>
#include <linux/kernel_stat.h>
+#include <linux/irq.h>
-#include <asm/system.h>
#include <asm/io.h>
+#include <asm/smp.h>
+#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/pgalloc.h>
#include <asm/delay.h>
#include <asm/desc.h>
#include <asm/irq.h>
-#include <linux/irq.h>
unsigned int local_bh_count[NR_CPUS];
@@ -99,7 +97,7 @@ static void ack_none(unsigned int irq)
*/
#if CONFIG_X86
printk("unexpected IRQ trap at vector %02x\n", irq);
-#ifdef __SMP__
+#ifdef CONFIG_X86_LOCAL_APIC
/*
* Currently unexpected vectors happen only on SMP and APIC.
* We _must_ ack these because every local APIC has only N
@@ -149,7 +147,7 @@ int get_irq_list(char *buf)
if (!action)
continue;
p += sprintf(p, "%3d: ",i);
-#ifndef __SMP__
+#ifndef CONFIG_SMP
p += sprintf(p, "%10u ", kstat_irqs(i));
#else
for (j = 0; j < smp_num_cpus; j++)
@@ -186,7 +184,7 @@ int get_irq_list(char *buf)
*/
spinlock_t i386_bh_lock = SPIN_LOCK_UNLOCKED;
-#ifdef __SMP__
+#ifdef CONFIG_SMP
unsigned char global_irq_holder = NO_PROC_ID;
unsigned volatile int global_irq_lock;
atomic_t global_irq_count;
@@ -707,7 +705,7 @@ void free_irq(unsigned int irq, void *dev_id)
}
spin_unlock_irqrestore(&irq_controller_lock,flags);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/* Wait to make sure it's not being used on another CPU */
while (irq_desc[irq].status & IRQ_INPROGRESS)
barrier();
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
new file mode 100644
index 000000000..977dd18ba
--- /dev/null
+++ b/arch/i386/kernel/mpparse.c
@@ -0,0 +1,514 @@
+/*
+ * Intel Multiprocessor Specificiation 1.1 and 1.4
+ * compliant MP-table parsing routines.
+ *
+ * (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
+ * (c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com>
+ *
+ * Fixes
+ * Erich Boleyn : MP v1.4 and additional changes.
+ * Alan Cox : Added EBDA scanning
+ * Ingo Molnar : various cleanups and rewrites
+ * Maciej W. Rozycki : Bits for genuine 82489DX timers
+ */
+
+#include <linux/mm.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/config.h>
+#include <linux/bootmem.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel_stat.h>
+#include <linux/mc146818rtc.h>
+
+#include <asm/smp.h>
+#include <asm/mtrr.h>
+#include <asm/mpspec.h>
+#include <asm/pgalloc.h>
+
+/* Have we found an MP table */
+int smp_found_config = 0;
+
+/*
+ * Various Linux-internal data structures created from the
+ * MP-table.
+ */
+int apic_version [NR_CPUS];
+int mp_bus_id_to_type [MAX_MP_BUSSES] = { -1, };
+int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { -1, };
+int mp_current_pci_id = 0;
+int pic_mode;
+unsigned long mp_lapic_addr = 0;
+
+/* Processor that is doing the boot up */
+unsigned int boot_cpu_id = 0;
+/* Internal processor count */
+static unsigned int num_processors = 1;
+
+/* Bitmask of physically existing CPUs */
+unsigned long phys_cpu_present_map = 0;
+
+/*
+ * IA s/w dev Vol 3, Section 7.4
+ */
+#define APIC_DEFAULT_PHYS_BASE 0xfee00000
+
+/*
+ * Intel MP BIOS table parsing routines:
+ */
+
+#ifndef CONFIG_X86_VISWS_APIC
+/*
+ * Checksum an MP configuration block.
+ */
+
+static int __init mpf_checksum(unsigned char *mp, int len)
+{
+ int sum=0;
+ while(len--)
+ sum+=*mp++;
+ return sum&0xFF;
+}
+
+/*
+ * Processor encoding in an MP configuration block
+ */
+
+static char __init *mpc_family(int family,int model)
+{
+ static char n[32];
+ static char *model_defs[]=
+ {
+ "80486DX","80486DX",
+ "80486SX","80486DX/2 or 80487",
+ "80486SL","80486SX/2",
+ "Unknown","80486DX/2-WB",
+ "80486DX/4","80486DX/4-WB"
+ };
+
+ switch (family) {
+ case 0x04:
+ if (model < 10)
+ return model_defs[model];
+ break;
+
+ case 0x05:
+ return("Pentium(tm)");
+
+ case 0x06:
+ return("Pentium(tm) Pro");
+
+ case 0x0F:
+ if (model == 0x0F)
+ return("Special controller");
+ }
+ sprintf(n,"Unknown CPU [%d:%d]",family, model);
+ return n;
+}
+
+static void __init MP_processor_info (struct mpc_config_processor *m)
+{
+ int ver;
+
+ if (!(m->mpc_cpuflag & CPU_ENABLED))
+ return;
+
+ printk("Processor #%d %s APIC version %d\n",
+ m->mpc_apicid,
+ mpc_family( (m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
+ (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
+ m->mpc_apicver);
+
+ if (m->mpc_featureflag&(1<<0))
+ Dprintk(" Floating point unit present.\n");
+ if (m->mpc_featureflag&(1<<7))
+ Dprintk(" Machine Exception supported.\n");
+ if (m->mpc_featureflag&(1<<8))
+ Dprintk(" 64 bit compare & exchange supported.\n");
+ if (m->mpc_featureflag&(1<<9))
+ Dprintk(" Internal APIC present.\n");
+
+ if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
+ Dprintk(" Bootup CPU\n");
+ boot_cpu_id = m->mpc_apicid;
+ } else
+ /* Boot CPU already counted */
+ num_processors++;
+
+ if (m->mpc_apicid > NR_CPUS) {
+ printk("Processor #%d unused. (Max %d processors).\n",
+ m->mpc_apicid, NR_CPUS);
+ return;
+ }
+ ver = m->mpc_apicver;
+
+ phys_cpu_present_map |= 1 << m->mpc_apicid;
+ /*
+ * Validate version
+ */
+ if (ver == 0x0) {
+ printk("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
+ ver = 0x10;
+ }
+ apic_version[m->mpc_apicid] = ver;
+}
+
+static void __init MP_bus_info (struct mpc_config_bus *m)
+{
+ char str[7];
+
+ memcpy(str, m->mpc_bustype, 6);
+ str[6] = 0;
+ Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
+
+ if (strncmp(str, "ISA", 3) == 0) {
+ mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
+ } else {
+ if (strncmp(str, "EISA", 4) == 0) {
+ mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
+ } else {
+ if (strncmp(str, "PCI", 3) == 0) {
+ mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
+ mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
+ mp_current_pci_id++;
+ } else {
+ printk("Unknown bustype %s\n", str);
+ panic("cannot handle bus - mail to linux-smp@vger.rutgers.edu");
+ } } }
+}
+
+static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
+{
+ if (!(m->mpc_flags & MPC_APIC_USABLE))
+ return;
+
+ printk("I/O APIC #%d Version %d at 0x%lX.\n",
+ m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
+ if (nr_ioapics >= MAX_IO_APICS) {
+ printk("Max # of I/O APICs (%d) exceeded (found %d).\n",
+ MAX_IO_APICS, nr_ioapics);
+ panic("Recompile kernel with bigger MAX_IO_APICS!.\n");
+ }
+ mp_ioapics[nr_ioapics] = *m;
+ nr_ioapics++;
+}
+
+static void __init MP_intsrc_info (struct mpc_config_intsrc *m)
+{
+ mp_irqs [mp_irq_entries] = *m;
+ if (++mp_irq_entries == MAX_IRQ_SOURCES)
+ panic("Max # of irq sources exceeded!!\n");
+}
+
+static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
+{
+ /*
+ * Well it seems all SMP boards in existence
+ * use ExtINT/LVT1 == LINT0 and
+ * NMI/LVT2 == LINT1 - the following check
+ * will show us if this assumptions is false.
+ * Until then we do not have to add baggage.
+ */
+ if ((m->mpc_irqtype == mp_ExtINT) &&
+ (m->mpc_destapiclint != 0))
+ BUG();
+ if ((m->mpc_irqtype == mp_NMI) &&
+ (m->mpc_destapiclint != 1))
+ BUG();
+}
+
+/*
+ * Read/parse the MPC
+ */
+
+static int __init smp_read_mpc(struct mp_config_table *mpc)
+{
+ char str[16];
+ int count=sizeof(*mpc);
+ unsigned char *mpt=((unsigned char *)mpc)+count;
+
+ if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4))
+ {
+ panic("SMP mptable: bad signature [%c%c%c%c]!\n",
+ mpc->mpc_signature[0],
+ mpc->mpc_signature[1],
+ mpc->mpc_signature[2],
+ mpc->mpc_signature[3]);
+ return 1;
+ }
+ if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length))
+ {
+ panic("SMP mptable: checksum error!\n");
+ return 1;
+ }
+ if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04)
+ {
+ printk("Bad Config Table version (%d)!!\n",mpc->mpc_spec);
+ return 1;
+ }
+ memcpy(str,mpc->mpc_oem,8);
+ str[8]=0;
+ printk("OEM ID: %s ",str);
+
+ memcpy(str,mpc->mpc_productid,12);
+ str[12]=0;
+ printk("Product ID: %s ",str);
+
+ printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
+
+ /* save the local APIC address, it might be non-default */
+ mp_lapic_addr = mpc->mpc_lapic;
+
+ /*
+ * Now process the configuration blocks.
+ */
+ while (count < mpc->mpc_length) {
+ switch(*mpt) {
+ case MP_PROCESSOR:
+ {
+ struct mpc_config_processor *m=
+ (struct mpc_config_processor *)mpt;
+ MP_processor_info(m);
+ mpt += sizeof(*m);
+ count += sizeof(*m);
+ break;
+ }
+ case MP_BUS:
+ {
+ struct mpc_config_bus *m=
+ (struct mpc_config_bus *)mpt;
+ MP_bus_info(m);
+ mpt += sizeof(*m);
+ count += sizeof(*m);
+ break;
+ }
+ case MP_IOAPIC:
+ {
+ struct mpc_config_ioapic *m=
+ (struct mpc_config_ioapic *)mpt;
+ MP_ioapic_info(m);
+ mpt+=sizeof(*m);
+ count+=sizeof(*m);
+ break;
+ }
+ case MP_INTSRC:
+ {
+ struct mpc_config_intsrc *m=
+ (struct mpc_config_intsrc *)mpt;
+
+ MP_intsrc_info(m);
+ mpt+=sizeof(*m);
+ count+=sizeof(*m);
+ break;
+ }
+ case MP_LINTSRC:
+ {
+ struct mpc_config_lintsrc *m=
+ (struct mpc_config_lintsrc *)mpt;
+ MP_lintsrc_info(m);
+ mpt+=sizeof(*m);
+ count+=sizeof(*m);
+ break;
+ }
+ }
+ }
+ return num_processors;
+}
+
+/*
+ * Scan the memory blocks for an SMP configuration block.
+ */
+static int __init smp_get_mpf(struct intel_mp_floating *mpf)
+{
+ printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
+ if (mpf->mpf_feature2 & (1<<7)) {
+ printk(" IMCR and PIC compatibility mode.\n");
+ pic_mode = 1;
+ } else {
+ printk(" Virtual Wire compatibility mode.\n");
+ pic_mode = 0;
+ }
+ smp_found_config = 1;
+ /*
+ * default CPU id - if it's different in the mptable
+ * then we change it before first using it.
+ */
+ boot_cpu_id = 0;
+ /*
+ * Now see if we need to read further.
+ */
+ if (mpf->mpf_feature1 != 0) {
+ /*
+ * local APIC has default address
+ */
+ mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+
+ /*
+ * 2 CPUs, numbered 0 & 1.
+ */
+ phys_cpu_present_map = 3;
+ num_processors = 2;
+
+ nr_ioapics = 1;
+ mp_ioapics[0].mpc_apicaddr = 0xFEC00000;
+ /*
+ * Save the default type number, we
+ * need it later to set the IO-APIC
+ * up properly:
+ */
+ mpc_default_type = mpf->mpf_feature1;
+
+ printk("Bus #0 is ");
+ }
+
+ switch (mpf->mpf_feature1) {
+ case 1:
+ case 5:
+ printk("ISA\n");
+ break;
+ case 2:
+ printk("EISA with no IRQ0 and no IRQ13 DMA chaining\n");
+ break;
+ case 6:
+ case 3:
+ printk("EISA\n");
+ break;
+ case 4:
+ case 7:
+ printk("MCA\n");
+ break;
+ case 0:
+ if (!mpf->mpf_physptr)
+ BUG();
+ break;
+ default:
+ printk("???\nUnknown standard configuration %d\n",
+ mpf->mpf_feature1);
+ return 1;
+ }
+ if (mpf->mpf_feature1 > 4) {
+ printk("Bus #1 is PCI\n");
+
+ /*
+ * Set local APIC version to the integrated form.
+ * It's initialized to zero otherwise, representing
+ * a discrete 82489DX.
+ */
+ apic_version[0] = 0x10;
+ apic_version[1] = 0x10;
+ }
+ /*
+ * Read the physical hardware table. Anything here will override the
+ * defaults.
+ */
+ if (mpf->mpf_physptr)
+ smp_read_mpc((void *)mpf->mpf_physptr);
+
+ printk("Processors: %d\n", num_processors);
+ /*
+ * Only use the first configuration found.
+ */
+ return 1;
+}
+
+static int __init smp_scan_config(unsigned long base, unsigned long length)
+{
+ unsigned long *bp = phys_to_virt(base);
+ struct intel_mp_floating *mpf;
+
+ Dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
+ if (sizeof(*mpf) != 16)
+ printk("Error: MPF size\n");
+
+ while (length > 0) {
+ mpf = (struct intel_mp_floating *)bp;
+ if ((*bp == SMP_MAGIC_IDENT) &&
+ (mpf->mpf_length == 1) &&
+ !mpf_checksum((unsigned char *)bp, 16) &&
+ ((mpf->mpf_specification == 1)
+ || (mpf->mpf_specification == 4)) ) {
+
+ printk("found SMP MP-table at %08ld\n",
+ virt_to_phys(mpf));
+ smp_get_mpf(mpf);
+ return 1;
+ }
+ bp += 4;
+ length -= 16;
+ }
+ return 0;
+}
+
+void __init init_intel_smp (void)
+{
+ unsigned int address;
+
+ /*
+ * FIXME: Linux assumes you have 640K of base ram..
+ * this continues the error...
+ *
+ * 1) Scan the bottom 1K for a signature
+ * 2) Scan the top 1K of base RAM
+ * 3) Scan the 64K of bios
+ */
+ if (smp_scan_config(0x0,0x400) ||
+ smp_scan_config(639*0x400,0x400) ||
+ smp_scan_config(0xF0000,0x10000))
+ return;
+ /*
+ * If it is an SMP machine we should know now, unless the
+ * configuration is in an EISA/MCA bus machine with an
+ * extended bios data area.
+ *
+ * there is a real-mode segmented pointer pointing to the
+ * 4K EBDA area at 0x40E, calculate and scan it here.
+ *
+ * NOTE! There are Linux loaders that will corrupt the EBDA
+ * area, and as such this kind of SMP config may be less
+ * trustworthy, simply because the SMP table may have been
+ * stomped on during early boot. These loaders are buggy and
+ * should be fixed.
+ */
+
+ address = *(unsigned short *)phys_to_virt(0x40E);
+ address <<= 4;
+ smp_scan_config(address, 0x1000);
+ if (smp_found_config)
+ printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.rutgers.edu if you experience SMP problems!\n");
+}
+
+#else
+
+/*
+ * The Visual Workstation is Intel MP compliant in the hardware
+ * sense, but it doesnt have a BIOS(-configuration table).
+ * No problem for Linux.
+ */
+void __init init_visws_smp(void)
+{
+ smp_found_config = 1;
+
+ phys_cpu_present_map |= 2; /* or in id 1 */
+ apic_version[1] |= 0x10; /* integrated APIC */
+ apic_version[0] |= 0x10;
+
+ mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
+}
+
+#endif
+
+/*
+ * - Intel MP Configuration Table
+ * - or SGI Visual Workstation configuration
+ */
+void __init init_smp_config (void)
+{
+#ifdef CONFIG_X86_IO_APIC
+ init_intel_smp();
+#endif
+#ifdef CONFIG_VISWS
+ init_visws_smp();
+#endif
+}
+
diff --git a/arch/i386/kernel/pci-i386.c b/arch/i386/kernel/pci-i386.c
index e94868cd9..ee2edca1e 100644
--- a/arch/i386/kernel/pci-i386.c
+++ b/arch/i386/kernel/pci-i386.c
@@ -94,59 +94,56 @@
#include "pci-i386.h"
-/*
- * Assign new address to PCI resource. We hope our resource information
- * is complete. On the PC, we don't re-assign resources unless we are
- * forced to do so.
- *
- * Expects start=0, end=size-1, flags=resource type.
- */
-
-int pci_assign_resource(struct pci_dev *dev, int i)
+void
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+ struct resource *res, int resource)
{
- struct resource *r = &dev->resource[i];
- struct resource *pr = pci_find_parent_resource(dev, r);
- unsigned long size = r->end + 1;
u32 new, check;
+ int reg;
- if (!pr) {
- printk(KERN_ERR "PCI: Cannot find parent resource for device %s\n", dev->slot_name);
- return -EINVAL;
- }
- if (r->flags & IORESOURCE_IO) {
- /*
- * We need to avoid collisions with `mirrored' VGA ports and other strange
- * ISA hardware, so we always want the addresses kilobyte aligned.
- */
- if (size > 0x100) {
- printk(KERN_ERR "PCI: I/O Region %s/%d too large (%ld bytes)\n", dev->slot_name, i, size);
- return -EFBIG;
- }
- if (allocate_resource(pr, r, size, 0x1000, ~0, 1024, NULL, NULL)) {
- printk(KERN_ERR "PCI: Allocation of I/O region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size);
- return -EBUSY;
- }
+ new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+ if (resource < 6) {
+ reg = PCI_BASE_ADDRESS_0 + 4*resource;
+ } else if (resource == PCI_ROM_RESOURCE) {
+ res->flags |= PCI_ROM_ADDRESS_ENABLE;
+ reg = dev->rom_base_reg;
} else {
- if (allocate_resource(pr, r, size, 0x10000000, ~0, size, NULL, NULL)) {
- printk(KERN_ERR "PCI: Allocation of memory region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size);
- return -EBUSY;
- }
+ /* Somebody might have asked allocation of a non-standard resource */
+ return;
}
- if (i < 6) {
- int reg = PCI_BASE_ADDRESS_0 + 4*i;
- new = r->start | (r->flags & PCI_REGION_FLAG_MASK);
- pci_write_config_dword(dev, reg, new);
- pci_read_config_dword(dev, reg, &check);
- if (new != check)
- printk(KERN_ERR "PCI: Error while updating region %s/%d (%08x != %08x)\n", dev->slot_name, i, new, check);
- } else if (i == PCI_ROM_RESOURCE) {
- r->flags |= PCI_ROM_ADDRESS_ENABLE;
- pci_write_config_dword(dev, dev->rom_base_reg, r->start | (r->flags & PCI_REGION_FLAG_MASK));
+
+ pci_write_config_dword(dev, reg, new);
+ pci_read_config_dword(dev, reg, &check);
+ if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+ printk(KERN_ERR "PCI: Error while updating region "
+ "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+ new, check);
}
- printk("PCI: Assigned addresses %08lx-%08lx to region %s/%d\n", r->start, r->end, dev->slot_name, i);
- return 0;
}
+void
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+ struct pci_dev *dev = data;
+
+ if (res->flags & IORESOURCE_IO) {
+ unsigned long start = res->start;
+
+ /* We need to avoid collisions with `mirrored' VGA ports
+ and other strange ISA hardware, so we always want the
+ addresses kilobyte aligned. */
+ if (size >= 0x100) {
+ printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+ " (%ld bytes)\n", dev->slot_name,
+ dev->resource - res, size);
+ }
+
+ start = (start + 1024 - 1) & ~(1024 - 1);
+ res->start = start;
+ }
+}
+
+
/*
* Handle resources of PCI devices. If the world were perfect, we could
* just allocate all the resource regions and do nothing more. It isn't.
diff --git a/arch/i386/kernel/pci-pc.c b/arch/i386/kernel/pci-pc.c
index 6b7d65589..601ffd3bf 100644
--- a/arch/i386/kernel/pci-pc.c
+++ b/arch/i386/kernel/pci-pc.c
@@ -23,6 +23,7 @@
unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2;
static struct pci_bus *pci_root_bus;
+static struct pci_ops *pci_root_ops;
/*
* IRQ routing table provided by the BIOS
@@ -876,9 +877,9 @@ static void __init pci_fixup_i450nx(struct pci_dev *d)
pci_read_config_byte(d, reg++, &subb);
DBG("i450NX PXB %d: %02x/%02x/%02x\n", pxb, busno, suba, subb);
if (busno)
- pci_scan_bus(busno, pci_root_bus->ops, NULL); /* Bus A */
+ pci_scan_bus(busno, pci_root_ops, NULL); /* Bus A */
if (suba < subb)
- pci_scan_bus(suba+1, pci_root_bus->ops, NULL); /* Bus B */
+ pci_scan_bus(suba+1, pci_root_ops, NULL); /* Bus B */
}
}
@@ -891,7 +892,7 @@ static void __init pci_fixup_rcc(struct pci_dev *d)
u8 busno;
pci_read_config_byte(d, 0x44, &busno);
printk("PCI: RCC host bridge: secondary bus %02x\n", busno);
- pci_scan_bus(busno, pci_root_bus->ops, NULL);
+ pci_scan_bus(busno, pci_root_ops, NULL);
}
static void __init pci_fixup_compaq(struct pci_dev *d)
@@ -903,7 +904,7 @@ static void __init pci_fixup_compaq(struct pci_dev *d)
u8 busno;
pci_read_config_byte(d, 0xc8, &busno);
printk("PCI: Compaq host bridge: secondary bus %02x\n", busno);
- pci_scan_bus(busno, pci_root_bus->ops, NULL);
+ pci_scan_bus(busno, pci_root_ops, NULL);
}
static void __init pci_fixup_umc_ide(struct pci_dev *d)
@@ -1189,7 +1190,6 @@ void __init pcibios_init(void)
{
struct pci_ops *bios = NULL;
struct pci_ops *dir = NULL;
- struct pci_ops *ops;
#ifdef CONFIG_PCI_BIOS
if ((pci_probe & PCI_PROBE_BIOS) && ((bios = pci_find_bios()))) {
@@ -1202,16 +1202,16 @@ void __init pcibios_init(void)
dir = pci_check_direct();
#endif
if (dir)
- ops = dir;
+ pci_root_ops = dir;
else if (bios)
- ops = bios;
+ pci_root_ops = bios;
else {
printk("PCI: No PCI bus detected\n");
return;
}
printk("PCI: Probing PCI hardware\n");
- pci_root_bus = pci_scan_bus(0, ops, NULL);
+ pci_root_bus = pci_scan_bus(0, pci_root_ops, NULL);
pcibios_fixup_irqs();
if (pci_probe & PCI_PEER_FIXUP)
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 1e6576860..ed64f15a2 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -198,259 +198,242 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data)
switch (request) {
/* when I and D space are separate, these will need to be fixed. */
- case PTRACE_PEEKTEXT: /* read word at location addr. */
- case PTRACE_PEEKDATA: {
- unsigned long tmp;
- int copied;
-
- copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
- ret = -EIO;
- if (copied != sizeof(tmp))
- goto out;
- ret = put_user(tmp,(unsigned long *) data);
- goto out;
- }
+ case PTRACE_PEEKTEXT: /* read word at location addr. */
+ case PTRACE_PEEKDATA: {
+ unsigned long tmp;
+ int copied;
+
+ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+ ret = -EIO;
+ if (copied != sizeof(tmp))
+ break;
+ ret = put_user(tmp,(unsigned long *) data);
+ break;
+ }
/* read the word at location addr in the USER area. */
- case PTRACE_PEEKUSR: {
- unsigned long tmp;
+ case PTRACE_PEEKUSR: {
+ unsigned long tmp;
- ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
- goto out;
-
- tmp = 0; /* Default return condition */
- if(addr < 17*sizeof(long))
- tmp = getreg(child, addr);
- if(addr >= (long) &dummy->u_debugreg[0] &&
- addr <= (long) &dummy->u_debugreg[7]){
- addr -= (long) &dummy->u_debugreg[0];
- addr = addr >> 2;
- tmp = child->thread.debugreg[addr];
- };
- ret = put_user(tmp,(unsigned long *) data);
- goto out;
- }
+ ret = -EIO;
+ if ((addr & 3) || addr < 0 ||
+ addr > sizeof(struct user) - 3)
+ break;
- /* when I and D space are separate, this will have to be fixed. */
- case PTRACE_POKETEXT: /* write the word at location addr. */
- case PTRACE_POKEDATA:
- ret = 0;
- if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
- goto out;
- ret = -EIO;
- goto out;
+ tmp = 0; /* Default return condition */
+ if(addr < 17*sizeof(long))
+ tmp = getreg(child, addr);
+ if(addr >= (long) &dummy->u_debugreg[0] &&
+ addr <= (long) &dummy->u_debugreg[7]){
+ addr -= (long) &dummy->u_debugreg[0];
+ addr = addr >> 2;
+ tmp = child->thread.debugreg[addr];
+ }
+ ret = put_user(tmp,(unsigned long *) data);
+ break;
+ }
- case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
- ret = -EIO;
- if ((addr & 3) || addr < 0 ||
- addr > sizeof(struct user) - 3)
- goto out;
+ /* when I and D space are separate, this will have to be fixed. */
+ case PTRACE_POKETEXT: /* write the word at location addr. */
+ case PTRACE_POKEDATA:
+ ret = 0;
+ if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data))
+ break;
+ ret = -EIO;
+ break;
- if (addr < 17*sizeof(long)) {
- ret = putreg(child, addr, data);
- goto out;
- }
+ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */
+ ret = -EIO;
+ if ((addr & 3) || addr < 0 ||
+ addr > sizeof(struct user) - 3)
+ break;
- /* We need to be very careful here. We implicitly
- want to modify a portion of the task_struct, and we
- have to be selective about what portions we allow someone
- to modify. */
+ if (addr < 17*sizeof(long)) {
+ ret = putreg(child, addr, data);
+ break;
+ }
+ /* We need to be very careful here. We implicitly
+ want to modify a portion of the task_struct, and we
+ have to be selective about what portions we allow someone
+ to modify. */
+ ret = -EIO;
if(addr >= (long) &dummy->u_debugreg[0] &&
addr <= (long) &dummy->u_debugreg[7]){
- if(addr == (long) &dummy->u_debugreg[4]) return -EIO;
- if(addr == (long) &dummy->u_debugreg[5]) return -EIO;
+ if(addr == (long) &dummy->u_debugreg[4]) break;
+ if(addr == (long) &dummy->u_debugreg[5]) break;
if(addr < (long) &dummy->u_debugreg[4] &&
- ((unsigned long) data) >= TASK_SIZE-3) return -EIO;
+ ((unsigned long) data) >= TASK_SIZE-3) break;
- ret = -EIO;
if(addr == (long) &dummy->u_debugreg[7]) {
data &= ~DR_CONTROL_RESERVED;
for(i=0; i<4; i++)
if ((0x5f54 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
goto out;
- };
+ }
addr -= (long) &dummy->u_debugreg;
addr = addr >> 2;
child->thread.debugreg[addr] = data;
ret = 0;
- goto out;
- };
- ret = -EIO;
- goto out;
+ }
+ break;
- case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
- case PTRACE_CONT: { /* restart after signal. */
- long tmp;
+ case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */
+ case PTRACE_CONT: { /* restart after signal. */
+ long tmp;
- ret = -EIO;
- if ((unsigned long) data > _NSIG)
- goto out;
- if (request == PTRACE_SYSCALL)
- child->flags |= PF_TRACESYS;
- else
- child->flags &= ~PF_TRACESYS;
- child->exit_code = data;
+ ret = -EIO;
+ if ((unsigned long) data > _NSIG)
+ break;
+ if (request == PTRACE_SYSCALL)
+ child->flags |= PF_TRACESYS;
+ else
+ child->flags &= ~PF_TRACESYS;
+ child->exit_code = data;
/* make sure the single step bit is not set. */
- tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG;
- put_stack_long(child, EFL_OFFSET,tmp);
- wake_up_process(child);
- ret = 0;
- goto out;
- }
+ tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG;
+ put_stack_long(child, EFL_OFFSET,tmp);
+ wake_up_process(child);
+ ret = 0;
+ break;
+ }
/*
* make the child exit. Best I can do is send it a sigkill.
* perhaps it should be put in the status that it wants to
* exit.
*/
- case PTRACE_KILL: {
- long tmp;
+ case PTRACE_KILL: {
+ long tmp;
- ret = 0;
- if (child->state == TASK_ZOMBIE) /* already dead */
- goto out;
- child->exit_code = SIGKILL;
- /* make sure the single step bit is not set. */
- tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG;
- put_stack_long(child, EFL_OFFSET, tmp);
- wake_up_process(child);
- goto out;
+ ret = 0;
+ if (child->state == TASK_ZOMBIE) /* already dead */
+ break;
+ child->exit_code = SIGKILL;
+ /* make sure the single step bit is not set. */
+ tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG;
+ put_stack_long(child, EFL_OFFSET, tmp);
+ wake_up_process(child);
+ break;
+ }
+
+ case PTRACE_SINGLESTEP: { /* set the trap flag. */
+ long tmp;
+
+ ret = -EIO;
+ if ((unsigned long) data > _NSIG)
+ break;
+ child->flags &= ~PF_TRACESYS;
+ if ((child->flags & PF_DTRACE) == 0) {
+ /* Spurious delayed TF traps may occur */
+ child->flags |= PF_DTRACE;
}
+ tmp = get_stack_long(child, EFL_OFFSET) | TRAP_FLAG;
+ put_stack_long(child, EFL_OFFSET, tmp);
+ child->exit_code = data;
+ /* give it a chance to run. */
+ wake_up_process(child);
+ ret = 0;
+ break;
+ }
+
+ case PTRACE_DETACH: { /* detach a process that was attached. */
+ long tmp;
- case PTRACE_SINGLESTEP: { /* set the trap flag. */
- long tmp;
+ ret = -EIO;
+ if ((unsigned long) data > _NSIG)
+ break;
+ child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+ child->exit_code = data;
+ write_lock_irqsave(&tasklist_lock, flags);
+ REMOVE_LINKS(child);
+ child->p_pptr = child->p_opptr;
+ SET_LINKS(child);
+ write_unlock_irqrestore(&tasklist_lock, flags);
+ /* make sure the single step bit is not set. */
+ tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG;
+ put_stack_long(child, EFL_OFFSET, tmp);
+ wake_up_process(child);
+ ret = 0;
+ break;
+ }
+ case PTRACE_GETREGS: { /* Get all gp regs from the child. */
+ if (!access_ok(VERIFY_WRITE, (unsigned *)data, 17*sizeof(long))) {
ret = -EIO;
- if ((unsigned long) data > _NSIG)
- goto out;
- child->flags &= ~PF_TRACESYS;
- if ((child->flags & PF_DTRACE) == 0) {
- /* Spurious delayed TF traps may occur */
- child->flags |= PF_DTRACE;
- }
- tmp = get_stack_long(child, EFL_OFFSET) | TRAP_FLAG;
- put_stack_long(child, EFL_OFFSET, tmp);
- child->exit_code = data;
- /* give it a chance to run. */
- wake_up_process(child);
- ret = 0;
- goto out;
+ break;
}
+ for ( i = 0; i < 17*sizeof(long); i += sizeof(long) ) {
+ __put_user(getreg(child, i),(unsigned long *) data);
+ data += sizeof(long);
+ }
+ ret = 0;
+ break;
+ }
- case PTRACE_DETACH: { /* detach a process that was attached. */
- long tmp;
-
+ case PTRACE_SETREGS: { /* Set all gp regs in the child. */
+ unsigned long tmp;
+ if (!access_ok(VERIFY_READ, (unsigned *)data, 17*sizeof(long))) {
ret = -EIO;
- if ((unsigned long) data > _NSIG)
- goto out;
- child->flags &= ~(PF_PTRACED|PF_TRACESYS);
- child->exit_code = data;
- write_lock_irqsave(&tasklist_lock, flags);
- REMOVE_LINKS(child);
- child->p_pptr = child->p_opptr;
- SET_LINKS(child);
- write_unlock_irqrestore(&tasklist_lock, flags);
- /* make sure the single step bit is not set. */
- tmp = get_stack_long(child, EFL_OFFSET) & ~TRAP_FLAG;
- put_stack_long(child, EFL_OFFSET, tmp);
- wake_up_process(child);
- ret = 0;
- goto out;
+ break;
}
+ for ( i = 0; i < 17*sizeof(long); i += sizeof(long) ) {
+ __get_user(tmp, (unsigned long *) data);
+ putreg(child, i, tmp);
+ data += sizeof(long);
+ }
+ ret = 0;
+ break;
+ }
- case PTRACE_GETREGS: { /* Get all gp regs from the child. */
- if (!access_ok(VERIFY_WRITE, (unsigned *)data,
- 17*sizeof(long)))
- {
- ret = -EIO;
- goto out;
- }
- for ( i = 0; i < 17*sizeof(long); i += sizeof(long) )
- {
- __put_user(getreg(child, i),(unsigned long *) data);
- data += sizeof(long);
- }
- ret = 0;
- goto out;
- };
-
- case PTRACE_SETREGS: { /* Set all gp regs in the child. */
- unsigned long tmp;
- if (!access_ok(VERIFY_READ, (unsigned *)data,
- 17*sizeof(long)))
- {
- ret = -EIO;
- goto out;
- }
- for ( i = 0; i < 17*sizeof(long); i += sizeof(long) )
- {
- __get_user(tmp, (unsigned long *) data);
- putreg(child, i, tmp);
- data += sizeof(long);
- }
- ret = 0;
- goto out;
- };
-
- case PTRACE_GETFPREGS: { /* Get the child FPU state. */
- if (!access_ok(VERIFY_WRITE, (unsigned *)data,
- sizeof(struct user_i387_struct)))
- {
- ret = -EIO;
- goto out;
- }
- ret = 0;
- if ( !child->used_math ) {
- /* Simulate an empty FPU. */
- child->thread.i387.hard.cwd = 0xffff037f;
- child->thread.i387.hard.swd = 0xffff0000;
- child->thread.i387.hard.twd = 0xffffffff;
- }
+ case PTRACE_GETFPREGS: { /* Get the child FPU state. */
+ if (!access_ok(VERIFY_WRITE, (unsigned *)data, sizeof(struct user_i387_struct))) {
+ ret = -EIO;
+ break;
+ }
+ ret = 0;
+ if ( !child->used_math ) {
+ /* Simulate an empty FPU. */
+ child->thread.i387.hard.cwd = 0xffff037f;
+ child->thread.i387.hard.swd = 0xffff0000;
+ child->thread.i387.hard.twd = 0xffffffff;
+ }
#ifdef CONFIG_MATH_EMULATION
- if ( boot_cpu_data.hard_math ) {
+ if ( boot_cpu_data.hard_math ) {
#endif
- __copy_to_user((void *)data, &child->thread.i387.hard,
- sizeof(struct user_i387_struct));
+ __copy_to_user((void *)data, &child->thread.i387.hard, sizeof(struct user_i387_struct));
#ifdef CONFIG_MATH_EMULATION
- } else {
- save_i387_soft(&child->thread.i387.soft,
- (struct _fpstate *)data);
- }
+ } else {
+ save_i387_soft(&child->thread.i387.soft, (struct _fpstate *)data);
+ }
#endif
- goto out;
- };
-
- case PTRACE_SETFPREGS: { /* Set the child FPU state. */
- if (!access_ok(VERIFY_READ, (unsigned *)data,
- sizeof(struct user_i387_struct)))
- {
- ret = -EIO;
- goto out;
- }
- child->used_math = 1;
+ break;
+ }
+
+ case PTRACE_SETFPREGS: { /* Set the child FPU state. */
+ if (!access_ok(VERIFY_READ, (unsigned *)data, sizeof(struct user_i387_struct))) {
+ ret = -EIO;
+ break;
+ }
+ child->used_math = 1;
#ifdef CONFIG_MATH_EMULATION
- if ( boot_cpu_data.hard_math ) {
+ if ( boot_cpu_data.hard_math ) {
#endif
- __copy_from_user(&child->thread.i387.hard, (void *)data,
- sizeof(struct user_i387_struct));
+ __copy_from_user(&child->thread.i387.hard, (void *)data, sizeof(struct user_i387_struct));
#ifdef CONFIG_MATH_EMULATION
- } else {
- restore_i387_soft(&child->thread.i387.soft,
- (struct _fpstate *)data);
- }
+ } else {
+ restore_i387_soft(&child->thread.i387.soft, (struct _fpstate *)data);
+ }
#endif
- ret = 0;
- goto out;
- };
+ ret = 0;
+ break;
+ }
- default:
- ret = -EIO;
- goto out;
+ default:
+ ret = -EIO;
+ break;
}
out:
unlock_kernel();
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index cd80009d4..d308a1280 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -31,6 +31,11 @@
*
* Added proper L2 cache detection for Coppermine
* Dragan Stancevic <visitor@valinux.com>, October 1999
+ *
+ * Added the origninal array for capability flags but forgot to credit
+ * myself :) (~1998) Fixed/cleaned up some cpu_model_info and other stuff
+ * Jauder Ho <jauderho@carumba.com>, January 2000
+ *
*/
/*
@@ -69,6 +74,7 @@
#include <asm/desc.h>
#include <asm/e820.h>
#include <asm/dma.h>
+#include <asm/mpspec.h>
/*
* Machine setup..
@@ -77,7 +83,7 @@
char ignore_irq13 = 0; /* set if exception 16 works */
struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
-unsigned long mmu_cr4_features __initdata = 0;
+unsigned long mmu_cr4_features = 0;
/*
* Bus types ..
@@ -691,7 +697,7 @@ void __init setup_arch(char **cmdline_p)
*/
reserve_bootmem(0, PAGE_SIZE);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
/*
* But first pinch a few for the stack/trampoline stuff
* FIXME: Don't need the extra page at 4K, but need to fix
@@ -701,7 +707,7 @@ void __init setup_arch(char **cmdline_p)
smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
#endif
-#ifdef __SMP__
+#ifdef CONFIG_X86_IO_APIC
/*
* Save possible boot-time SMP configuration:
*/
@@ -1166,6 +1172,8 @@ void __init get_cpu_vendor(struct cpuinfo_x86 *c)
c->x86_vendor = X86_VENDOR_CENTAUR;
else if (!strcmp(v, "NexGenDriven"))
c->x86_vendor = X86_VENDOR_NEXGEN;
+ else if (!strcmp(v, "RiseRiseRise"))
+ c->x86_vendor = X86_VENDOR_RISE;
else
c->x86_vendor = X86_VENDOR_UNKNOWN;
}
@@ -1176,6 +1184,7 @@ struct cpu_model_info {
char *model_names[16];
};
+/* Naming convention should be: <Name> [(<Codename>)] */
static struct cpu_model_info cpu_models[] __initdata = {
{ X86_VENDOR_INTEL, 4,
{ "486 DX-25/33", "486 DX-50", "486 SX", "486 DX/2", "486 SL",
@@ -1188,8 +1197,9 @@ static struct cpu_model_info cpu_models[] __initdata = {
NULL, NULL, NULL, NULL }},
{ X86_VENDOR_INTEL, 6,
{ "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II (Klamath)",
- NULL, "Pentium II (Deschutes)", "Mobile Pentium II", "Pentium III (Katmai)",
- "Pentium III (Coppermine)", NULL, NULL, NULL, NULL, NULL, NULL }},
+ NULL, "Pentium II (Deschutes)", "Mobile Pentium II",
+ "Pentium III (Katmai)", "Pentium III (Coppermine)", NULL, NULL,
+ NULL, NULL, NULL, NULL }},
{ X86_VENDOR_AMD, 4,
{ NULL, NULL, NULL, "486 DX/2", NULL, NULL, NULL, "486 DX/2-WB",
"486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL, "Am5x86-WT",
@@ -1210,6 +1220,9 @@ static struct cpu_model_info cpu_models[] __initdata = {
{ X86_VENDOR_NEXGEN, 5,
{ "Nx586", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL }},
+ { X86_VENDOR_RISE, 5,
+ { "mP6", "mP6", NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }},
};
void __init identify_cpu(struct cpuinfo_x86 *c)
@@ -1300,8 +1313,9 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
if (c->x86_model <= 16)
p = cpu_models[i].model_names[c->x86_model];
- /* Names for the Pentium II Celeron processors
- detectable only by also checking the cache size */
+ /* Names for the Pentium II/Celeron processors
+ detectable only by also checking the cache size.
+ Dixon is NOT a Celeron. */
if ((cpu_models[i].vendor == X86_VENDOR_INTEL)
&& (cpu_models[i].x86 == 6))
{
@@ -1310,7 +1324,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
else if(c->x86_model == 6 && c->x86_cache_size == 128)
p = "Celeron (Mendocino)";
else if(c->x86_model == 5 && c->x86_cache_size == 256)
- p = "Celeron (Dixon)";
+ p = "Mobile Pentium II (Dixon)";
}
}
}
@@ -1341,7 +1355,7 @@ void __init dodgy_tsc(void)
static char *cpu_vendor_names[] __initdata = {
- "Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur" };
+ "Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur", "Rise" };
void __init print_cpu_info(struct cpuinfo_x86 *c)
@@ -1373,17 +1387,28 @@ int get_cpuinfo(char * buffer)
{
char *p = buffer;
int sep_bug;
+
+ /*
+ * Flags should be entered into the array ONLY if there is no overlap.
+ * Else a number should be used and then overridden in the case
+ * statement below. --Jauder <jauderho@carumba.com>
+ *
+ * NOTE: bits 10, 19-22, 26-31 are reserved.
+ *
+ * Data courtesy of http://www.sandpile.org/arch/cpuid.htm
+ * Thanks to the Greasel!
+ */
static char *x86_cap_flags[] = {
"fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
"cx8", "apic", "10", "sep", "mtrr", "pge", "mca", "cmov",
- "pat", "17", "psn", "19", "20", "21", "22", "mmx",
- "24", "kni", "26", "27", "28", "29", "30", "31"
+ "16", "pse36", "psn", "19", "20", "21", "22", "mmx",
+ "24", "xmm", "26", "27", "28", "29", "30", "31"
};
struct cpuinfo_x86 *c = cpu_data;
int i, n;
- for(n=0; n<NR_CPUS; n++, c++) {
-#ifdef __SMP__
+ for (n = 0; n < NR_CPUS; n++, c++) {
+#ifdef CONFIG_SMP
if (!(cpu_online_map & (1<<n)))
continue;
#endif
@@ -1430,9 +1455,8 @@ int get_cpuinfo(char * buffer)
break;
case X86_VENDOR_INTEL:
- x86_cap_flags[17] = "pse36";
- x86_cap_flags[18] = "psn";
- x86_cap_flags[24] = "osfxsr";
+ x86_cap_flags[16] = "pat";
+ x86_cap_flags[24] = "fxsr";
break;
case X86_VENDOR_CENTAUR:
@@ -1496,14 +1520,14 @@ void cpu_init (void)
int nr = smp_processor_id();
struct tss_struct * t = &init_tss[nr];
- if (test_and_set_bit(nr,&cpu_initialized)) {
+ if (test_and_set_bit(nr, &cpu_initialized)) {
printk("CPU#%d already initialized!\n", nr);
for (;;) __sti();
}
cpus_initialized++;
printk("Initializing CPU#%d\n", nr);
- if (boot_cpu_data.x86_capability & X86_FEATURE_PSE)
+ if (cpu_has_pse)
clear_in_cr4(X86_CR4_VME|X86_CR4_PVI|X86_CR4_TSD|X86_CR4_DE);
__asm__ __volatile__("lgdt %0": "=m" (gdt_descr));
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index a973746b9..18de47dd4 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -19,6 +19,7 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
+#include <linux/highuid.h>
#include <asm/ucontext.h>
#include <asm/uaccess.h>
@@ -642,6 +643,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
info.si_code = SI_USER;
info.si_pid = current->p_pptr->pid;
info.si_uid = current->p_pptr->uid;
+ info.si_uid16 = high2lowuid(current->p_pptr->uid);
}
/* If the (new) signal is now blocked, requeue it. */
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 9acf81556..05e0d1d23 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -2,7 +2,7 @@
* Intel SMP support routines.
*
* (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
- * (c) 1998-99 Ingo Molnar <mingo@redhat.com>
+ * (c) 1998-99, 2000 Ingo Molnar <mingo@redhat.com>
*
* This code is released under the GNU public license version 2 or
* later.
@@ -11,18 +11,18 @@
#include <linux/init.h>
#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/kernel_stat.h>
-#include <linux/smp_lock.h>
#include <linux/irq.h>
-
#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/smp_lock.h>
+#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
+
#include <asm/mtrr.h>
#include <asm/pgalloc.h>
/*
- * Some notes on processor bugs:
+ * Some notes on x86 processor bugs affecting SMP operation:
*
* Pentium, Pentium Pro, II, III (and all CPUs) have bugs.
* The Linux implications for SMP are handled as follows:
@@ -381,7 +381,7 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
static inline void do_flush_tlb_all_local(void)
{
- local_flush_tlb();
+ __flush_tlb_all();
if (!current->mm && current->active_mm) {
unsigned long cpu = smp_processor_id();
@@ -397,9 +397,7 @@ static void flush_tlb_all_ipi(void* info)
void flush_tlb_all(void)
{
- if (cpu_online_map ^ (1 << smp_processor_id()))
- while (smp_call_function (flush_tlb_all_ipi,0,0,1) == -EBUSY)
- mb();
+ smp_call_function (flush_tlb_all_ipi,0,1,1);
do_flush_tlb_all_local();
}
@@ -438,50 +436,44 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
* [SUMMARY] Run a function on all other CPUs.
* <func> The function to run. This must be fast and non-blocking.
* <info> An arbitrary pointer to pass to the function.
- * <nonatomic> If true, we might schedule away to lock the mutex
+ * <nonatomic> currently unused.
* <wait> If true, wait (atomically) until function has completed on other CPUs.
* [RETURNS] 0 on success, else a negative status code. Does not return until
* remote CPUs are nearly ready to execute <<func>> or are or have executed.
+ *
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler, you may call it from a bottom half handler.
*/
{
struct call_data_struct data;
int ret, cpus = smp_num_cpus-1;
- static DECLARE_MUTEX(lock);
- unsigned long timeout;
+ static spinlock_t lock = SPIN_LOCK_UNLOCKED;
- if (nonatomic)
- down(&lock);
- else
- if (down_trylock(&lock))
- return -EBUSY;
+ if(cpus == 0)
+ return 0;
- call_data = &data;
data.func = func;
data.info = info;
atomic_set(&data.started, 0);
data.wait = wait;
if (wait)
atomic_set(&data.finished, 0);
- mb();
+ spin_lock_bh(&lock);
+ call_data = &data;
/* Send a message to all other CPUs and wait for them to respond */
send_IPI_allbutself(CALL_FUNCTION_VECTOR);
/* Wait for response */
- timeout = jiffies + HZ;
- while ((atomic_read(&data.started) != cpus)
- && time_before(jiffies, timeout))
+ /* FIXME: lock-up detection, backtrace on lock-up */
+ while(atomic_read(&data.started) != cpus)
barrier();
- ret = -ETIMEDOUT;
- if (atomic_read(&data.started) != cpus)
- goto out;
+
ret = 0;
if (wait)
while (atomic_read(&data.finished) != cpus)
barrier();
-out:
- call_data = NULL;
- up(&lock);
+ spin_unlock_bh(&lock);
return 0;
}
@@ -504,14 +496,12 @@ static void stop_this_cpu (void * dummy)
void smp_send_stop(void)
{
- unsigned long flags;
+ smp_call_function(stop_this_cpu, NULL, 1, 0);
+ smp_num_cpus = 1;
- __save_flags(flags);
__cli();
- smp_call_function(stop_this_cpu, NULL, 1, 0);
disable_local_APIC();
- __restore_flags(flags);
-
+ __sti();
}
/*
@@ -561,431 +551,3 @@ asmlinkage void smp_call_function_interrupt(void)
atomic_inc(&call_data->finished);
}
-/*
- * This interrupt should _never_ happen with our APIC/SMP architecture
- */
-asmlinkage void smp_spurious_interrupt(void)
-{
- ack_APIC_irq();
- /* see sw-dev-man vol 3, chapter 7.4.13.5 */
- printk("spurious APIC interrupt on CPU#%d, should never happen.\n",
- smp_processor_id());
-}
-
-/*
- * This interrupt should never happen with our APIC/SMP architecture
- */
-
-static spinlock_t err_lock = SPIN_LOCK_UNLOCKED;
-
-asmlinkage void smp_error_interrupt(void)
-{
- unsigned long v;
-
- spin_lock(&err_lock);
-
- v = apic_read(APIC_ESR);
- printk("APIC error interrupt on CPU#%d, should never happen.\n",
- smp_processor_id());
- printk("... APIC ESR0: %08lx\n", v);
-
- apic_write(APIC_ESR, 0);
- v |= apic_read(APIC_ESR);
- printk("... APIC ESR1: %08lx\n", v);
- /*
- * Be a bit more verbose. (multiple bits can be set)
- */
- if (v & 0x01)
- printk("... bit 0: APIC Send CS Error (hw problem).\n");
- if (v & 0x02)
- printk("... bit 1: APIC Receive CS Error (hw problem).\n");
- if (v & 0x04)
- printk("... bit 2: APIC Send Accept Error.\n");
- if (v & 0x08)
- printk("... bit 3: APIC Receive Accept Error.\n");
- if (v & 0x10)
- printk("... bit 4: Reserved!.\n");
- if (v & 0x20)
- printk("... bit 5: Send Illegal Vector (kernel bug).\n");
- if (v & 0x40)
- printk("... bit 6: Received Illegal Vector.\n");
- if (v & 0x80)
- printk("... bit 7: Illegal Register Address.\n");
-
- ack_APIC_irq();
-
- irq_err_count++;
-
- spin_unlock(&err_lock);
-}
-
-/*
- * This part sets up the APIC 32 bit clock in LVTT1, with HZ interrupts
- * per second. We assume that the caller has already set up the local
- * APIC.
- *
- * The APIC timer is not exactly sync with the external timer chip, it
- * closely follows bus clocks.
- */
-
-int prof_multiplier[NR_CPUS] = { 1, };
-int prof_old_multiplier[NR_CPUS] = { 1, };
-int prof_counter[NR_CPUS] = { 1, };
-
-/*
- * The timer chip is already set up at HZ interrupts per second here,
- * but we do not accept timer interrupts yet. We only allow the BP
- * to calibrate.
- */
-static unsigned int __init get_8254_timer_count(void)
-{
- extern rwlock_t xtime_lock;
- unsigned long flags;
-
- unsigned int count;
-
- write_lock_irqsave(&xtime_lock, flags);
-
- outb_p(0x00, 0x43);
- count = inb_p(0x40);
- count |= inb_p(0x40) << 8;
-
- write_unlock_irqrestore(&xtime_lock, flags);
-
- return count;
-}
-
-void __init wait_8254_wraparound(void)
-{
- unsigned int curr_count, prev_count=~0;
- int delta;
-
- curr_count = get_8254_timer_count();
-
- do {
- prev_count = curr_count;
- curr_count = get_8254_timer_count();
- delta = curr_count-prev_count;
-
- /*
- * This limit for delta seems arbitrary, but it isn't, it's
- * slightly above the level of error a buggy Mercury/Neptune
- * chipset timer can cause.
- */
-
- } while (delta<300);
-}
-
-/*
- * This function sets up the local APIC timer, with a timeout of
- * 'clocks' APIC bus clock. During calibration we actually call
- * this function twice on the boot CPU, once with a bogus timeout
- * value, second time for real. The other (noncalibrating) CPUs
- * call this function only once, with the real, calibrated value.
- *
- * We do reads before writes even if unnecessary, to get around the
- * P5 APIC double write bug.
- */
-
-#define APIC_DIVISOR 16
-
-void __setup_APIC_LVTT(unsigned int clocks)
-{
- unsigned int lvtt1_value, tmp_value;
-
- tmp_value = apic_read(APIC_LVTT);
- lvtt1_value = SET_APIC_TIMER_BASE(APIC_TIMER_BASE_DIV) |
- APIC_LVT_TIMER_PERIODIC | LOCAL_TIMER_VECTOR;
- apic_write(APIC_LVTT, lvtt1_value);
-
- /*
- * Divide PICLK by 16
- */
- tmp_value = apic_read(APIC_TDCR);
- apic_write(APIC_TDCR, (tmp_value
- & ~(APIC_TDR_DIV_1 | APIC_TDR_DIV_TMBASE))
- | APIC_TDR_DIV_16);
-
- tmp_value = apic_read(APIC_TMICT);
- apic_write(APIC_TMICT, clocks/APIC_DIVISOR);
-}
-
-void setup_APIC_timer(void * data)
-{
- unsigned int clocks = (unsigned int) data, slice, t0, t1, nr;
- unsigned long flags;
- int delta;
-
- __save_flags(flags);
- __sti();
- /*
- * ok, Intel has some smart code in their APIC that knows
- * if a CPU was in 'hlt' lowpower mode, and this increases
- * its APIC arbitration priority. To avoid the external timer
- * IRQ APIC event being in synchron with the APIC clock we
- * introduce an interrupt skew to spread out timer events.
- *
- * The number of slices within a 'big' timeslice is smp_num_cpus+1
- */
-
- slice = clocks / (smp_num_cpus+1);
- nr = cpu_number_map[smp_processor_id()] + 1;
- printk("cpu: %d, clocks: %d, slice: %d, nr: %d.\n",
- smp_processor_id(), clocks, slice, nr);
- /*
- * Wait for IRQ0's slice:
- */
- wait_8254_wraparound();
-
- __setup_APIC_LVTT(clocks);
-
- t0 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
- do {
- t1 = apic_read(APIC_TMCCT)*APIC_DIVISOR;
- delta = (int)(t0 - t1 - slice*nr);
- } while (delta < 0);
-
- __setup_APIC_LVTT(clocks);
-
- printk("CPU%d<C0:%d,C:%d,D:%d,S:%d,C:%d>\n",
- smp_processor_id(), t0, t1, delta, slice, clocks);
-
- __restore_flags(flags);
-}
-
-/*
- * In this function we calibrate APIC bus clocks to the external
- * timer. Unfortunately we cannot use jiffies and the timer irq
- * to calibrate, since some later bootup code depends on getting
- * the first irq? Ugh.
- *
- * We want to do the calibration only once since we
- * want to have local timer irqs syncron. CPUs connected
- * by the same APIC bus have the very same bus frequency.
- * And we want to have irqs off anyways, no accidental
- * APIC irq that way.
- */
-
-int __init calibrate_APIC_clock(void)
-{
- unsigned long long t1 = 0, t2 = 0;
- long tt1, tt2;
- long result;
- int i;
- const int LOOPS = HZ/10;
-
- printk("calibrating APIC timer ... ");
-
- /*
- * Put whatever arbitrary (but long enough) timeout
- * value into the APIC clock, we just want to get the
- * counter running for calibration.
- */
- __setup_APIC_LVTT(1000000000);
-
- /*
- * The timer chip counts down to zero. Let's wait
- * for a wraparound to start exact measurement:
- * (the current tick might have been already half done)
- */
-
- wait_8254_wraparound();
-
- /*
- * We wrapped around just now. Let's start:
- */
- if (cpu_has_tsc)
- rdtscll(t1);
- tt1 = apic_read(APIC_TMCCT);
-
- /*
- * Let's wait LOOPS wraprounds:
- */
- for (i = 0; i < LOOPS; i++)
- wait_8254_wraparound();
-
- tt2 = apic_read(APIC_TMCCT);
- if (cpu_has_tsc)
- rdtscll(t2);
-
- /*
- * The APIC bus clock counter is 32 bits only, it
- * might have overflown, but note that we use signed
- * longs, thus no extra care needed.
- *
- * underflown to be exact, as the timer counts down ;)
- */
-
- result = (tt1-tt2)*APIC_DIVISOR/LOOPS;
-
- if (cpu_has_tsc)
- printk("\n..... CPU clock speed is %ld.%04ld MHz.\n",
- ((long)(t2-t1)/LOOPS)/(1000000/HZ),
- ((long)(t2-t1)/LOOPS)%(1000000/HZ));
-
- printk("..... host bus clock speed is %ld.%04ld MHz.\n",
- result/(1000000/HZ),
- result%(1000000/HZ));
-
- return result;
-}
-
-static unsigned int calibration_result;
-
-void __init setup_APIC_clocks(void)
-{
- unsigned long flags;
-
- __save_flags(flags);
- __cli();
-
- calibration_result = calibrate_APIC_clock();
-
- smp_call_function(setup_APIC_timer, (void *)calibration_result, 1, 1);
-
- /*
- * Now set up the timer for real.
- */
- setup_APIC_timer((void *)calibration_result);
-
- __restore_flags(flags);
-}
-
-/*
- * the frequency of the profiling timer can be changed
- * by writing a multiplier value into /proc/profile.
- */
-int setup_profiling_timer(unsigned int multiplier)
-{
- int i;
-
- /*
- * Sanity check. [at least 500 APIC cycles should be
- * between APIC interrupts as a rule of thumb, to avoid
- * irqs flooding us]
- */
- if ( (!multiplier) || (calibration_result/multiplier < 500))
- return -EINVAL;
-
- /*
- * Set the new multiplier for each CPU. CPUs don't start using the
- * new values until the next timer interrupt in which they do process
- * accounting. At that time they also adjust their APIC timers
- * accordingly.
- */
- for (i = 0; i < NR_CPUS; ++i)
- prof_multiplier[i] = multiplier;
-
- return 0;
-}
-
-#undef APIC_DIVISOR
-
-/*
- * Local timer interrupt handler. It does both profiling and
- * process statistics/rescheduling.
- *
- * We do profiling in every local tick, statistics/rescheduling
- * happen only every 'profiling multiplier' ticks. The default
- * multiplier is 1 and it can be changed by writing the new multiplier
- * value into /proc/profile.
- */
-
-inline void smp_local_timer_interrupt(struct pt_regs * regs)
-{
- int user = (user_mode(regs) != 0);
- int cpu = smp_processor_id();
-
- /*
- * The profiling function is SMP safe. (nothing can mess
- * around with "current", and the profiling counters are
- * updated with atomic operations). This is especially
- * useful with a profiling multiplier != 1
- */
- if (!user)
- x86_do_profile(regs->eip);
-
- if (--prof_counter[cpu] <= 0) {
- int system = 1 - user;
- struct task_struct * p = current;
-
- /*
- * The multiplier may have changed since the last time we got
- * to this point as a result of the user writing to
- * /proc/profile. In this case we need to adjust the APIC
- * timer accordingly.
- *
- * Interrupts are already masked off at this point.
- */
- prof_counter[cpu] = prof_multiplier[cpu];
- if (prof_counter[cpu] != prof_old_multiplier[cpu]) {
- __setup_APIC_LVTT(calibration_result/prof_counter[cpu]);
- prof_old_multiplier[cpu] = prof_counter[cpu];
- }
-
- /*
- * After doing the above, we need to make like
- * a normal interrupt - otherwise timer interrupts
- * ignore the global interrupt lock, which is the
- * WrongThing (tm) to do.
- */
-
- irq_enter(cpu, 0);
- update_one_process(p, 1, user, system, cpu);
- if (p->pid) {
- p->counter -= 1;
- if (p->counter <= 0) {
- p->counter = 0;
- p->need_resched = 1;
- }
- if (p->priority < DEF_PRIORITY) {
- kstat.cpu_nice += user;
- kstat.per_cpu_nice[cpu] += user;
- } else {
- kstat.cpu_user += user;
- kstat.per_cpu_user[cpu] += user;
- }
- kstat.cpu_system += system;
- kstat.per_cpu_system[cpu] += system;
-
- }
- irq_exit(cpu, 0);
- }
-
- /*
- * We take the 'long' return path, and there every subsystem
- * grabs the apropriate locks (kernel lock/ irq lock).
- *
- * we might want to decouple profiling from the 'long path',
- * and do the profiling totally in assembly.
- *
- * Currently this isn't too much of an issue (performance wise),
- * we can take more than 100K local irqs per second on a 100 MHz P5.
- */
-}
-
-/*
- * Local APIC timer interrupt. This is the most natural way for doing
- * local interrupts, but local timer interrupts can be emulated by
- * broadcast interrupts too. [in case the hw doesnt support APIC timers]
- *
- * [ if a single-CPU system runs an SMP kernel then we call the local
- * interrupt as well. Thus we cannot inline the local irq ... ]
- */
-unsigned int apic_timer_irqs [NR_CPUS] = { 0, };
-
-void smp_apic_timer_interrupt(struct pt_regs * regs)
-{
- /*
- * the NMI deadlock-detector uses this.
- */
- apic_timer_irqs[smp_processor_id()]++;
-
- /*
- * NOTE! We'd better ACK the irq immediately,
- * because timer handling can be slow.
- */
- ack_APIC_irq();
- smp_local_timer_interrupt(regs);
-}
-
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 811f00f38..3ff5cc002 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -1,8 +1,8 @@
/*
- * Intel MP v1.1/v1.4 specification compliant parsing routines.
+ * x86 SMP booting functions
*
* (c) 1995 Alan Cox, Building #3 <alan@redhat.com>
- * (c) 1998, 1999 Ingo Molnar <mingo@redhat.com>
+ * (c) 1998, 1999, 2000 Ingo Molnar <mingo@redhat.com>
*
* Much of the core SMP work is based on previous work by Thomas Radke, to
* whom a great many thanks are extended.
@@ -26,10 +26,8 @@
* Alan Cox : Dumb bug: 'B' step PPro's are fine
* Ingo Molnar : Added APIC timers, based on code
* from Jose Renau
- * Alan Cox : Added EBDA scanning
* Ingo Molnar : various cleanups and rewrites
* Tigran Aivazian : fixed "0.00 in /proc/uptime on SMP" bug.
- * Maciej W. Rozycki : Bits for genuine 82489DX timers
*/
#include <linux/config.h>
@@ -51,72 +49,28 @@ static int smp_b_stepping = 0;
/* Setup configured maximum number of CPUs to activate */
static int max_cpus = -1;
-/* 1 if "noapic" boot option passed */
-int skip_ioapic_setup = 0;
/* Total count of live CPUs */
-int smp_num_cpus = 0;
-/* Internal processor count */
-static unsigned int num_processors = 1;
+int smp_num_cpus = 1;
-/* Have we found an SMP box */
-int smp_found_config = 0;
-
-/* Bitmask of physically existing CPUs */
-unsigned long cpu_present_map = 0;
/* Bitmask of currently online CPUs */
unsigned long cpu_online_map = 0;
-/* which CPU maps to which logical number */
-volatile int cpu_number_map[NR_CPUS];
-/* which logical number maps to which CPU */
-volatile int __cpu_logical_map[NR_CPUS];
+/* which CPU (physical APIC ID) maps to which logical CPU number */
+volatile int x86_apicid_to_cpu[NR_CPUS];
+/* which logical CPU number maps to which CPU (physical APIC ID) */
+volatile int x86_cpu_to_apicid[NR_CPUS];
static volatile unsigned long cpu_callin_map = 0;
static volatile unsigned long cpu_callout_map = 0;
/* Per CPU bogomips and other parameters */
struct cpuinfo_x86 cpu_data[NR_CPUS];
-/* Processor that is doing the boot up */
-static unsigned int boot_cpu_id = 0;
-/* Tripped once we need to start cross invalidating */
-static int smp_activated = 0;
/* Set when the idlers are all forked */
int smp_threads_ready = 0;
/*
- * Various Linux-internal data structures created from the
- * MP-table.
- */
-int apic_version [NR_CPUS];
-int mp_bus_id_to_type [MAX_MP_BUSSES] = { -1, };
-extern int nr_ioapics;
-extern struct mpc_config_ioapic mp_ioapics [MAX_IO_APICS];
-extern int mp_irq_entries;
-extern struct mpc_config_intsrc mp_irqs [MAX_IRQ_SOURCES];
-extern int mpc_default_type;
-int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { -1, };
-int mp_current_pci_id = 0;
-unsigned long mp_lapic_addr = 0;
-int pic_mode;
-
-extern void cache_APIC_registers (void);
-
-#define SMP_DEBUG 1
-
-#if SMP_DEBUG
-#define dprintk(x...) printk(##x)
-#else
-#define dprintk(x...)
-#endif
-
-/*
- * IA s/w dev Vol 3, Section 7.4
- */
-#define APIC_DEFAULT_PHYS_BASE 0xfee00000
-
-/*
* Setup routine for controlling SMP activation
*
* Command-line option of "nosmp" or "maxcpus=0" will disable SMP
@@ -144,471 +98,6 @@ static int __init maxcpus(char *str)
__setup("maxcpus=", maxcpus);
/*
- * Intel MP BIOS table parsing routines:
- */
-
-#ifndef CONFIG_X86_VISWS_APIC
-/*
- * Checksum an MP configuration block.
- */
-
-static int __init mpf_checksum(unsigned char *mp, int len)
-{
- int sum=0;
- while(len--)
- sum+=*mp++;
- return sum&0xFF;
-}
-
-/*
- * Processor encoding in an MP configuration block
- */
-
-static char __init *mpc_family(int family,int model)
-{
- static char n[32];
- static char *model_defs[]=
- {
- "80486DX","80486DX",
- "80486SX","80486DX/2 or 80487",
- "80486SL","80486SX/2",
- "Unknown","80486DX/2-WB",
- "80486DX/4","80486DX/4-WB"
- };
-
- switch (family) {
- case 0x04:
- if (model < 10)
- return model_defs[model];
- break;
-
- case 0x05:
- return("Pentium(tm)");
-
- case 0x06:
- return("Pentium(tm) Pro");
-
- case 0x0F:
- if (model == 0x0F)
- return("Special controller");
- }
- sprintf(n,"Unknown CPU [%d:%d]",family, model);
- return n;
-}
-
-static void __init MP_processor_info (struct mpc_config_processor *m)
-{
- int ver;
-
- if (!(m->mpc_cpuflag & CPU_ENABLED))
- return;
-
- printk("Processor #%d %s APIC version %d\n",
- m->mpc_apicid,
- mpc_family( (m->mpc_cpufeature & CPU_FAMILY_MASK)>>8 ,
- (m->mpc_cpufeature & CPU_MODEL_MASK)>>4),
- m->mpc_apicver);
-
-#ifdef SMP_DEBUG
- if (m->mpc_featureflag&(1<<0))
- printk(" Floating point unit present.\n");
- if (m->mpc_featureflag&(1<<7))
- printk(" Machine Exception supported.\n");
- if (m->mpc_featureflag&(1<<8))
- printk(" 64 bit compare & exchange supported.\n");
- if (m->mpc_featureflag&(1<<9))
- printk(" Internal APIC present.\n");
-#endif
-
- if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) {
- dprintk(" Bootup CPU\n");
- boot_cpu_id = m->mpc_apicid;
- } else
- /* Boot CPU already counted */
- num_processors++;
-
- if (m->mpc_apicid > NR_CPUS) {
- printk("Processor #%d unused. (Max %d processors).\n",
- m->mpc_apicid, NR_CPUS);
- return;
- }
- ver = m->mpc_apicver;
-
- cpu_present_map |= (1<<m->mpc_apicid);
- /*
- * Validate version
- */
- if (ver == 0x0) {
- printk("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
- ver = 0x10;
- }
- apic_version[m->mpc_apicid] = ver;
-}
-
-static void __init MP_bus_info (struct mpc_config_bus *m)
-{
- char str[7];
-
- memcpy(str, m->mpc_bustype, 6);
- str[6] = 0;
- dprintk("Bus #%d is %s\n", m->mpc_busid, str);
-
- if (strncmp(str, "ISA", 3) == 0) {
- mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
- } else {
- if (strncmp(str, "EISA", 4) == 0) {
- mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
- } else {
- if (strncmp(str, "PCI", 3) == 0) {
- mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
- mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
- mp_current_pci_id++;
- } else {
- printk("Unknown bustype %s\n", str);
- panic("cannot handle bus - mail to linux-smp@vger.rutgers.edu");
- } } }
-}
-
-static void __init MP_ioapic_info (struct mpc_config_ioapic *m)
-{
- if (!(m->mpc_flags & MPC_APIC_USABLE))
- return;
-
- printk("I/O APIC #%d Version %d at 0x%lX.\n",
- m->mpc_apicid, m->mpc_apicver, m->mpc_apicaddr);
- if (nr_ioapics >= MAX_IO_APICS) {
- printk("Max # of I/O APICs (%d) exceeded (found %d).\n",
- MAX_IO_APICS, nr_ioapics);
- panic("Recompile kernel with bigger MAX_IO_APICS!.\n");
- }
- mp_ioapics[nr_ioapics] = *m;
- nr_ioapics++;
-}
-
-static void __init MP_intsrc_info (struct mpc_config_intsrc *m)
-{
- mp_irqs [mp_irq_entries] = *m;
- if (++mp_irq_entries == MAX_IRQ_SOURCES)
- panic("Max # of irq sources exceeded!!\n");
-}
-
-static void __init MP_lintsrc_info (struct mpc_config_lintsrc *m)
-{
- /*
- * Well it seems all SMP boards in existence
- * use ExtINT/LVT1 == LINT0 and
- * NMI/LVT2 == LINT1 - the following check
- * will show us if this assumptions is false.
- * Until then we do not have to add baggage.
- */
- if ((m->mpc_irqtype == mp_ExtINT) &&
- (m->mpc_destapiclint != 0))
- BUG();
- if ((m->mpc_irqtype == mp_NMI) &&
- (m->mpc_destapiclint != 1))
- BUG();
-}
-
-/*
- * Read/parse the MPC
- */
-
-static int __init smp_read_mpc(struct mp_config_table *mpc)
-{
- char str[16];
- int count=sizeof(*mpc);
- unsigned char *mpt=((unsigned char *)mpc)+count;
-
- if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4))
- {
- panic("SMP mptable: bad signature [%c%c%c%c]!\n",
- mpc->mpc_signature[0],
- mpc->mpc_signature[1],
- mpc->mpc_signature[2],
- mpc->mpc_signature[3]);
- return 1;
- }
- if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length))
- {
- panic("SMP mptable: checksum error!\n");
- return 1;
- }
- if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04)
- {
- printk("Bad Config Table version (%d)!!\n",mpc->mpc_spec);
- return 1;
- }
- memcpy(str,mpc->mpc_oem,8);
- str[8]=0;
- printk("OEM ID: %s ",str);
-
- memcpy(str,mpc->mpc_productid,12);
- str[12]=0;
- printk("Product ID: %s ",str);
-
- printk("APIC at: 0x%lX\n",mpc->mpc_lapic);
-
- /* save the local APIC address, it might be non-default */
- mp_lapic_addr = mpc->mpc_lapic;
-
- /*
- * Now process the configuration blocks.
- */
- while (count < mpc->mpc_length) {
- switch(*mpt) {
- case MP_PROCESSOR:
- {
- struct mpc_config_processor *m=
- (struct mpc_config_processor *)mpt;
- MP_processor_info(m);
- mpt += sizeof(*m);
- count += sizeof(*m);
- break;
- }
- case MP_BUS:
- {
- struct mpc_config_bus *m=
- (struct mpc_config_bus *)mpt;
- MP_bus_info(m);
- mpt += sizeof(*m);
- count += sizeof(*m);
- break;
- }
- case MP_IOAPIC:
- {
- struct mpc_config_ioapic *m=
- (struct mpc_config_ioapic *)mpt;
- MP_ioapic_info(m);
- mpt+=sizeof(*m);
- count+=sizeof(*m);
- break;
- }
- case MP_INTSRC:
- {
- struct mpc_config_intsrc *m=
- (struct mpc_config_intsrc *)mpt;
-
- MP_intsrc_info(m);
- mpt+=sizeof(*m);
- count+=sizeof(*m);
- break;
- }
- case MP_LINTSRC:
- {
- struct mpc_config_lintsrc *m=
- (struct mpc_config_lintsrc *)mpt;
- MP_lintsrc_info(m);
- mpt+=sizeof(*m);
- count+=sizeof(*m);
- break;
- }
- }
- }
- return num_processors;
-}
-
-/*
- * Scan the memory blocks for an SMP configuration block.
- */
-static int __init smp_get_mpf(struct intel_mp_floating *mpf)
-{
- printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification);
- if (mpf->mpf_feature2 & (1<<7)) {
- printk(" IMCR and PIC compatibility mode.\n");
- pic_mode = 1;
- } else {
- printk(" Virtual Wire compatibility mode.\n");
- pic_mode = 0;
- }
- smp_found_config = 1;
- /*
- * default CPU id - if it's different in the mptable
- * then we change it before first using it.
- */
- boot_cpu_id = 0;
- /*
- * Now see if we need to read further.
- */
- if (mpf->mpf_feature1 != 0) {
- /*
- * local APIC has default address
- */
- mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-
- /*
- * 2 CPUs, numbered 0 & 1.
- */
- cpu_present_map = 3;
- num_processors = 2;
-
- nr_ioapics = 1;
- mp_ioapics[0].mpc_apicaddr = 0xFEC00000;
- /*
- * Save the default type number, we
- * need it later to set the IO-APIC
- * up properly:
- */
- mpc_default_type = mpf->mpf_feature1;
-
- printk("Bus #0 is ");
- }
-
- switch (mpf->mpf_feature1) {
- case 1:
- case 5:
- printk("ISA\n");
- break;
- case 2:
- printk("EISA with no IRQ0 and no IRQ13 DMA chaining\n");
- break;
- case 6:
- case 3:
- printk("EISA\n");
- break;
- case 4:
- case 7:
- printk("MCA\n");
- break;
- case 0:
- if (!mpf->mpf_physptr)
- BUG();
- break;
- default:
- printk("???\nUnknown standard configuration %d\n",
- mpf->mpf_feature1);
- return 1;
- }
- if (mpf->mpf_feature1 > 4) {
- printk("Bus #1 is PCI\n");
-
- /*
- * Set local APIC version to the integrated form.
- * It's initialized to zero otherwise, representing
- * a discrete 82489DX.
- */
- apic_version[0] = 0x10;
- apic_version[1] = 0x10;
- }
- /*
- * Read the physical hardware table. Anything here will override the
- * defaults.
- */
- if (mpf->mpf_physptr)
- smp_read_mpc((void *)mpf->mpf_physptr);
-
- __cpu_logical_map[0] = boot_cpu_id;
- global_irq_holder = boot_cpu_id;
- current->processor = boot_cpu_id;
-
- printk("Processors: %d\n", num_processors);
- /*
- * Only use the first configuration found.
- */
- return 1;
-}
-
-static int __init smp_scan_config(unsigned long base, unsigned long length)
-{
- unsigned long *bp = phys_to_virt(base);
- struct intel_mp_floating *mpf;
-
- dprintk("Scan SMP from %p for %ld bytes.\n", bp,length);
- if (sizeof(*mpf) != 16)
- printk("Error: MPF size\n");
-
- while (length > 0) {
- mpf = (struct intel_mp_floating *)bp;
- if ((*bp == SMP_MAGIC_IDENT) &&
- (mpf->mpf_length == 1) &&
- !mpf_checksum((unsigned char *)bp, 16) &&
- ((mpf->mpf_specification == 1)
- || (mpf->mpf_specification == 4)) ) {
-
- printk("found SMP MP-table at %08ld\n",
- virt_to_phys(mpf));
- smp_get_mpf(mpf);
- return 1;
- }
- bp += 4;
- length -= 16;
- }
- return 0;
-}
-
-void __init init_intel_smp (void)
-{
- unsigned int address;
-
- /*
- * FIXME: Linux assumes you have 640K of base ram..
- * this continues the error...
- *
- * 1) Scan the bottom 1K for a signature
- * 2) Scan the top 1K of base RAM
- * 3) Scan the 64K of bios
- */
- if (smp_scan_config(0x0,0x400) ||
- smp_scan_config(639*0x400,0x400) ||
- smp_scan_config(0xF0000,0x10000))
- return;
- /*
- * If it is an SMP machine we should know now, unless the
- * configuration is in an EISA/MCA bus machine with an
- * extended bios data area.
- *
- * there is a real-mode segmented pointer pointing to the
- * 4K EBDA area at 0x40E, calculate and scan it here.
- *
- * NOTE! There are Linux loaders that will corrupt the EBDA
- * area, and as such this kind of SMP config may be less
- * trustworthy, simply because the SMP table may have been
- * stomped on during early boot. These loaders are buggy and
- * should be fixed.
- */
-
- address = *(unsigned short *)phys_to_virt(0x40E);
- address <<= 4;
- smp_scan_config(address, 0x1000);
- if (smp_found_config)
- printk(KERN_WARNING "WARNING: MP table in the EBDA can be UNSAFE, contact linux-smp@vger.rutgers.edu if you experience SMP problems!\n");
-}
-
-#else
-
-/*
- * The Visual Workstation is Intel MP compliant in the hardware
- * sense, but it doesnt have a BIOS(-configuration table).
- * No problem for Linux.
- */
-void __init init_visws_smp(void)
-{
- smp_found_config = 1;
-
- cpu_present_map |= 2; /* or in id 1 */
- apic_version[1] |= 0x10; /* integrated APIC */
- apic_version[0] |= 0x10;
-
- mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
-}
-
-#endif
-
-/*
- * - Intel MP Configuration Table
- * - or SGI Visual Workstation configuration
- */
-void __init init_smp_config (void)
-{
-#ifndef CONFIG_VISWS
- init_intel_smp();
-#else
- init_visws_smp();
-#endif
-}
-
-
-
-/*
* Trampoline 80x86 program as an array.
*/
@@ -688,209 +177,12 @@ void __init smp_commence(void)
/*
* Lets the callins below out of their loop.
*/
- dprintk("Setting commenced=1, go go go\n");
+ Dprintk("Setting commenced=1, go go go\n");
wmb();
atomic_set(&smp_commenced,1);
}
-extern void __error_in_io_apic_c(void);
-
-
-int get_maxlvt(void)
-{
- unsigned int v, ver, maxlvt;
-
- v = apic_read(APIC_LVR);
- ver = GET_APIC_VERSION(v);
- /* 82489DXs do not report # of LVT entries. */
- maxlvt = APIC_INTEGRATED(ver) ? GET_APIC_MAXLVT(v) : 2;
- return maxlvt;
-}
-
-void disable_local_APIC (void)
-{
- unsigned long value;
- int maxlvt;
-
- /*
- * Disable APIC
- */
- value = apic_read(APIC_SPIV);
- value &= ~(1<<8);
- apic_write(APIC_SPIV,value);
-
- /*
- * Clean APIC state for other OSs:
- */
- value = apic_read(APIC_SPIV);
- value &= ~(1<<8);
- apic_write(APIC_SPIV,value);
- maxlvt = get_maxlvt();
- apic_write_around(APIC_LVTT, 0x00010000);
- apic_write_around(APIC_LVT0, 0x00010000);
- apic_write_around(APIC_LVT1, 0x00010000);
- if (maxlvt >= 3)
- apic_write_around(APIC_LVTERR, 0x00010000);
- if (maxlvt >= 4)
- apic_write_around(APIC_LVTPC, 0x00010000);
-}
-
-void __init setup_local_APIC (void)
-{
- unsigned long value, ver, maxlvt;
-
- if ((SPURIOUS_APIC_VECTOR & 0x0f) != 0x0f)
- __error_in_io_apic_c();
-
- value = apic_read(APIC_SPIV);
- /*
- * Enable APIC
- */
- value |= (1<<8);
-
- /*
- * Some unknown Intel IO/APIC (or APIC) errata is biting us with
- * certain networking cards. If high frequency interrupts are
- * happening on a particular IOAPIC pin, plus the IOAPIC routing
- * entry is masked/unmasked at a high rate as well then sooner or
- * later IOAPIC line gets 'stuck', no more interrupts are received
- * from the device. If focus CPU is disabled then the hang goes
- * away, oh well :-(
- *
- * [ This bug can be reproduced easily with a level-triggered
- * PCI Ne2000 networking cards and PII/PIII processors, dual
- * BX chipset. ]
- */
-#if 0
- /* Enable focus processor (bit==0) */
- value &= ~(1<<9);
-#else
- /* Disable focus processor (bit==1) */
- value |= (1<<9);
-#endif
- /*
- * Set spurious IRQ vector
- */
- value |= SPURIOUS_APIC_VECTOR;
- apic_write(APIC_SPIV,value);
-
- /*
- * Set up LVT0, LVT1:
- *
- * set up through-local-APIC on the BP's LINT0. This is not
- * strictly necessery in pure symmetric-IO mode, but sometimes
- * we delegate interrupts to the 8259A.
- */
- if (hard_smp_processor_id() == boot_cpu_id) {
- value = 0x00000700;
- printk("enabled ExtINT on CPU#%d\n", hard_smp_processor_id());
- } else {
- value = 0x00010700;
- printk("masked ExtINT on CPU#%d\n", hard_smp_processor_id());
- }
- apic_write_around(APIC_LVT0,value);
-
- /*
- * only the BP should see the LINT1 NMI signal, obviously.
- */
- if (hard_smp_processor_id() == boot_cpu_id)
- value = 0x00000400; // unmask NMI
- else
- value = 0x00010400; // mask NMI
- apic_write_around(APIC_LVT1,value);
-
- value = apic_read(APIC_LVR);
- ver = GET_APIC_VERSION(value);
- if (APIC_INTEGRATED(ver)) { /* !82489DX */
- maxlvt = get_maxlvt();
- /*
- * Due to the Pentium erratum 3AP.
- */
- if (maxlvt > 3) {
- apic_readaround(APIC_SPIV); // not strictly necessery
- apic_write(APIC_ESR, 0);
- }
- value = apic_read(APIC_ESR);
- printk("ESR value before enabling vector: %08lx\n", value);
-
- value = apic_read(APIC_LVTERR);
- value = ERROR_APIC_VECTOR; // enables sending errors
- apic_write(APIC_LVTERR,value);
- /*
- * spec says clear errors after enabling vector.
- */
- if (maxlvt != 3) {
- apic_readaround(APIC_SPIV);
- apic_write(APIC_ESR, 0);
- }
- value = apic_read(APIC_ESR);
- printk("ESR value after enabling vector: %08lx\n", value);
- } else
- printk("No ESR for 82489DX.\n");
-
- /*
- * Set Task Priority to 'accept all'. We never change this
- * later on.
- */
- value = apic_read(APIC_TASKPRI);
- value &= ~APIC_TPRI_MASK;
- apic_write(APIC_TASKPRI,value);
-
- /*
- * Set up the logical destination ID and put the
- * APIC into flat delivery mode.
- */
- value = apic_read(APIC_LDR);
- value &= ~APIC_LDR_MASK;
- value |= (1<<(smp_processor_id()+24));
- apic_write(APIC_LDR,value);
-
- value = apic_read(APIC_DFR);
- value |= SET_APIC_DFR(0xf);
- apic_write(APIC_DFR, value);
-}
-
-void __init init_smp_mappings(void)
-{
- unsigned long apic_phys;
-
- if (smp_found_config) {
- apic_phys = mp_lapic_addr;
- } else {
- /*
- * set up a fake all zeroes page to simulate the
- * local APIC and another one for the IO-APIC. We
- * could use the real zero-page, but it's safer
- * this way if some buggy code writes to this page ...
- */
- apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
- apic_phys = __pa(apic_phys);
- }
- set_fixmap(FIX_APIC_BASE, apic_phys);
- dprintk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys);
-
-#ifdef CONFIG_X86_IO_APIC
- {
- unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
- int i;
-
- for (i = 0; i < nr_ioapics; i++) {
- if (smp_found_config) {
- ioapic_phys = mp_ioapics[i].mpc_apicaddr;
- } else {
- ioapic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
- ioapic_phys = __pa(ioapic_phys);
- }
- set_fixmap(idx,ioapic_phys);
- dprintk("mapped IOAPIC to %08lx (%08lx)\n",
- __fix_to_virt(idx), ioapic_phys);
- idx++;
- }
- }
-#endif
-}
-
/*
* TSC synchronization.
*
@@ -990,20 +282,14 @@ static void __init synchronize_tsc_bp (void)
}
sum = 0;
- for (i = 0; i < NR_CPUS; i++) {
- if (!(cpu_online_map & (1 << i)))
- continue;
-
+ for (i = 0; i < smp_num_cpus; i++) {
t0 = tsc_values[i];
sum += t0;
}
avg = div64(sum, smp_num_cpus);
sum = 0;
- for (i = 0; i < NR_CPUS; i++) {
- if (!(cpu_online_map & (1 << i)))
- continue;
-
+ for (i = 0; i < smp_num_cpus; i++) {
delta = tsc_values[i] - avg;
if (delta < 0)
delta = -delta;
@@ -1059,15 +345,20 @@ extern void calibrate_delay(void);
void __init smp_callin(void)
{
- int cpuid;
+ int cpuid, phys_id;
unsigned long timeout;
/*
* (This works even if the APIC is not enabled.)
*/
- cpuid = GET_APIC_ID(apic_read(APIC_ID));
-
- dprintk("CPU#%d waiting for CALLOUT\n", cpuid);
+ phys_id = GET_APIC_ID(apic_read(APIC_ID));
+ cpuid = current->processor;
+ if (test_and_set_bit(cpuid, &cpu_online_map)) {
+ printk("huh, phys CPU#%d, CPU#%d already present??\n",
+ phys_id, cpuid);
+ BUG();
+ }
+ Dprintk("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpuid, phys_id);
/*
* STARTUP IPIs are fragile beasts as they might sometimes
@@ -1102,7 +393,7 @@ void __init smp_callin(void)
* boards)
*/
- dprintk("CALLIN, before setup_local_APIC().\n");
+ Dprintk("CALLIN, before setup_local_APIC().\n");
setup_local_APIC();
sti();
@@ -1117,7 +408,7 @@ void __init smp_callin(void)
* Get our bogomips.
*/
calibrate_delay();
- dprintk("Stack at about %p\n",&cpuid);
+ Dprintk("Stack at about %p\n",&cpuid);
/*
* Save our processor parameters
@@ -1133,7 +424,7 @@ void __init smp_callin(void)
* Synchronize the TSC with the BP
*/
if (cpu_has_tsc)
- synchronize_tsc_ap ();
+ synchronize_tsc_ap();
}
int cpucount = 0;
@@ -1198,21 +489,21 @@ static int __init fork_by_hand(void)
return do_fork(CLONE_VM|CLONE_PID, 0, &regs);
}
-static void __init do_boot_cpu(int i)
+static void __init do_boot_cpu (int apicid)
{
unsigned long cfg;
struct task_struct *idle;
unsigned long send_status, accept_status;
- int timeout, num_starts, j;
+ int timeout, num_starts, j, cpu;
unsigned long start_eip;
- cpucount++;
+ cpu = ++cpucount;
/*
* We can't use kernel_thread since we must avoid to
* reschedule the child.
*/
if (fork_by_hand() < 0)
- panic("failed fork for CPU %d", i);
+ panic("failed fork for CPU %d", cpu);
/*
* We remove it from the pidhash and the runqueue
@@ -1220,23 +511,23 @@ static void __init do_boot_cpu(int i)
*/
idle = init_task.prev_task;
if (!idle)
- panic("No idle process for CPU %d", i);
+ panic("No idle process for CPU %d", cpu);
- idle->processor = i;
- __cpu_logical_map[cpucount] = i;
- cpu_number_map[i] = cpucount;
+ idle->processor = cpu;
+ x86_cpu_to_apicid[cpu] = apicid;
+ x86_apicid_to_cpu[apicid] = cpu;
idle->has_cpu = 1; /* we schedule the first task manually */
idle->thread.eip = (unsigned long) start_secondary;
del_from_runqueue(idle);
unhash_process(idle);
- init_tasks[cpucount] = idle;
+ init_tasks[cpu] = idle;
/* start_eip had better be page-aligned! */
start_eip = setup_trampoline();
/* So we see what's up */
- printk("Booting processor %d eip %lx\n", i, start_eip);
+ printk("Booting processor %d eip %lx\n", cpu, start_eip);
stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle);
/*
@@ -1244,21 +535,20 @@ static void __init do_boot_cpu(int i)
* the targeted processor.
*/
- dprintk("Setting warm reset code and vector.\n");
+ Dprintk("Setting warm reset code and vector.\n");
CMOS_WRITE(0xa, 0xf);
local_flush_tlb();
- dprintk("1.\n");
+ Dprintk("1.\n");
*((volatile unsigned short *) phys_to_virt(0x469)) = start_eip >> 4;
- dprintk("2.\n");
+ Dprintk("2.\n");
*((volatile unsigned short *) phys_to_virt(0x467)) = start_eip & 0xf;
- dprintk("3.\n");
+ Dprintk("3.\n");
/*
* Be paranoid about clearing APIC errors.
*/
-
- if (APIC_INTEGRATED(apic_version[i])) {
+ if (APIC_INTEGRATED(apic_version[apicid])) {
apic_readaround(APIC_SPIV);
apic_write(APIC_ESR, 0);
accept_status = (apic_read(APIC_ESR) & 0xEF);
@@ -1274,7 +564,7 @@ static void __init do_boot_cpu(int i)
* Starting actual IPI sequence...
*/
- dprintk("Asserting INIT.\n");
+ Dprintk("Asserting INIT.\n");
/*
* Turn INIT on
@@ -1285,7 +575,7 @@ static void __init do_boot_cpu(int i)
/*
* Target chip
*/
- apic_write(APIC_ICR2, cfg | SET_APIC_DEST_FIELD(i));
+ apic_write(APIC_ICR2, cfg | SET_APIC_DEST_FIELD(apicid));
/*
* Send IPI
@@ -1296,12 +586,12 @@ static void __init do_boot_cpu(int i)
apic_write(APIC_ICR, cfg);
udelay(200);
- dprintk("Deasserting INIT.\n");
+ Dprintk("Deasserting INIT.\n");
/* Target chip */
cfg = apic_read(APIC_ICR2);
cfg &= 0x00FFFFFF;
- apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i));
+ apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(apicid));
/* Send IPI */
cfg = apic_read(APIC_ICR);
@@ -1316,8 +606,7 @@ static void __init do_boot_cpu(int i)
* If we don't have an integrated APIC, don't
* send the STARTUP IPIs.
*/
-
- if (APIC_INTEGRATED(apic_version[i]))
+ if (APIC_INTEGRATED(apic_version[apicid]))
num_starts = 2;
else
num_starts = 0;
@@ -1325,13 +614,14 @@ static void __init do_boot_cpu(int i)
/*
* Run STARTUP IPI loop.
*/
+ Dprintk("#startup loops: %d.\n", num_starts);
for (j = 1; j <= num_starts; j++) {
- dprintk("Sending STARTUP #%d.\n",j);
+ Dprintk("Sending STARTUP #%d.\n",j);
apic_readaround(APIC_SPIV);
apic_write(APIC_ESR, 0);
apic_read(APIC_ESR);
- dprintk("After apic_write.\n");
+ Dprintk("After apic_write.\n");
/*
* STARTUP IPI
@@ -1340,7 +630,7 @@ static void __init do_boot_cpu(int i)
/* Target chip */
cfg = apic_read(APIC_ICR2);
cfg &= 0x00FFFFFF;
- apic_write(APIC_ICR2, cfg|SET_APIC_DEST_FIELD(i));
+ apic_write(APIC_ICR2, cfg | SET_APIC_DEST_FIELD(apicid));
/* Boot on the stack */
cfg = apic_read(APIC_ICR);
@@ -1350,12 +640,12 @@ static void __init do_boot_cpu(int i)
/* Kick the second */
apic_write(APIC_ICR, cfg);
- dprintk("Startup point 1.\n");
+ Dprintk("Startup point 1.\n");
- dprintk("Waiting for send to finish...\n");
+ Dprintk("Waiting for send to finish...\n");
timeout = 0;
do {
- dprintk("+");
+ Dprintk("+");
udelay(100);
send_status = apic_read(APIC_ICR) & 0x1000;
} while (send_status && (timeout++ < 1000));
@@ -1368,7 +658,7 @@ static void __init do_boot_cpu(int i)
if (send_status || accept_status)
break;
}
- dprintk("After Startup.\n");
+ Dprintk("After Startup.\n");
if (send_status)
printk("APIC never delivered???\n");
@@ -1379,24 +669,24 @@ static void __init do_boot_cpu(int i)
/*
* allow APs to start initializing.
*/
- dprintk("Before Callout %d.\n", i);
- set_bit(i, &cpu_callout_map);
- dprintk("After Callout %d.\n", i);
+ Dprintk("Before Callout %d.\n", cpu);
+ set_bit(cpu, &cpu_callout_map);
+ Dprintk("After Callout %d.\n", cpu);
/*
* Wait 5s total for a response
*/
- for (timeout = 0; timeout < 50000; timeout++) {
- if (test_bit(i, &cpu_callin_map))
+ for (timeout = 0; timeout < 1000000000; timeout++) {
+ if (test_bit(cpu, &cpu_callin_map))
break; /* It has booted */
udelay(100);
}
- if (test_bit(i, &cpu_callin_map)) {
+ if (test_bit(cpu, &cpu_callin_map)) {
/* number CPUs logically, starting from 1 (BSP is 0) */
- printk("OK.\n");
- printk("CPU%d: ", i);
- print_cpu_info(&cpu_data[i]);
+ Dprintk("OK.\n");
+ printk("CPU%d: ", cpu);
+ print_cpu_info(&cpu_data[cpu]);
} else {
if (*((volatile unsigned char *)phys_to_virt(8192))
== 0xA5) /* trampoline code not run */
@@ -1404,10 +694,10 @@ static void __init do_boot_cpu(int i)
else
printk("CPU booted but not responding.\n");
}
- dprintk("CPU has booted.\n");
+ Dprintk("CPU has booted.\n");
} else {
- __cpu_logical_map[cpucount] = -1;
- cpu_number_map[i] = -1;
+ x86_cpu_to_apicid[cpu] = -1;
+ x86_apicid_to_cpu[apicid] = -1;
cpucount--;
}
@@ -1462,7 +752,7 @@ extern int prof_counter[NR_CPUS];
void __init smp_boot_cpus(void)
{
- int i;
+ int apicid, cpu;
#ifdef CONFIG_MTRR
/* Must be done before other processors booted */
@@ -1473,58 +763,63 @@ void __init smp_boot_cpus(void)
* and the per-CPU profiling counter/multiplier
*/
- for (i = 0; i < NR_CPUS; i++) {
- cpu_number_map[i] = -1;
- prof_counter[i] = 1;
- prof_old_multiplier[i] = 1;
- prof_multiplier[i] = 1;
+ for (apicid = 0; apicid < NR_CPUS; apicid++) {
+ x86_apicid_to_cpu[apicid] = -1;
+ prof_counter[apicid] = 1;
+ prof_old_multiplier[apicid] = 1;
+ prof_multiplier[apicid] = 1;
}
/*
* Setup boot CPU information
*/
-
- smp_store_cpu_info(boot_cpu_id); /* Final full version of the data */
- smp_tune_scheduling();
- printk("CPU%d: ", boot_cpu_id);
- print_cpu_info(&cpu_data[boot_cpu_id]);
+ smp_store_cpu_info(0); /* Final full version of the data */
+ printk("CPU%d: ", 0);
+ print_cpu_info(&cpu_data[0]);
/*
- * not necessary because the MP table should list the boot
- * CPU too, but we do it for the sake of robustness anyway.
- * (and for the case when a non-SMP board boots an SMP kernel)
+ * We have the boot CPU online for sure.
*/
- cpu_present_map |= (1 << hard_smp_processor_id());
-
- cpu_number_map[boot_cpu_id] = 0;
-
+ set_bit(0, &cpu_online_map);
+ x86_apicid_to_cpu[boot_cpu_id] = 0;
+ x86_cpu_to_apicid[0] = boot_cpu_id;
+ global_irq_holder = 0;
+ current->processor = 0;
init_idle();
+ smp_tune_scheduling();
/*
* If we couldnt find an SMP configuration at boot time,
* get out of here now!
*/
-
if (!smp_found_config) {
printk(KERN_NOTICE "SMP motherboard not detected. Using dummy APIC emulation.\n");
#ifndef CONFIG_VISWS
io_apic_irqs = 0;
#endif
- cpu_online_map = cpu_present_map;
+ cpu_online_map = phys_cpu_present_map = 1;
smp_num_cpus = 1;
goto smp_done;
}
/*
- * If SMP should be disabled, then really disable it!
+ * Should not be necessary because the MP table should list the boot
+ * CPU too, but we do it for the sake of robustness anyway.
*/
+ if (!test_bit(boot_cpu_id, &phys_cpu_present_map)) {
+ printk("weird, boot CPU (#%d) not listed by the BIOS.\n",
+ boot_cpu_id);
+ phys_cpu_present_map |= (1 << hard_smp_processor_id());
+ }
+ /*
+ * If SMP should be disabled, then really disable it!
+ */
if (!max_cpus) {
smp_found_config = 0;
printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
}
-#ifdef SMP_DEBUG
{
int reg;
@@ -1536,11 +831,11 @@ void __init smp_boot_cpus(void)
*/
reg = apic_read(APIC_LVR);
- dprintk("Getting VERSION: %x\n", reg);
+ Dprintk("Getting VERSION: %x\n", reg);
apic_write(APIC_LVR, 0);
reg = apic_read(APIC_LVR);
- dprintk("Getting VERSION: %x\n", reg);
+ Dprintk("Getting VERSION: %x\n", reg);
/*
* The two version reads above should print the same
@@ -1553,14 +848,12 @@ void __init smp_boot_cpus(void)
* compatibility mode, but most boxes are anymore.
*/
-
reg = apic_read(APIC_LVT0);
- dprintk("Getting LVT0: %x\n", reg);
+ Dprintk("Getting LVT0: %x\n", reg);
reg = apic_read(APIC_LVT1);
- dprintk("Getting LVT1: %x\n", reg);
+ Dprintk("Getting LVT1: %x\n", reg);
}
-#endif
setup_local_APIC();
@@ -1570,42 +863,33 @@ void __init smp_boot_cpus(void)
/*
* Now scan the CPU present map and fire up the other CPUs.
*/
+ Dprintk("CPU present map: %lx\n", phys_cpu_present_map);
- /*
- * Add all detected CPUs. (later on we can down individual
- * CPUs which will change cpu_online_map but not necessarily
- * cpu_present_map. We are pretty much ready for hot-swap CPUs.)
- */
- cpu_online_map = cpu_present_map;
- mb();
-
- dprintk("CPU map: %lx\n", cpu_present_map);
-
- for (i = 0; i < NR_CPUS; i++) {
+ for (apicid = 0; apicid < NR_CPUS; apicid++) {
/*
* Don't even attempt to start the boot CPU!
*/
- if (i == boot_cpu_id)
+ if (apicid == boot_cpu_id)
continue;
- if ((cpu_online_map & (1 << i))
- && (max_cpus < 0 || max_cpus > cpucount+1)) {
- do_boot_cpu(i);
- }
+ if (!(phys_cpu_present_map & (1 << apicid)))
+ continue;
+ if ((max_cpus >= 0) && (max_cpus < cpucount+1))
+ continue;
+
+ do_boot_cpu(apicid);
/*
* Make sure we unmap all failed CPUs
*/
- if (cpu_number_map[i] == -1 && (cpu_online_map & (1 << i))) {
- printk("CPU #%d not responding - cannot use it.\n",i);
- cpu_online_map &= ~(1 << i);
- }
+ if ((x86_apicid_to_cpu[apicid] == -1) &&
+ (phys_cpu_present_map & (1 << apicid)))
+ printk("phys CPU #%d not responding - cannot use it.\n",apicid);
}
/*
* Cleanup possible dangling ends...
*/
-
#ifndef CONFIG_VISWS
{
/*
@@ -1627,27 +911,25 @@ void __init smp_boot_cpus(void)
* Allow the user to impress friends.
*/
- dprintk("Before bogomips.\n");
+ Dprintk("Before bogomips.\n");
if (!cpucount) {
printk(KERN_ERR "Error: only one processor found.\n");
- cpu_online_map = (1<<hard_smp_processor_id());
} else {
unsigned long bogosum = 0;
- for(i = 0; i < 32; i++)
- if (cpu_online_map&(1<<i))
- bogosum+=cpu_data[i].loops_per_sec;
+ for (cpu = 0; cpu < NR_CPUS; cpu++)
+ if (cpu_online_map & (1<<cpu))
+ bogosum += cpu_data[cpu].loops_per_sec;
printk(KERN_INFO "Total of %d processors activated (%lu.%02lu BogoMIPS).\n",
cpucount+1,
(bogosum+2500)/500000,
((bogosum+2500)/5000)%100);
- dprintk("Before bogocount - setting activated=1.\n");
- smp_activated = 1;
+ Dprintk("Before bogocount - setting activated=1.\n");
}
smp_num_cpus = cpucount + 1;
if (smp_b_stepping)
printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n");
- dprintk("Boot done.\n");
+ Dprintk("Boot done.\n");
cache_APIC_registers();
#ifndef CONFIG_VISWS
@@ -1661,12 +943,6 @@ void __init smp_boot_cpus(void)
smp_done:
/*
- * now we know the other CPUs have fired off and we know our
- * APIC ID, so we can go init the TSS and stuff:
- */
- cpu_init();
-
- /*
* Set up all local APIC timers in the system:
*/
setup_APIC_clocks();
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 903dcf15d..84e20b225 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -42,12 +42,14 @@
#include <linux/init.h>
#include <linux/smp.h>
-#include <asm/processor.h>
-#include <asm/uaccess.h>
#include <asm/io.h>
+#include <asm/smp.h>
#include <asm/irq.h>
-#include <asm/delay.h>
#include <asm/msr.h>
+#include <asm/delay.h>
+#include <asm/mpspec.h>
+#include <asm/uaccess.h>
+#include <asm/processor.h>
#include <linux/mc146818rtc.h>
#include <linux/timex.h>
@@ -368,7 +370,7 @@ static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *reg
* profiling, except when we simulate SMP mode on a uniprocessor
* system, in that case we have to call the local interrupt handler.
*/
-#ifndef __SMP__
+#ifndef CONFIG_X86_LOCAL_APIC
if (!user_mode(regs))
x86_do_profile(regs->eip);
#else
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 063e9fefb..17cac5019 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -138,7 +138,7 @@ static void show_registers(struct pt_regs *regs)
unsigned short ss;
unsigned long *stack, addr, module_start, module_end;
- esp = (unsigned long) (1+regs);
+ esp = (unsigned long) (&regs->esp);
ss = __KERNEL_DS;
if (regs->xcs & 3) {
in_kernel = 0;
@@ -337,7 +337,7 @@ static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
atomic_t nmi_counter[NR_CPUS];
-#if CONFIG_SMP
+#if CONFIG_X86_IO_APIC
int nmi_watchdog = 1;
@@ -388,7 +388,12 @@ inline void nmi_watchdog_tick(struct pt_regs * regs)
alert_counter[cpu]++;
if (alert_counter[cpu] == 5*HZ) {
spin_lock(&nmi_print_lock);
- console_lock.lock = 0; // we are in trouble anyway
+ /*
+ * We are in trouble anyway, lets at least try
+ * to get a message out.
+ */
+ spin_trylock(&console_lock);
+ spin_unlock(&console_lock);
printk("NMI Watchdog detected LOCKUP on CPU%d, registers:\n", cpu);
show_registers(regs);
printk("console shuts up ...\n");
@@ -409,7 +414,7 @@ asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
atomic_inc(nmi_counter+smp_processor_id());
if (!(reason & 0xc0)) {
-#if CONFIG_SMP
+#if CONFIG_X86_IO_APIC
/*
* Ok, so this is none of the documented NMI sources,
* so it must be the NMI watchdog.
@@ -600,7 +605,10 @@ void __init trap_init_f00f_bug(void)
pte = pte_offset(pmd, page);
__free_page(pte_page(*pte));
*pte = mk_pte_phys(__pa(&idt_table), PAGE_KERNEL_RO);
- local_flush_tlb();
+ /*
+ * Not that any PGE-capable kernel should have the f00f bug ...
+ */
+ __flush_tlb_all();
/*
* "idt" is magic - it overlaps the idt_descr
@@ -806,13 +814,9 @@ void __init trap_init(void)
set_call_gate(&default_ldt[4],lcall27);
/*
- * on SMP we do not yet know which CPU is on which TSS,
- * so we delay this until smp_init(). (the CPU is already
- * in a reasonable state, otherwise we wouldnt have gotten so far :)
+ * Should be a barrier for any external CPU state.
*/
-#ifndef __SMP__
cpu_init();
-#endif
#ifdef CONFIG_X86_VISWS_APIC
superio_init();
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index 618b36544..21c9cadff 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -16,6 +16,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/interrupt.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -76,7 +77,7 @@ bad_area:
return 0;
}
-static inline void handle_wp_test (void)
+static void __init handle_wp_test (void)
{
const unsigned long vaddr = PAGE_OFFSET;
pgd_t *pgd;
@@ -91,7 +92,7 @@ static inline void handle_wp_test (void)
pmd = pmd_offset(pgd, vaddr);
pte = pte_offset(pmd, vaddr);
*pte = mk_pte_phys(0, PAGE_KERNEL);
- local_flush_tlb();
+ __flush_tlb_all();
boot_cpu_data.wp_works_ok = 1;
/*
@@ -123,6 +124,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
unsigned long page;
unsigned long fixup;
int write;
+ int si_code = SEGV_MAPERR;
/* get the address */
__asm__("movl %%cr2,%0":"=r" (address));
@@ -164,6 +166,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code)
*/
good_area:
write = 0;
+ si_code = SEGV_ACCERR;
+
switch (error_code & 3) {
default: /* 3: write, present */
#ifdef TEST_VERIFY_AREA
@@ -216,10 +220,14 @@ bad_area:
/* User mode accesses just cause a SIGSEGV */
if (error_code & 4) {
+ struct siginfo si;
tsk->thread.cr2 = address;
tsk->thread.error_code = error_code;
tsk->thread.trap_no = 14;
- force_sig(SIGSEGV, tsk);
+ si.si_signo = SIGSEGV;
+ si.si_code = si_code;
+ si.si_addr = (void*) address;
+ force_sig_info(SIGSEGV, &si, tsk);
return;
}
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index b99daee84..b20ddc2d5 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -34,6 +34,7 @@
#include <asm/dma.h>
#include <asm/fixmap.h>
#include <asm/e820.h>
+#include <asm/apic.h>
unsigned long highstart_pfn, highend_pfn;
static unsigned long totalram_pages = 0;
@@ -194,8 +195,6 @@ void __init kmap_init(void)
kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
kmap_prot = PAGE_KERNEL;
- if (boot_cpu_data.x86_capability & X86_FEATURE_PGE)
- pgprot_val(kmap_prot) |= _PAGE_GLOBAL;
}
#endif
@@ -239,7 +238,8 @@ void show_mem(void)
extern char _text, _etext, _edata, __bss_start, _end;
extern char __init_begin, __init_end;
-static void set_pte_phys (unsigned long vaddr, unsigned long phys)
+static inline void set_pte_phys (unsigned long vaddr,
+ unsigned long phys, pgprot_t flags)
{
pgprot_t prot;
pgd_t *pgd;
@@ -249,26 +249,25 @@ static void set_pte_phys (unsigned long vaddr, unsigned long phys)
pgd = swapper_pg_dir + __pgd_offset(vaddr);
pmd = pmd_offset(pgd, vaddr);
pte = pte_offset(pmd, vaddr);
- prot = PAGE_KERNEL;
- if (boot_cpu_data.x86_capability & X86_FEATURE_PGE)
- pgprot_val(prot) |= _PAGE_GLOBAL;
+ pgprot_val(prot) = pgprot_val(PAGE_KERNEL) | pgprot_val(flags);
set_pte(pte, mk_pte_phys(phys, prot));
/*
* It's enough to flush this one mapping.
+ * (PGE mappings get flushed as well)
*/
__flush_tlb_one(vaddr);
}
-void set_fixmap (enum fixed_addresses idx, unsigned long phys)
+void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t flags)
{
unsigned long address = __fix_to_virt(idx);
if (idx >= __end_of_fixed_addresses) {
- printk("Invalid set_fixmap\n");
+ printk("Invalid __set_fixmap\n");
return;
}
- set_pte_phys(address,phys);
+ set_pte_phys(address, phys, flags);
}
static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
@@ -439,10 +438,10 @@ void __init paging_init(void)
set_in_cr4(X86_CR4_PAE);
#endif
- __flush_tlb();
+ __flush_tlb_all();
-#ifdef __SMP__
- init_smp_mappings();
+#ifdef CONFIG_X86_LOCAL_APIC
+ init_apic_mappings();
#endif
#ifdef CONFIG_HIGHMEM
diff --git a/arch/i386/vmlinux.lds b/arch/i386/vmlinux.lds
index 9624cae47..5790bb5d4 100644
--- a/arch/i386/vmlinux.lds
+++ b/arch/i386/vmlinux.lds
@@ -64,6 +64,12 @@ SECTIONS
}
_end = . ;
+ /* Sections to be discarded */
+ /DISCARD/ : {
+ *(.text.exit)
+ *(.data.exit)
+ }
+
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
index 81dc17103..cbccf3956 100644
--- a/arch/m68k/atari/stram.c
+++ b/arch/m68k/atari/stram.c
@@ -1255,6 +1255,8 @@ int __init stram_device_init(void)
blksize_size[STRAM_MAJOR] = stram_blocksizes;
stram_sizes[STRAM_MINOR] = (swap_end - swap_start)/1024;
blk_size[STRAM_MAJOR] = stram_sizes;
+ register_disk(NULL, MKDEV(STRAM_MAJOR, STRAM_MINOR), 1, &stram_fops,
+ (swap_end-swap_start)>>9);
do_z2_request(); /* to avoid warning */
return( 0 );
}
diff --git a/arch/m68k/config.in b/arch/m68k/config.in
index 2d6095694..52a083750 100644
--- a/arch/m68k/config.in
+++ b/arch/m68k/config.in
@@ -2,6 +2,9 @@
# For a description of the syntax of this configuration file,
# see the Configure script.
#
+
+define_bool CONFIG_UID16 y
+
mainmenu_name "Linux/68k Kernel Configuration"
mainmenu_option next_comment
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index 21acaa218..b3ef8ded3 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -425,15 +425,15 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_time)
.long SYMBOL_NAME(sys_mknod)
.long SYMBOL_NAME(sys_chmod) /* 15 */
- .long SYMBOL_NAME(sys_chown)
+ .long SYMBOL_NAME(sys_chown16)
.long SYMBOL_NAME(sys_ni_syscall) /* old break syscall holder */
.long SYMBOL_NAME(sys_stat)
.long SYMBOL_NAME(sys_lseek)
.long SYMBOL_NAME(sys_getpid) /* 20 */
.long SYMBOL_NAME(sys_mount)
.long SYMBOL_NAME(sys_oldumount)
- .long SYMBOL_NAME(sys_setuid)
- .long SYMBOL_NAME(sys_getuid)
+ .long SYMBOL_NAME(sys_setuid16)
+ .long SYMBOL_NAME(sys_getuid16)
.long SYMBOL_NAME(sys_stime) /* 25 */
.long SYMBOL_NAME(sys_ptrace)
.long SYMBOL_NAME(sys_alarm)
@@ -455,11 +455,11 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_times)
.long SYMBOL_NAME(sys_ni_syscall) /* old prof syscall holder */
.long SYMBOL_NAME(sys_brk) /* 45 */
- .long SYMBOL_NAME(sys_setgid)
- .long SYMBOL_NAME(sys_getgid)
+ .long SYMBOL_NAME(sys_setgid16)
+ .long SYMBOL_NAME(sys_getgid16)
.long SYMBOL_NAME(sys_signal)
- .long SYMBOL_NAME(sys_geteuid)
- .long SYMBOL_NAME(sys_getegid) /* 50 */
+ .long SYMBOL_NAME(sys_geteuid16)
+ .long SYMBOL_NAME(sys_getegid16) /* 50 */
.long SYMBOL_NAME(sys_acct)
.long SYMBOL_NAME(sys_umount) /* recycled never used phys() */
.long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */
@@ -479,18 +479,18 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_sigaction)
.long SYMBOL_NAME(sys_sgetmask)
.long SYMBOL_NAME(sys_ssetmask)
- .long SYMBOL_NAME(sys_setreuid) /* 70 */
- .long SYMBOL_NAME(sys_setregid)
+ .long SYMBOL_NAME(sys_setreuid16) /* 70 */
+ .long SYMBOL_NAME(sys_setregid16)
.long SYMBOL_NAME(sys_sigsuspend)
.long SYMBOL_NAME(sys_sigpending)
.long SYMBOL_NAME(sys_sethostname)
.long SYMBOL_NAME(sys_setrlimit) /* 75 */
- .long SYMBOL_NAME(sys_getrlimit)
+ .long SYMBOL_NAME(sys_old_getrlimit)
.long SYMBOL_NAME(sys_getrusage)
.long SYMBOL_NAME(sys_gettimeofday)
.long SYMBOL_NAME(sys_settimeofday)
- .long SYMBOL_NAME(sys_getgroups) /* 80 */
- .long SYMBOL_NAME(sys_setgroups)
+ .long SYMBOL_NAME(sys_getgroups16) /* 80 */
+ .long SYMBOL_NAME(sys_setgroups16)
.long SYMBOL_NAME(old_select)
.long SYMBOL_NAME(sys_symlink)
.long SYMBOL_NAME(sys_lstat)
@@ -504,7 +504,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_truncate)
.long SYMBOL_NAME(sys_ftruncate)
.long SYMBOL_NAME(sys_fchmod)
- .long SYMBOL_NAME(sys_fchown) /* 95 */
+ .long SYMBOL_NAME(sys_fchown16) /* 95 */
.long SYMBOL_NAME(sys_getpriority)
.long SYMBOL_NAME(sys_setpriority)
.long SYMBOL_NAME(sys_ni_syscall) /* old profil syscall holder */
@@ -547,8 +547,8 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_sysfs) /* 135 */
.long SYMBOL_NAME(sys_personality)
.long SYMBOL_NAME(sys_ni_syscall) /* for afs_syscall */
- .long SYMBOL_NAME(sys_setfsuid)
- .long SYMBOL_NAME(sys_setfsgid)
+ .long SYMBOL_NAME(sys_setfsuid16)
+ .long SYMBOL_NAME(sys_setfsgid16)
.long SYMBOL_NAME(sys_llseek) /* 140 */
.long SYMBOL_NAME(sys_getdents)
.long SYMBOL_NAME(sys_select)
@@ -573,14 +573,14 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_sched_rr_get_interval)
.long SYMBOL_NAME(sys_nanosleep)
.long SYMBOL_NAME(sys_mremap)
- .long SYMBOL_NAME(sys_setresuid)
- .long SYMBOL_NAME(sys_getresuid) /* 165 */
+ .long SYMBOL_NAME(sys_setresuid16)
+ .long SYMBOL_NAME(sys_getresuid16) /* 165 */
.long SYMBOL_NAME(sys_ni_syscall) /* for vm86 */
.long SYMBOL_NAME(sys_query_module)
.long SYMBOL_NAME(sys_poll)
.long SYMBOL_NAME(sys_nfsservctl)
- .long SYMBOL_NAME(sys_setresgid) /* 170 */
- .long SYMBOL_NAME(sys_getresgid)
+ .long SYMBOL_NAME(sys_setresgid16) /* 170 */
+ .long SYMBOL_NAME(sys_getresgid16)
.long SYMBOL_NAME(sys_prctl)
.long SYMBOL_NAME(sys_rt_sigreturn)
.long SYMBOL_NAME(sys_rt_sigaction)
@@ -591,7 +591,7 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_rt_sigsuspend)
.long SYMBOL_NAME(sys_pread) /* 180 */
.long SYMBOL_NAME(sys_pwrite)
- .long SYMBOL_NAME(sys_lchown);
+ .long SYMBOL_NAME(sys_lchown16);
.long SYMBOL_NAME(sys_getcwd)
.long SYMBOL_NAME(sys_capget)
.long SYMBOL_NAME(sys_capset) /* 185 */
@@ -600,6 +600,29 @@ SYMBOL_NAME_LABEL(sys_call_table)
.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
.long SYMBOL_NAME(sys_vfork) /* 190 */
+ .long SYMBOL_NAME(sys_getrlimit)
+ .long SYMBOL_NAME(sys_mmap2)
+ .long SYMBOL_NAME(sys_truncate64)
+ .long SYMBOL_NAME(sys_ftruncate64)
+ .long SYMBOL_NAME(sys_chown) /* 195 */
+ .long SYMBOL_NAME(sys_getuid)
+ .long SYMBOL_NAME(sys_getgid)
+ .long SYMBOL_NAME(sys_geteuid)
+ .long SYMBOL_NAME(sys_getegid)
+ .long SYMBOL_NAME(sys_setreuid) /* 200 */
+ .long SYMBOL_NAME(sys_setregid)
+ .long SYMBOL_NAME(sys_getgroups)
+ .long SYMBOL_NAME(sys_setgroups)
+ .long SYMBOL_NAME(sys_fchown)
+ .long SYMBOL_NAME(sys_setresuid) /* 205 */
+ .long SYMBOL_NAME(sys_getresuid)
+ .long SYMBOL_NAME(sys_setresgid)
+ .long SYMBOL_NAME(sys_getresgid)
+ .long SYMBOL_NAME(sys_lchown)
+ .long SYMBOL_NAME(sys_setuid) /* 210 */
+ .long SYMBOL_NAME(sys_setgid)
+ .long SYMBOL_NAME(sys_setfsuid)
+ .long SYMBOL_NAME(sys_setfsgid)
.rept NR_syscalls-(.-SYMBOL_NAME(sys_call_table))/4
.long SYMBOL_NAME(sys_ni_syscall)
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index 81014d9c8..bbff5d590 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -37,6 +37,7 @@
#include <linux/ptrace.h>
#include <linux/unistd.h>
#include <linux/stddef.h>
+#include <linux/highuid.h>
#include <asm/setup.h>
#include <asm/uaccess.h>
@@ -1048,6 +1049,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
info.si_code = SI_USER;
info.si_pid = current->p_pptr->pid;
info.si_uid = current->p_pptr->uid;
+ info.si_uid16 = high2lowuid(current->p_pptr->uid);
}
/* If the (new) signal is now blocked, requeue it. */
diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig
index 3fd8237b7..3c32d6c1a 100644
--- a/arch/mips64/defconfig
+++ b/arch/mips64/defconfig
@@ -13,6 +13,7 @@
# CONFIG_SGI_IP22 is not set
CONFIG_SGI_IP27=y
# CONFIG_SGI_SN0_N_MODE is not set
+CONFIG_DISCONTIGMEM=y
CONFIG_BOOT_ELF64=y
CONFIG_ARC64=y
CONFIG_COHERENT_IO=y
diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27
index 3fd8237b7..3c32d6c1a 100644
--- a/arch/mips64/defconfig-ip27
+++ b/arch/mips64/defconfig-ip27
@@ -13,6 +13,7 @@
# CONFIG_SGI_IP22 is not set
CONFIG_SGI_IP27=y
# CONFIG_SGI_SN0_N_MODE is not set
+CONFIG_DISCONTIGMEM=y
CONFIG_BOOT_ELF64=y
CONFIG_ARC64=y
CONFIG_COHERENT_IO=y
diff --git a/arch/mips64/sgi-ip27/ip27-pci.c b/arch/mips64/sgi-ip27/ip27-pci.c
index 45e9cd649..80868cf6a 100644
--- a/arch/mips64/sgi-ip27/ip27-pci.c
+++ b/arch/mips64/sgi-ip27/ip27-pci.c
@@ -1,4 +1,4 @@
-/* $Id: ip27-pci.c,v 1.5 2000/01/31 23:25:06 kanoj Exp $
+/* $Id: ip27-pci.c,v 1.7 2000/02/03 23:30:59 kanoj Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -172,6 +172,7 @@ void __init
pcibios_fixup_bus(struct pci_bus *b)
{
unsigned short command;
+ struct list_head *ln;
struct pci_dev *dev;
pci_fixup_irqs(pci_swizzle, pci_map_irq);
@@ -182,7 +183,8 @@ pcibios_fixup_bus(struct pci_bus *b)
* stop working if we program the controllers as not having
* PCI_COMMAND_MEMORY, so we have to fudge the mem_flags.
*/
- for (dev = b->devices; dev; dev = dev->sibling) {
+ for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
+ dev = pci_dev_b(ln);
if (PCI_FUNC(dev->devfn) == 0) {
if ((PCI_SLOT(dev->devfn) == 0) ||
(PCI_SLOT(dev->devfn) == 1)) {
@@ -208,6 +210,13 @@ pcibios_fixup_pbus_ranges(struct pci_bus * bus,
ranges->mem_end -= bus->resource[1]->start;
}
+int __init
+pcibios_enable_device(struct pci_dev *dev)
+{
+ /* Not needed, since we enable all devices at startup. */
+ return 0;
+}
+
void __init
pcibios_align_resource(void *data, struct resource *res, unsigned long size)
{
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 6552a7140..d62c07669 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -155,9 +155,6 @@ oak_config: clean_config
walnut_config: clean_config
ln -s configs/walnut_defconfig arch/ppc/defconfig
-tags:
- etags */*.c include/{asm,linux}/*.h arch/ppc/kernel/*.{c,h}
-
archclean:
rm -f arch/ppc/kernel/{mk_defs,ppc_defs.h,find_name,checks}
@$(MAKECOFFBOOT) clean
diff --git a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile
index b9868e6ac..12032930d 100644
--- a/arch/ppc/coffboot/Makefile
+++ b/arch/ppc/coffboot/Makefile
@@ -39,11 +39,13 @@ ifeq ($(CONFIG_PMAC),y)
hack-coff: hack-coff.c
$(HOSTCC) $(HOSTCFLAGS) -o hack-coff hack-coff.c
-znetboot: vmlinux.coff zImage
+znetboot: vmlinux.coff vmlinux.elf zImage
cp vmlinux.coff $(TFTPIMAGE)
+ cp vmlinux.elf $(TFTPIMAGE).elf
znetboot.initrd: vmlinux.coff.initrd
cp vmlinux.coff.initrd $(TFTPIMAGE)
+ cp vmlinux.elf.initrd $(TFTPIMAGE).elf
floppy: zImage
# mount -t hfs /dev/fd0 /mnt
diff --git a/arch/ppc/coffboot/chrpmain.c b/arch/ppc/coffboot/chrpmain.c
index fc5648944..bffb9d9ee 100644
--- a/arch/ppc/coffboot/chrpmain.c
+++ b/arch/ppc/coffboot/chrpmain.c
@@ -10,7 +10,6 @@
#include "zlib.h"
#include <asm/bootinfo.h>
#include <asm/processor.h>
-#define __KERNEL__
#include <asm/page.h>
extern void *finddevice(const char *);
diff --git a/arch/ppc/coffboot/coffmain.c b/arch/ppc/coffboot/coffmain.c
index 2bb4ea31d..b76ba5976 100644
--- a/arch/ppc/coffboot/coffmain.c
+++ b/arch/ppc/coffboot/coffmain.c
@@ -10,7 +10,6 @@
#include "zlib.h"
#include <asm/bootinfo.h>
#include <asm/processor.h>
-#define __KERNEL__
#include <asm/page.h>
extern void *finddevice(const char *);
diff --git a/arch/ppc/config.in b/arch/ppc/config.in
index fa98b5fcf..43a678c6d 100644
--- a/arch/ppc/config.in
+++ b/arch/ppc/config.in
@@ -2,6 +2,8 @@
# For a description of the syntax of this configuration file,
# see the Configure script.
#
+define_bool CONFIG_UID16 n
+
mainmenu_name "Linux/PowerPC Kernel Configuration"
mainmenu_option next_comment
@@ -91,10 +93,9 @@ if [ "$CONFIG_OAK" = "y" ]; then
fi
if [ "$CONFIG_8xx" = "y" ]; then
bool 'QSpan PCI' CONFIG_PCI
-else
- if [ "$CONFIG_APUS" != "y" ]; then
+fi
+if [ "$CONFIG_6xx" = "y" -a "$CONFIG_APUS" != "y" ]; then
define_bool CONFIG_PCI y
- fi
fi
bool 'Networking support' CONFIG_NET
@@ -112,11 +113,15 @@ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
source drivers/pci/Config.in
-source drivers/pcmcia/Config.in
+bool 'Support for hot-pluggable devices' CONFIG_HOTPLUG
+
+if [ "$CONFIG_HOTPLUG" = "y" ]; then
+ source drivers/pcmcia/Config.in
+fi
source drivers/parport/Config.in
-if [ "$CONFIG_8xx" != "y" ]; then
+if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then
bool 'Support for VGA Console' CONFIG_VGA_CONSOLE
bool 'Support for frame buffer devices' CONFIG_FB
if [ "$CONFIG_FB" = "y" ]; then
@@ -188,6 +193,8 @@ if [ "$CONFIG_SCSI" != "n" ]; then
fi
endmenu
+source drivers/ieee1394/Config.in
+
if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment
comment 'Network device support'
diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig
index 977626274..795aa5b83 100644
--- a/arch/ppc/configs/common_defconfig
+++ b/arch/ppc/configs/common_defconfig
@@ -45,11 +45,7 @@ CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
# CONFIG_BINFMT_MISC is not set
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG is not set
# CONFIG_PARPORT is not set
CONFIG_VGA_CONSOLE=y
CONFIG_FB=y
diff --git a/arch/ppc/configs/gemini_defconfig b/arch/ppc/configs/gemini_defconfig
index b3129c7a5..9850f61d8 100644
--- a/arch/ppc/configs/gemini_defconfig
+++ b/arch/ppc/configs/gemini_defconfig
@@ -46,11 +46,8 @@ CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
# CONFIG_BINFMT_MISC is not set
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
# CONFIG_PARPORT is not set
# CONFIG_VGA_CONSOLE is not set
# CONFIG_FB is not set
@@ -161,6 +158,7 @@ CONFIG_BLK_DEV_SR_VENDOR=y
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
# CONFIG_SCSI_MULTI_LUN is not set
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set
@@ -243,7 +241,6 @@ CONFIG_NCR885E=y
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_YELLOWFIN is not set
# CONFIG_RTL8139 is not set
# CONFIG_DM9102 is not set
# CONFIG_AT1700 is not set
@@ -251,6 +248,13 @@ CONFIG_NCR885E=y
# CONFIG_NET_ISA is not set
# CONFIG_NET_EISA is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
@@ -310,10 +314,20 @@ CONFIG_UNIX98_PTYS=y
CONFIG_UNIX98_PTY_COUNT=256
#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
# Mice
#
# CONFIG_BUSMOUSE is not set
# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
# CONFIG_QIC02_TAPE is not set
#
@@ -327,11 +341,6 @@ CONFIG_UNIX98_PTY_COUNT=256
# Video For Linux
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -341,9 +350,10 @@ CONFIG_UNIX98_PTY_COUNT=256
#
# CONFIG_FTAPE is not set
# CONFIG_DRM is not set
+# CONFIG_AGP is not set
#
-# Support for USB
+# USB support
#
# CONFIG_USB is not set
@@ -358,9 +368,9 @@ CONFIG_UNIX98_PTY_COUNT=256
# CONFIG_BFS_FS is not set
# CONFIG_FAT_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
-# CONFIG_UDF_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -370,16 +380,17 @@ CONFIG_DEVPTS_FS=y
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
# CONFIG_UFS_FS is not set
#
# Network File Systems
#
# CONFIG_CODA_FS is not set
-# CONFIG_NFS_FS is not set
+CONFIG_NFS_FS=y
# CONFIG_NFSD is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_LOCKD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
@@ -403,4 +414,4 @@ CONFIG_MSDOS_PARTITION=y
#
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
+CONFIG_XMON=y
diff --git a/arch/ppc/configs/oak_defconfig b/arch/ppc/configs/oak_defconfig
index 1c2daf125..5fe9be376 100644
--- a/arch/ppc/configs/oak_defconfig
+++ b/arch/ppc/configs/oak_defconfig
@@ -3,41 +3,44 @@
#
#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
# Platform support
#
CONFIG_PPC=y
-CONFIG_4xx=y
# CONFIG_6xx is not set
+CONFIG_4xx=y
# CONFIG_PPC64 is not set
# CONFIG_82xx is not set
# CONFIG_8xx is not set
-CONFIG_403=y
-# CONFIG_405 is not set
CONFIG_OAK=y
+# CONFIG_WALNUT is not set
+# CONFIG_PCI is not set
# CONFIG_SMP is not set
CONFIG_MACH_SPECIFIC=y
# CONFIG_MATH_EMULATION is not set
#
-# General setup
+# Loadable module support
#
-# CONFIG_EXPERIMENTAL is not set
CONFIG_MODULES=y
# CONFIG_MODVERSIONS is not set
CONFIG_KMOD=y
-# CONFIG_PCI is not set
+
+#
+# General setup
+#
CONFIG_NET=y
CONFIG_SYSCTL=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
-CONFIG_BINFMT_MISC=y
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG is not set
# CONFIG_PARPORT is not set
# CONFIG_VGA_CONSOLE is not set
# CONFIG_FB is not set
@@ -66,7 +69,6 @@ CONFIG_BINFMT_MISC=y
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_CPQ_DA is not set
#
# Additional Block Devices
@@ -77,7 +79,6 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_DEV_XD is not set
-# CONFIG_BLK_DEV_DAC960 is not set
CONFIG_PARIDE_PARPORT=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
@@ -108,12 +109,29 @@ CONFIG_SYN_COOKIES=y
# (it is safe to leave these untouched)
#
# CONFIG_SKB_LARGE is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
#
# SCSI support
@@ -140,15 +158,27 @@ CONFIG_NET_ETHERNET=y
# CONFIG_MACE is not set
# CONFIG_BMAC is not set
# CONFIG_NCR885E is not set
+CONFIG_OAKNET=y
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_RTL8139 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_EISA is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -162,6 +192,8 @@ CONFIG_NET_ETHERNET=y
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
#
# Wan interfaces
@@ -208,6 +240,10 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_BUSMOUSE is not set
# CONFIG_MOUSE is not set
# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
@@ -229,9 +265,10 @@ CONFIG_SERIAL_CONSOLE=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
#
-# USB drivers - not for the faint of heart
+# Support for USB
#
# CONFIG_USB is not set
@@ -239,13 +276,16 @@ CONFIG_SERIAL_CONSOLE=y
# Filesystems
#
# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_UDF_FS is not set
@@ -253,7 +293,8 @@ CONFIG_AUTOFS_FS=y
# CONFIG_NTFS_FS is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
-CONFIG_ROMFS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
@@ -274,8 +315,8 @@ CONFIG_LOCKD=y
# Partition Types
#
# CONFIG_PARTITION_ADVANCED is not set
-CONFIG_MAC_PARTITION=y
-CONFIG_MSDOS_PARTITION=y
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
diff --git a/arch/ppc/configs/pmac_defconfig b/arch/ppc/configs/pmac_defconfig
index 514843d00..e2b7c31bd 100644
--- a/arch/ppc/configs/pmac_defconfig
+++ b/arch/ppc/configs/pmac_defconfig
@@ -35,6 +35,7 @@ CONFIG_SYSVIPC=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
CONFIG_BINFMT_MISC=m
+CONFIG_HOTPLUG=y
#
# PCMCIA/Cardbus support
diff --git a/arch/ppc/configs/walnut_defconfig b/arch/ppc/configs/walnut_defconfig
index 66edd11b6..931e1a7a9 100644
--- a/arch/ppc/configs/walnut_defconfig
+++ b/arch/ppc/configs/walnut_defconfig
@@ -3,41 +3,44 @@
#
#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
# Platform support
#
CONFIG_PPC=y
-CONFIG_4xx=y
# CONFIG_6xx is not set
+CONFIG_4xx=y
# CONFIG_PPC64 is not set
# CONFIG_82xx is not set
# CONFIG_8xx is not set
-CONFIG_403=y
-# CONFIG_405 is not set
-CONFIG_OAK=y
+# CONFIG_OAK is not set
+CONFIG_WALNUT=y
+CONFIG_PCI=y
# CONFIG_SMP is not set
CONFIG_MACH_SPECIFIC=y
# CONFIG_MATH_EMULATION is not set
#
-# General setup
+# Loadable module support
#
-# CONFIG_EXPERIMENTAL is not set
CONFIG_MODULES=y
# CONFIG_MODVERSIONS is not set
CONFIG_KMOD=y
-CONFIG_PCI=y
+
+#
+# General setup
+#
CONFIG_NET=y
CONFIG_SYSCTL=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
-CONFIG_BINFMT_MISC=y
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_HOTPLUG is not set
# CONFIG_PARPORT is not set
# CONFIG_VGA_CONSOLE is not set
# CONFIG_FB is not set
@@ -66,7 +69,6 @@ CONFIG_BINFMT_MISC=y
# Please see Documentation/ide.txt for help/info on IDE drives
#
# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_CPQ_DA is not set
#
# Additional Block Devices
@@ -77,7 +79,6 @@ CONFIG_BLK_DEV_LOOP=y
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_DEV_XD is not set
-# CONFIG_BLK_DEV_DAC960 is not set
CONFIG_PARIDE_PARPORT=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
@@ -108,12 +109,29 @@ CONFIG_SYN_COOKIES=y
# (it is safe to leave these untouched)
#
# CONFIG_SKB_LARGE is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
#
#
#
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
#
# SCSI support
@@ -140,15 +158,27 @@ CONFIG_NET_ETHERNET=y
# CONFIG_MACE is not set
# CONFIG_BMAC is not set
# CONFIG_NCR885E is not set
+# CONFIG_OAKNET is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_RTL8139 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_EISA is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -162,6 +192,8 @@ CONFIG_NET_ETHERNET=y
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
#
# Wan interfaces
@@ -208,6 +240,10 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_BUSMOUSE is not set
# CONFIG_MOUSE is not set
# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
@@ -229,9 +265,10 @@ CONFIG_SERIAL_CONSOLE=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
#
-# USB drivers - not for the faint of heart
+# Support for USB
#
# CONFIG_USB is not set
@@ -239,13 +276,16 @@ CONFIG_SERIAL_CONSOLE=y
# Filesystems
#
# CONFIG_QUOTA is not set
-CONFIG_AUTOFS_FS=y
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_UDF_FS is not set
@@ -253,7 +293,8 @@ CONFIG_AUTOFS_FS=y
# CONFIG_NTFS_FS is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
-CONFIG_ROMFS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig
index 2a3aac0f7..795aa5b83 100644
--- a/arch/ppc/defconfig
+++ b/arch/ppc/defconfig
@@ -35,8 +35,8 @@ CONFIG_KMOD=y
#
# General setup
#
+# CONFIG_PCI is not set
CONFIG_PCI=y
-CONFIG_PCI_NAMES=y
CONFIG_NET=y
CONFIG_SYSCTL=y
CONFIG_SYSVIPC=y
@@ -45,11 +45,7 @@ CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
# CONFIG_BINFMT_MISC is not set
-
-#
-# PCMCIA/CardBus support
-#
-# CONFIG_PCMCIA is not set
+# CONFIG_HOTPLUG is not set
# CONFIG_PARPORT is not set
CONFIG_VGA_CONSOLE=y
CONFIG_FB=y
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index a41473fa5..7aaacfadb 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -57,8 +57,11 @@ ifdef CONFIG_SMP
O_OBJS += smp.o
endif
-ifeq ($(CONFIG_OAK),y)
- O_OBJS += oak_setup.o
+ifeq ($(CONFIG_4xx),y)
+ O_OBJS += ppc4xx_pic.o
+ ifeq ($(CONFIG_OAK),y)
+ O_OBJS += oak_setup.o
+ endif
endif
ifeq ($(CONFIG_8xx),y)
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 5ed04344e..cb92163d6 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -265,37 +265,29 @@ _GLOBAL(_switch)
SYNC
rfi
-/*
- * ret_from_int():
- *
- * Return from an interrupt (external interrupt and
- * decrementer). This checks the first argument so
- * we know if rtl_intercept wants us to check for
- * a bottom half, signals and so on (normal return) or
- * we're returning from a real-time interrupt or have
- * interrupts soft disabled so we cannot enter Linux.
- * -- Cort
- */
- .globl ret_from_int
-ret_from_int:
- cmpi 0,r3,0
- beq 10f
- /* we're allowed to do signal/bh checks */
- b ret_from_syscall
#ifdef __SMP__
.globl ret_from_smpfork
ret_from_smpfork:
bl schedule_tail
+ b ret_from_except
#endif
- .globl ret_from_syscall
-ret_from_syscall:
+ .globl ret_from_intercept
+ret_from_intercept:
+ /*
+ * We may be returning from RTL and cannot do the normal checks
+ * -- Cort
+ */
+ cmpi 0,r3,0
+ beq 10f
.globl ret_from_except
ret_from_except:
-0: mfmsr r30 /* Disable interrupts */
- rlwinm r30,r30,0,17,15 /* clear MSR_EE */
- SYNC /* Some chip revs need this... */
- mtmsr r30
- SYNC
+0: /* disable interrupts */
+ lis r30,int_control@h
+ ori r30,r30,int_control@l
+ lwz r30,0(r30)
+ mtlr r30
+ blrl
+
lwz r5,_MSR(r1)
andi. r5,r5,MSR_EE
beq 2f
@@ -317,9 +309,13 @@ lost_irq_ret:
bl do_bottom_half
.globl do_bottom_half_ret
do_bottom_half_ret:
-2: SYNC
- mtmsr r30 /* disable interrupts again */
- SYNC
+2: /* disable interrupts */
+ lis r30,int_control@h
+ ori r30,r30,int_control@l
+ lwz r30,0(r30)
+ mtlr r30
+ blrl
+
lwz r3,_MSR(r1) /* Returning to user mode? */
andi. r3,r3,MSR_PR
beq+ 10f /* if so, check need_resched and signals */
diff --git a/arch/ppc/kernel/gemini_pci.c b/arch/ppc/kernel/gemini_pci.c
index 3d6feed13..fb80dc493 100644
--- a/arch/ppc/kernel/gemini_pci.c
+++ b/arch/ppc/kernel/gemini_pci.c
@@ -229,13 +229,11 @@ __init void layout_bus( struct pci_bus *bus )
{
struct pci_dev *dev;
- if (!bus->devices && !bus->children)
- return;
-
io_base = ALIGN(io_base, 4*KB);
mem_base = ALIGN(mem_base, 4*KB);
- for( dev = bus->devices; dev; dev = dev->sibling ) {
+ pci_for_each_dev(dev)
+ {
if (((dev->class >> 16) != PCI_BASE_CLASS_BRIDGE) ||
((dev->class >> 8) == PCI_CLASS_BRIDGE_OTHER))
layout_dev( dev );
diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c
index fadddda8b..d7ca91780 100644
--- a/arch/ppc/kernel/gemini_setup.c
+++ b/arch/ppc/kernel/gemini_setup.c
@@ -330,7 +330,7 @@ void __init gemini_init_IRQ(void)
int i;
/* gemini has no 8259 */
- open_pic.irq_offset = 0;
+ open_pic_irq_offset = 0;
for( i=0; i < NR_IRQS; i++ )
irq_desc[i].handler = &open_pic;
openpic_init(1);
@@ -515,7 +515,7 @@ void gemini_post_irq(int irq)
* We do it this way since our irq_desc[irq].handler can change
* with RTL and no longer be open_pic -- Cort
*/
- if ( irq >= open_pic.irq_offset)
+ if ( irq >= open_pic_irq_offset)
openpic_eoi( smp_processor_id() );
}
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index 451a1cad4..a70ba8bfd 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -287,7 +287,8 @@ turn_on_mmu:
stw r2,GPR2(r21); \
stw r1,0(r21); \
tovirt(r1,r21); /* set new kernel sp */ \
- SAVE_4GPRS(3, r21);
+ SAVE_4GPRS(3, r21); \
+ SAVE_GPR(7, r21);
/*
* Note: code which follows this uses cr0.eq (set if from kernel),
* r21, r22 (SRR0), and r23 (SRR1).
@@ -374,7 +375,7 @@ HardwareInterrupt:
.globl do_IRQ_intercept
do_IRQ_intercept:
.long do_IRQ;
- .long ret_from_except
+ .long ret_from_intercept
#else
bl apus_interrupt_entry
#endif /* CONFIG_APUS */
@@ -424,7 +425,7 @@ Decrementer:
.globl timer_interrupt_intercept
timer_interrupt_intercept:
.long timer_interrupt
- .long ret_from_except
+ .long ret_from_intercept
STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
@@ -674,7 +675,6 @@ DataStoreTLBMiss:
transfer_to_handler:
stw r22,_NIP(r21)
stw r23,_MSR(r21)
- SAVE_GPR(7, r21)
SAVE_4GPRS(8, r21)
SAVE_8GPRS(12, r21)
SAVE_8GPRS(24, r21)
diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S
index abc651218..ba3284ad8 100644
--- a/arch/ppc/kernel/head_4xx.S
+++ b/arch/ppc/kernel/head_4xx.S
@@ -27,10 +27,8 @@
#include <linux/config.h>
#include <asm/processor.h>
-#include <asm/4xx.h>
-#include <asm/403gcx.h>
-#include <asm/405gp.h>
#include <asm/page.h>
+#include <asm/pgtable.h>
#include <asm/mmu.h>
#include "ppc_asm.h"
@@ -58,7 +56,7 @@
### execution begins here, the following registers contain valid, yet
### optional, information:
###
-### r3 - ???
+### r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
### r4 - Starting address of the init RAM disk
### r5 - Ending address of the init RAM disk
### r6 - Start of kernel command line string (e.g. "mem=96m")
@@ -80,17 +78,55 @@ _GLOBAL(_start)
li r24,0
- ## Establish exception vector base
+ ## We should still be executing code at physical address 0x0000xxxx
+ ## at this point. However, start_here is at virtual address
+ ## 0xC000xxxx. So, set up a TLB mapping to cover this once
+ ## translation is enabled.
+
+ lis r3,KERNELBASE@h # Load the kernel virtual address
+ addis r3,r3,KERNELBASE@l
+ tophys(r4,r3) # Load the kernel physical address
+
+ ## Save the existing PID and load the kernel PID.
+
+ mfspr r7,SPRN_PID # Save the old PID
+ li r0,0
+ mtspr SPRN_PID,r0 # Load the kernel PID
+
+ ## Configure and load entry into TLB slot 0.
- lis r0,KERNELBASE@h
- mtspr SPRN_EVPR,r0
+ clrrwi r4,r4,10 # Mask off the real page number
- ## Jump to the main PowerPC kernel start-up code
+ ## XXX - Temporarily set the TLB_I bit because of cache issues that
+ ## seem to foul-up the exception handling code.
+
+ ori r4,r4,(TLB_WR | TLB_EX | TLB_I) # Set the write and execute bits
-1: lis r7,start_here@ha
- addi r7,r7,start_here@l
- mtlr r7
- blr
+ clrrwi r3,r3,10 # Mask off the effective page number
+ ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
+
+ tlbwe r4,r0,TLB_DATA # Load the data portion of the entry
+ tlbwe r3,r0,TLB_TAG # Load the tag portion of the entry
+ isync
+
+ mtspr SPRN_PID,r7 # Restore the existing PID
+
+ ## Establish the exception vector base
+
+ lis r4,KERNELBASE@h # EVPR only uses the high 16-bits
+ tophys(r0,r4) # Use the physical address
+ mtspr SPRN_EVPR,r0
+
+ ## Enable the MMU and jump to the main PowerPC kernel start-up code
+
+ mfmsr r0 # Get the machine state register
+ ori r0,r0,(MSR_DR | MSR_IR) # Enable data and instr. translation
+ mtspr SPRN_SRR1,r0 # Set up the new machine state register
+ lis r0,start_here@h
+ ori r0,r0,start_here@l
+ mtspr SPRN_SRR0,r0 # Set up the new instruction pointer
+ rfi # Jump to start_here w/ translation on
+
###
### Exception vector entry code. This code runs with address translation
@@ -129,7 +165,8 @@ _GLOBAL(_start)
stw r2,GPR2(r21); /* Save r2 on the stack */\
stw r1,0(r21); \
tovirt(r1,r21); /* Set-up new kernel stack pointer */\
- SAVE_4GPRS(3, r21); /* Save r3 through r6 on the stack */
+ SAVE_4GPRS(3, r21); /* Save r3 through r6 on the stack */\
+ SAVE_GPR(7, r21); /* Save r7 on the stack */
## Common exception code for standard (non-critical) exceptions.
@@ -166,7 +203,7 @@ label:
START_EXCEPTION(n, label); \
STND_EXCEPTION_PROLOG; \
addi r3,r1,STACK_FRAME_OVERHEAD; \
- li r0,STND_EXC; \
+ li r7,STND_EXC; \
li r20,MSR_KERNEL; \
FINISH_EXCEPTION(func)
@@ -175,23 +212,10 @@ label:
START_EXCEPTION(n, label); \
CRIT_EXCEPTION_PROLOG; \
addi r3,r1,STACK_FRAME_OVERHEAD; \
- li r0,CRIT_EXC; \
+ li r7,CRIT_EXC; \
li r20,MSR_KERNEL; \
FINISH_EXCEPTION(func)
-
-#define INTR_EXCEPTION(n, label, func) \
- START_EXCEPTION(n, label); \
- STND_EXCEPTION_PROLOG; \
- addi r3,r1,STACK_FRAME_OVERHEAD; \
- li r0,STND_EXC; \
- li r20,MSR_KERNEL; \
- li r4,0; \
- bl transfer_to_handler; \
-_GLOBAL(do_IRQ_intercept); \
- .long func; \
- .long ret_from_except
-
###
### Exception vectors.
@@ -214,7 +238,7 @@ _GLOBAL(do_IRQ_intercept); \
mfspr r4,SPRN_DEAR # Grab the DEAR, save it, pass as arg2
stw r4,_DEAR(r21)
addi r3,r1,STACK_FRAME_OVERHEAD
- li r0,STND_EXC # This is a standard exception
+ li r7,STND_EXC # This is a standard exception
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR
FINISH_EXCEPTION(do_page_fault) # do_page_fault(regs, ESR, DEAR)
@@ -226,15 +250,24 @@ _GLOBAL(do_IRQ_intercept); \
mr r4,r22 # Pass SRR0 as arg2
mr r5,r23 # Pass SRR1 as arg3
addi r3,r1,STACK_FRAME_OVERHEAD
- li r0,STND_EXC # This is a standard exception
+ li r7,STND_EXC # This is a standard exception
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR
FINISH_EXCEPTION(do_page_fault) # do_page_fault(regs, SRR0, SRR1)
### 0x0500 - External Interrupt Exception
- INTR_EXCEPTION(0x0500, HardwareInterrupt, do_IRQ)
-
+ START_EXCEPTION(0x0500, HardwareInterrupt)
+ STND_EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r7,STND_EXC
+ li r20,MSR_KERNEL
+ li r4,0
+ bl transfer_to_handler
+_GLOBAL(do_IRQ_intercept)
+ .long do_IRQ
+ .long ret_from_intercept
+
### 0x0600 - Alignment Exception
START_EXCEPTION(0x0600, Alignment)
@@ -242,7 +275,7 @@ _GLOBAL(do_IRQ_intercept); \
mfspr r4,SPRN_DEAR # Grab the DEAR and save it
stw r4,_DEAR(r21)
addi r3,r1,STACK_FRAME_OVERHEAD
- li r0,STND_EXC # This is a standard exception
+ li r7,STND_EXC # This is a standard exception
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR
FINISH_EXCEPTION(AlignmentException)
@@ -252,7 +285,7 @@ _GLOBAL(do_IRQ_intercept); \
START_EXCEPTION(0x0700, ProgramCheck)
STND_EXCEPTION_PROLOG
addi r3,r1,STACK_FRAME_OVERHEAD
- li r0,STND_EXC # This is a standard exception
+ li r7,STND_EXC # This is a standard exception
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR
FINISH_EXCEPTION(ProgramCheckException)
@@ -266,7 +299,7 @@ _GLOBAL(do_IRQ_intercept); \
START_EXCEPTION(0x0C00, SystemCall)
STND_EXCEPTION_PROLOG
stw r3,ORIG_GPR3(r21)
- li r0,STND_EXC # This is a standard exception
+ li r7,STND_EXC # This is a standard exception
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR
FINISH_EXCEPTION(DoSyscall)
@@ -275,11 +308,21 @@ _GLOBAL(do_IRQ_intercept); \
STND_EXCEPTION(0x0E00, Trap_0E, UnknownException)
STND_EXCEPTION(0x0F00, Trap_0F, UnknownException)
-#if 0
### 0x1000 - Programmable Interval Timer (PIT) Exception
- STND_EXCEPTION(0x1000, PITException, UnknownException)
+ START_EXCEPTION(0x1000, Decrementer)
+ STND_EXCEPTION_PROLOG
+ lis r0,TSR_PIS@h # Set-up the PIT exception mask
+ mtspr SPRN_TSR,r0 # Clear the PIT exception
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r7,STND_EXC # This is a standard exception
+ li r20,MSR_KERNEL
+ bl transfer_to_handler
+_GLOBAL(timer_interrupt_intercept)
+ .long timer_interrupt
+ .long ret_from_intercept
+#if 0
### 0x1010 - Fixed Interval Timer (FIT) Exception
STND_EXCEPTION(0x1010, FITException, UnknownException)
@@ -294,7 +337,7 @@ _GLOBAL(do_IRQ_intercept); \
START_EXCEPTION(0x1100, DTLBMiss)
STND_EXCEPTION_PROLOG
addi r3,r1,STACK_FRAME_OVERHEAD
- li r0,STND_EXC
+ li r7,STND_EXC
li r20,MSR_KERNEL
FINISH_EXCEPTION(UnknownException)
@@ -303,7 +346,7 @@ _GLOBAL(do_IRQ_intercept); \
START_EXCEPTION(0x1200, ITLBMiss)
STND_EXCEPTION_PROLOG
addi r3,r1,STACK_FRAME_OVERHEAD
- li r0,STND_EXC
+ li r7,STND_EXC
li r20,MSR_KERNEL
FINISH_EXCEPTION(UnknownException)
@@ -341,7 +384,6 @@ _GLOBAL(do_IRQ_intercept); \
_GLOBAL(transfer_to_handler)
stw r22,_NIP(r21) # Save the faulting IP on the stack
stw r23,_MSR(r21) # Save the exception MSR on the stack
- SAVE_GPR(7, r21) # Save r7 on the stack
SAVE_4GPRS(8, r21) # Save r8 through r11 on the stack
SAVE_8GPRS(12, r21) # Save r12 through r19 on the stack
SAVE_8GPRS(24, r21) # Save r24 through r31 on the stack
@@ -367,7 +409,7 @@ _GLOBAL(transfer_to_handler)
bgt- stack_ovf # If r2 < r1 < r2 + TASK_STRUCT_SIZE
lwz r24,0(r23) # Virtual address of the handler
lwz r23,4(r23) # Handler return pointer
- cmpwi cr0,r0,STND_EXC # What type of exception is this?
+ cmpwi cr0,r7,STND_EXC # What type of exception is this?
bne 3f # It is a critical exception...
## Standard exception jump path
@@ -432,67 +474,10 @@ _GLOBAL(giveup_fpu)
_GLOBAL(abort)
mfspr r13,SPRN_DBCR
- ori r13,r13,DBCR_RST(SYSTEM)@h
+ oris r13,r13,DBCR_RST(DBCR_RST_SYSTEM)@h
mtspr SPRN_DBCR,r13
-
-###
-### This code is jumped-to from the startup code. It copies the kernel
-### image from wherever it happens to be currently running at in physical
-### address space to physical address 0.
-###
-### In general, for a running Linux/PPC system:
-### Kernel Physical Address (KPA) = 0x00000000
-### Kernel Virtual Address (KVA) = 0xC0000000
-###
-
-#if 0
-relocate_kernel:
- lis r9,0x426f /* if booted from BootX, don't */
- addi r9,r9,0x6f58 /* translate source addr */
- cmpw r31,r9 /* (we have to on chrp) */
- beq 7f
- rlwinm r4,r4,0,8,31 /* translate source address */
- add r4,r4,r3 /* to region mapped with BATs */
-7: addis r9,r26,klimit@ha /* fetch klimit */
- lwz r25,klimit@l(r9)
- addis r25,r25,-KERNELBASE@h
- li r6,0 /* Destination offset */
- li r5,0x4000 /* # bytes of memory to copy */
- bl copy_and_flush /* copy the first 0x4000 bytes */
- addi r0,r3,4f@l /* jump to the address of 4f */
- mtctr r0 /* in copy and do the rest. */
- bctr /* jump to the copy */
-4: mr r5,r25
- bl copy_and_flush /* copy the rest */
- b turn_on_mmu
-/*
- * Copy routine used to copy the kernel to start at physical address 0
- * and flush and invalidate the caches as needed.
- * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
- * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
- */
-copy_and_flush:
- addi r5,r5,-4
- addi r6,r6,-4
-4: li r0,8
- mtctr r0
-3: addi r6,r6,4 /* copy a cache line */
- lwzx r0,r6,r4
- stwx r0,r6,r3
- bdnz 3b
- dcbst r6,r3 /* write it to memory */
- sync
- icbi r6,r3 /* flush the icache line */
- cmplw 0,r6,r5
- blt 4b
- isync
- addi r5,r5,4
- addi r6,r6,4
- blr
-#endif
-
###
### This is where the main kernel code starts.
###
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
index c5a55c6a2..94cd67d3b 100644
--- a/arch/ppc/kernel/head_8xx.S
+++ b/arch/ppc/kernel/head_8xx.S
@@ -197,7 +197,8 @@ turn_on_mmu:
stw r2,GPR2(r21); \
stw r1,0(r21); \
tovirt(r1,r21); /* set new kernel sp */ \
- SAVE_4GPRS(3, r21);
+ SAVE_4GPRS(3, r21); \
+ SAVE_GPR(7, r21);
/*
* Note: code which follows this uses cr0.eq (set if from kernel),
* r21, r22 (SRR0), and r23 (SRR1).
@@ -265,34 +266,6 @@ InstructionAccess:
. = 0x500;
HardwareInterrupt:
EXCEPTION_PROLOG;
-#ifdef CONFIG_APUS
- /* This is horrible, but there's no way around it. Enable the
- data cache so the IRQ hardware register can be accessed
- without cache intervention. Then disable interrupts and get
- the current emulated m68k IPL value. */
-
- mfmsr 20
- xori r20,r20,MSR_DR
- sync
- mtmsr r20
- sync
-
- lis r3,APUS_IPL_EMU@h
-
- li r20,(IPLEMU_SETRESET|IPLEMU_DISABLEINT)
- stb r20,APUS_IPL_EMU@l(r3)
- eieio
-
- lbz r3,APUS_IPL_EMU@l(r3)
-
- mfmsr r20
- xori r20,r20,MSR_DR
- sync
- mtmsr r20
- sync
-
- stw r3,(_CCR+4)(r21);
-#endif
addi r3,r1,STACK_FRAME_OVERHEAD
li r20,MSR_KERNEL
li r4,0
@@ -300,7 +273,7 @@ HardwareInterrupt:
.globl do_IRQ_intercept
do_IRQ_intercept:
.long do_IRQ;
- .long ret_from_except
+ .long ret_from_intercept
/* Alignment exception */
@@ -342,7 +315,7 @@ Decrementer:
.globl timer_interrupt_intercept
timer_interrupt_intercept:
.long timer_interrupt
- .long ret_from_except
+ .long ret_from_intercept
STD_EXCEPTION(0xa00, Trap_0a, UnknownException)
STD_EXCEPTION(0xb00, Trap_0b, UnknownException)
@@ -591,7 +564,6 @@ transfer_to_handler:
lis r22,MSR_POW@h
andc r23,r23,r22
stw r23,_MSR(r21)
- SAVE_GPR(7, r21)
SAVE_4GPRS(8, r21)
SAVE_8GPRS(12, r21)
SAVE_8GPRS(24, r21)
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index a09d6ad98..c2f2d1c11 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -294,11 +294,10 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
}
}
-asmlinkage void do_IRQ(struct pt_regs *regs, int isfake)
+asmlinkage int do_IRQ(struct pt_regs *regs, int isfake)
{
int cpu = smp_processor_id();
int irq;
-
hardirq_enter( cpu );
/* every arch is required to have a get_irq -- Cort */
@@ -320,10 +319,9 @@ asmlinkage void do_IRQ(struct pt_regs *regs, int isfake)
out:
hardirq_exit( cpu );
+ return 1; /* lets ret_from_int know we can do checks */
}
-
-
unsigned long probe_irq_on (void)
{
return 0;
diff --git a/arch/ppc/kernel/oak_setup.c b/arch/ppc/kernel/oak_setup.c
index a9c9137a0..ad2c224bb 100644
--- a/arch/ppc/kernel/oak_setup.c
+++ b/arch/ppc/kernel/oak_setup.c
@@ -7,26 +7,74 @@
* Description:
* Architecture- / platform-specific boot-time initialization code for
* the IBM PowerPC 403GCX "Oak" evaluation board. Adapted from original
- * code by Gary Thomas, Cort Dougan <cort@cs.nmt.edu>, and Dan Malek
- * <dmalek@jlc.net>.
+ * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek
+ * <dan@net4x.com>.
*
*/
#include <linux/config.h>
#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/threads.h>
+#include <linux/interrupt.h>
+#include <linux/param.h>
#include <linux/string.h>
+#include <asm/processor.h>
+#include <asm/board.h>
#include <asm/machdep.h>
#include <asm/page.h>
+#include "local_irq.h"
+#include "ppc4xx_pic.h"
+#include "time.h"
#include "oak_setup.h"
+/* Function Prototypes */
+extern void abort(void);
+
+/* Global Variables */
+
+unsigned char __res[sizeof(bd_t)];
+
+
+/*
+ * void __init oak_init()
+ *
+ * Description:
+ * This routine...
+ *
+ * Input(s):
+ * r3 - Optional pointer to a board information structure.
+ * r4 - Optional pointer to the physical starting address of the init RAM
+ * disk.
+ * r5 - Optional pointer to the physical ending address of the init RAM
+ * disk.
+ * r6 - Optional pointer to the physical starting address of any kernel
+ * command-line parameters.
+ * r7 - Optional pointer to the physical ending address of any kernel
+ * command-line parameters.
+ *
+ * Output(s):
+ * N/A
+ *
+ * Returns:
+ * N/A
+ *
+ */
void __init
oak_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
-#if 0
+ /*
+ * If we were passed in a board information, copy it into the
+ * residual data area.
+ */
+ if (r3) {
+ memcpy((void *)__res, (void *)(r3 + KERNELBASE), sizeof(bd_t));
+ }
+
#if defined(CONFIG_BLK_DEV_INITRD)
/*
* If the init RAM disk has been configured in, and there's a valid
@@ -44,24 +92,25 @@ oak_init(unsigned long r3, unsigned long r4, unsigned long r5,
*(char *)(r7 + KERNELBASE) = 0;
strcpy(cmd_line, (char *)(r6 + KERNELBASE));
}
-#endif /* 0 */
+
+ /* Initialize machine-dependency vectors */
ppc_md.setup_arch = oak_setup_arch;
- ppc_md.setup_residual = NULL;
+ ppc_md.setup_residual = oak_setup_residual;
ppc_md.get_cpuinfo = NULL;
ppc_md.irq_cannonicalize = NULL;
- ppc_md.init_IRQ = NULL;
- ppc_md.get_irq = NULL;
+ ppc_md.init_IRQ = oak_init_IRQ;
+ ppc_md.get_irq = oak_get_irq;
ppc_md.init = NULL;
- ppc_md.restart = NULL;
- ppc_md.power_off = NULL;
- ppc_md.halt = NULL;
+ ppc_md.restart = oak_restart;
+ ppc_md.power_off = oak_power_off;
+ ppc_md.halt = oak_halt;
- ppc_md.time_init = NULL;
- ppc_md.set_rtc_time = NULL;
- ppc_md.get_rtc_time = NULL;
- ppc_md.calibrate_decr = NULL;
+ ppc_md.time_init = oak_time_init;
+ ppc_md.set_rtc_time = oak_set_rtc_time;
+ ppc_md.get_rtc_time = oak_get_rtc_time;
+ ppc_md.calibrate_decr = oak_calibrate_decr;
ppc_md.kbd_setkeycode = NULL;
ppc_md.kbd_getkeycode = NULL;
@@ -77,8 +126,168 @@ oak_init(unsigned long r3, unsigned long r4, unsigned long r5,
return;
}
+/*
+ * Document me.
+ */
void __init
oak_setup_arch(void)
{
+ /* XXX - Implement me */
+}
+
+/*
+ * int oak_setup_residual()
+ *
+ * Description:
+ * This routine pretty-prints the platform's internal CPU and bus clock
+ * frequencies into the buffer for usage in /proc/cpuinfo.
+ *
+ * Input(s):
+ * *buffer - Buffer into which CPU and bus clock frequencies are to be
+ * printed.
+ *
+ * Output(s):
+ * *buffer - Buffer with the CPU and bus clock frequencies.
+ *
+ * Returns:
+ * The number of bytes copied into 'buffer' if OK, otherwise zero or less
+ * on error.
+ */
+int
+oak_setup_residual(char *buffer)
+{
+ int len = 0;
+ bd_t *bp = (bd_t *)__res;
+
+ len += sprintf(len + buffer,
+ "clock\t\t: %dMHz\n"
+ "bus clock\t\t: %dMHz\n",
+ bp->bi_intfreq / 1000000,
+ bp->bi_busfreq / 1000000);
+
+ return (len);
+}
+
+/*
+ * Document me.
+ */
+void __init
+oak_init_IRQ(void)
+{
+ int i;
+
+ ppc4xx_pic_init();
+
+ for (i = 0; i < NR_IRQS; i++) {
+ irq_desc[i].handler = ppc4xx_pic;
+ }
+
+ return;
+}
+
+/*
+ * Document me.
+ */
+int
+oak_get_irq(struct pt_regs *regs)
+{
+ return (ppc4xx_pic_get_irq(regs));
+}
+
+/*
+ * Document me.
+ */
+void
+oak_restart(char *cmd)
+{
+ abort();
+}
+
+/*
+ * Document me.
+ */
+void
+oak_power_off(void)
+{
+ oak_restart(NULL);
+}
+
+/*
+ * Document me.
+ */
+void
+oak_halt(void)
+{
+ oak_restart(NULL);
+}
+
+/*
+ * Document me.
+ */
+void __init
+oak_time_init(void)
+{
+ /* XXX - Implement me */
+}
+
+/*
+ * Document me.
+ */
+int __init
+oak_set_rtc_time(unsigned long time)
+{
+ /* XXX - Implement me */
+
+ return (0);
+}
+
+/*
+ * Document me.
+ */
+unsigned long __init
+oak_get_rtc_time(void)
+{
+ /* XXX - Implement me */
+
+ return (0);
+}
+
+/*
+ * void __init oak_calibrate_decr()
+ *
+ * Description:
+ * This routine retrieves the internal processor frequency from the board
+ * information structure, sets up the kernel timer decrementer based on
+ * that value, enables the 403 programmable interval timer (PIT) and sets
+ * it up for auto-reload.
+ *
+ * Input(s):
+ * N/A
+ *
+ * Output(s):
+ * N/A
+ *
+ * Returns:
+ * N/A
+ *
+ */
+void __init
+oak_calibrate_decr(void)
+{
+ unsigned int freq;
+ bd_t *bip = (bd_t *)__res;
+
+ freq = bip->bi_intfreq;
+
+ decrementer_count = freq / HZ;
+ count_period_num = 1;
+ count_period_den = freq;
+
+ /* Enable the PIT and set auto-reload of its value */
+
+ mtspr(SPRN_TCR, TCR_PIE | TCR_ARE);
+
+ /* Clear any pending timer interrupts */
+ mtspr(SPRN_TSR, TSR_ENW | TSR_WIS | TSR_PIS | TSR_FIS);
}
diff --git a/arch/ppc/kernel/oak_setup.h b/arch/ppc/kernel/oak_setup.h
index 10f7d7354..62cfac906 100644
--- a/arch/ppc/kernel/oak_setup.h
+++ b/arch/ppc/kernel/oak_setup.h
@@ -15,14 +15,32 @@
#ifndef __OAK_SETUP_H__
#define __OAK_SETUP_H__
+#include <asm/ptrace.h>
+#include <asm/board.h>
+
+
#ifdef __cplusplus
extern "C" {
#endif
-extern void oak_init(unsigned long r3,
- unsigned long ird_start, unsigned long ird_end,
- unsigned long cline_start, unsigned long cline_end);
-extern void oak_setup_arch(void);
+extern unsigned char __res[sizeof(bd_t)];
+
+extern void oak_init(unsigned long r3,
+ unsigned long ird_start,
+ unsigned long ird_end,
+ unsigned long cline_start,
+ unsigned long cline_end);
+extern void oak_setup_arch(void);
+extern int oak_setup_residual(char *buffer);
+extern void oak_init_IRQ(void);
+extern int oak_get_irq(struct pt_regs *regs);
+extern void oak_restart(char *cmd);
+extern void oak_power_off(void);
+extern void oak_halt(void);
+extern void oak_time_init(void);
+extern int oak_set_rtc_time(unsigned long now);
+extern unsigned long oak_get_rtc_time(void);
+extern void oak_calibrate_decr(void);
#ifdef __cplusplus
diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c
index 02e276729..6857aa36f 100644
--- a/arch/ppc/kernel/open_pic.c
+++ b/arch/ppc/kernel/open_pic.c
@@ -38,6 +38,7 @@ struct hw_interrupt_type open_pic = {
0,
0
};
+int open_pic_irq_offset;
/*
* Accesses to the current processor's registers
@@ -69,7 +70,7 @@ struct hw_interrupt_type open_pic = {
* -- Cort
*/
#define check_arg_irq(irq) \
- /*if (irq < 0 || irq >= (NumSources+open_pic.irq_offset)) \
+ /*if (irq < 0 || irq >= (NumSources+open_pic_irq_offset)) \
printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq);*/
#define check_arg_cpu(cpu) \
if (cpu < 0 || cpu >= NumProcessors) \
@@ -212,11 +213,11 @@ void __init openpic_init(int main_pic)
/* Initialize external interrupts */
if ( ppc_md.progress ) ppc_md.progress("openpic ext",0x3bc);
/* SIOint (8259 cascade) is special */
- openpic_initirq(0, 8, open_pic.irq_offset, 1, 1);
+ openpic_initirq(0, 8, open_pic_irq_offset, 1, 1);
openpic_mapirq(0, 1<<0);
for (i = 1; i < NumSources; i++) {
/* Enabled, Priority 8 */
- openpic_initirq(i, 8, open_pic.irq_offset+i, 0,
+ openpic_initirq(i, 8, open_pic_irq_offset+i, 0,
i < OpenPIC_NumInitSenses ? OpenPIC_InitSenses[i] : 1);
/* Processor 0 */
openpic_mapirq(i, 1<<0);
@@ -416,13 +417,13 @@ void openpic_maptimer(u_int timer, u_int cpumask)
void openpic_enable_irq(u_int irq)
{
check_arg_irq(irq);
- openpic_clearfield(&OpenPIC->Source[irq-irq_desc[irq].handler->irq_offset].Vector_Priority, OPENPIC_MASK);
+ openpic_clearfield(&OpenPIC->Source[irq - open_pic_irq_offset].Vector_Priority, OPENPIC_MASK);
}
void openpic_disable_irq(u_int irq)
{
check_arg_irq(irq);
- openpic_setfield(&OpenPIC->Source[irq-irq_desc[irq].handler->irq_offset].Vector_Priority, OPENPIC_MASK);
+ openpic_setfield(&OpenPIC->Source[irq - open_pic_irq_offset].Vector_Priority, OPENPIC_MASK);
}
/*
diff --git a/arch/ppc/kernel/open_pic.h b/arch/ppc/kernel/open_pic.h
index 2673263cf..3e51ffba3 100644
--- a/arch/ppc/kernel/open_pic.h
+++ b/arch/ppc/kernel/open_pic.h
@@ -7,4 +7,5 @@ void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
void openpic_enable_IPI(u_int ipi);
void do_openpic_setup_cpu(void);
+extern int open_pic_irq_offset;
#endif /* _PPC_KERNEL_OPEN_PIC_H */
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index ec1ff3565..6c98bbf2c 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -9,6 +9,7 @@
#include <linux/string.h>
#include <linux/init.h>
#include <linux/openpic.h>
+#include <linux/errno.h>
#include <asm/processor.h>
#include <asm/io.h>
@@ -21,7 +22,7 @@
#include "pci.h"
-static void __init pcibios_claim_resources(struct pci_bus *);
+static void __init pcibios_claim_resources(struct list_head *);
unsigned long isa_io_base = 0;
unsigned long isa_mem_base = 0;
@@ -69,10 +70,9 @@ struct pci_ops generic_pci_ops =
void __init pcibios_init(void)
{
printk("PCI: Probing PCI hardware\n");
- ioport_resource.end = ~0L;
pci_scan_bus(0, &generic_pci_ops, NULL);
- pcibios_claim_resources(pci_root);
- if ( ppc_md.pcibios_fixup )
+ pcibios_claim_resources(&pci_root_buses);
+ if (ppc_md.pcibios_fixup)
ppc_md.pcibios_fixup();
}
@@ -162,3 +162,75 @@ void __init
pcibios_align_resource(void *data, struct resource *res, unsigned long size)
{
}
+
+int pcibios_enable_device(struct pci_dev *dev)
+{
+ u16 cmd, old_cmd;
+ int idx;
+ struct resource *r;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ old_cmd = cmd;
+ for (idx=0; idx<6; idx++) {
+ r = &dev->resource[idx];
+ if (!r->start && r->end) {
+ printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ cmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+ if (cmd != old_cmd) {
+ printk("PCI: Enabling device %s (%04x -> %04x)\n",
+ dev->slot_name, old_cmd, cmd);
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ }
+ return 0;
+}
+
+/*
+ * Assign new address to PCI resource. We hope our resource information
+ * is complete. We don't re-assign resources unless we are
+ * forced to do so.
+ *
+ * Expects start=0, end=size-1, flags=resource type.
+ */
+
+int pci_assign_resource(struct pci_dev *dev, int i)
+{
+ struct resource *r = &dev->resource[i];
+ struct resource *pr = pci_find_parent_resource(dev, r);
+ unsigned long size = r->end + 1;
+ u32 new, check;
+
+ if (!pr) {
+ printk(KERN_ERR "PCI: Cannot find parent resource for device %s\n", dev->slot_name);
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO) {
+ if (allocate_resource(pr, r, size, 0x100, ~0, size, NULL, NULL)) {
+ printk(KERN_ERR "PCI: Allocation of I/O region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size);
+ return -EBUSY;
+ }
+ } else {
+ if (allocate_resource(pr, r, size, 0x10000, ~0, size, NULL, NULL)) {
+ printk(KERN_ERR "PCI: Allocation of memory region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size);
+ return -EBUSY;
+ }
+ }
+ if (i < 6) {
+ int reg = PCI_BASE_ADDRESS_0 + 4*i;
+ new = r->start | (r->flags & PCI_REGION_FLAG_MASK);
+ pci_write_config_dword(dev, reg, new);
+ pci_read_config_dword(dev, reg, &check);
+ if (new != check)
+ printk(KERN_ERR "PCI: Error while updating region %s/%d (%08x != %08x)\n", dev->slot_name, i, new, check);
+ } else if (i == PCI_ROM_RESOURCE) {
+ r->flags |= PCI_ROM_ADDRESS_ENABLE;
+ pci_write_config_dword(dev, dev->rom_base_reg, r->start | (r->flags & PCI_REGION_FLAG_MASK));
+ }
+ printk("PCI: Assigned addresses %08lx-%08lx to region %s/%d\n", r->start, r->end, dev->slot_name, i);
+ return 0;
+}
diff --git a/arch/ppc/kernel/pmac_nvram.c b/arch/ppc/kernel/pmac_nvram.c
index 99bfa4f8b..ea3338aef 100644
--- a/arch/ppc/kernel/pmac_nvram.c
+++ b/arch/ppc/kernel/pmac_nvram.c
@@ -10,6 +10,7 @@
#include <asm/io.h>
#include <asm/system.h>
#include <asm/prom.h>
+#include <asm/machdep.h>
#include <linux/adb.h>
#include <linux/pmu.h>
diff --git a/arch/ppc/kernel/pmac_time.c b/arch/ppc/kernel/pmac_time.c
index 60b497cd6..3b7dd283f 100644
--- a/arch/ppc/kernel/pmac_time.c
+++ b/arch/ppc/kernel/pmac_time.c
@@ -24,6 +24,7 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/pgtable.h>
+#include <asm/machdep.h>
#include "time.h"
diff --git a/arch/ppc/kernel/ppc4xx_pic.c b/arch/ppc/kernel/ppc4xx_pic.c
new file mode 100644
index 000000000..8b40080b4
--- /dev/null
+++ b/arch/ppc/kernel/ppc4xx_pic.c
@@ -0,0 +1,204 @@
+/*
+ *
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ * Module name: ppc4xx_pic.c
+ *
+ * Description:
+ * Interrupt controller driver for PowerPC 4xx-based processors.
+ */
+
+/*
+ * The PowerPC 403 cores' Asynchronous Interrupt Controller (AIC) has
+ * 32 possible interrupts, a majority of which are not implemented on
+ * all cores. There are six configurable, external interrupt pins and
+ * there are eight internal interrupts for the on-chip serial port
+ * (SPU), DMA controller, and JTAG controller.
+ *
+ * The PowerPC 405 cores' Universal Interrupt Controller (UIC) has 32
+ * possible interrupts as well. There are seven, configurable external
+ * interrupt pins and there are 17 internal interrupts for the on-chip
+ * serial port, DMA controller, on-chip Ethernet controller, PCI, etc.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/stddef.h>
+
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+
+#include "local_irq.h"
+#include "ppc4xx_pic.h"
+
+
+/* Global Variables */
+
+struct hw_interrupt_type *ppc4xx_pic;
+
+
+/* Function Prototypes */
+
+static void ppc403_aic_enable(unsigned int irq);
+static void ppc403_aic_disable(unsigned int irq);
+static void ppc403_aic_disable_and_ack(unsigned int irq);
+
+static void ppc405_uic_enable(unsigned int irq);
+static void ppc405_uic_disable(unsigned int irq);
+static void ppc405_uic_disable_and_ack(unsigned int irq);
+
+static struct hw_interrupt_type ppc403_aic = {
+ "403GC AIC",
+ NULL,
+ NULL,
+ ppc403_aic_enable,
+ ppc403_aic_disable,
+ ppc403_aic_disable_and_ack,
+ 0
+};
+
+static struct hw_interrupt_type ppc405_uic = {
+ "405GP UIC",
+ NULL,
+ NULL,
+ ppc405_uic_enable,
+ ppc405_uic_disable,
+ ppc405_uic_disable_and_ack,
+ 0
+};
+
+/*
+ * Document me.
+ */
+void __init
+ppc4xx_pic_init(void)
+{
+ unsigned long ver = PVR_VER(mfspr(SPRN_PVR));
+
+ switch (ver) {
+
+ case PVR_VER(PVR_403GC):
+ /*
+ * Disable all external interrupts until they are
+ * explicity requested.
+ */
+ ppc_cached_irq_mask[0] = 0;
+ mtdcr(DCRN_EXIER, 0);
+
+ ppc4xx_pic = &ppc403_aic;
+ break;
+
+ case PVR_VER(PVR_405GP):
+ ppc4xx_pic = &ppc405_uic;
+ break;
+ }
+
+ return;
+}
+
+/*
+ * XXX - Currently 403-specific!
+ *
+ * Document me.
+ */
+int
+ppc4xx_pic_get_irq(struct pt_regs *regs)
+{
+ int irq;
+ unsigned long bits, mask = (1 << 31);
+
+ /*
+ * Only report the status of those interrupts that are actually
+ * enabled.
+ */
+
+ bits = mfdcr(DCRN_EXISR) & mfdcr(DCRN_EXIER);
+
+ /*
+ * Walk through the interrupts from highest priority to lowest, and
+ * report the first pending interrupt found.
+ */
+
+ for (irq = 0; irq < NR_IRQS; irq++, mask >>= 1) {
+ if (bits & mask)
+ break;
+ }
+
+ return (irq);
+}
+
+/*
+ * Document me.
+ */
+static void
+ppc403_aic_enable(unsigned int irq)
+{
+ int bit, word;
+
+ bit = irq & 0x1f;
+ word = irq >> 5;
+
+ ppc_cached_irq_mask[word] |= (1 << (31 - bit));
+ mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
+}
+
+/*
+ * Document me.
+ */
+static void
+ppc403_aic_disable(unsigned int irq)
+{
+ int bit, word;
+
+ bit = irq & 0x1f;
+ word = irq >> 5;
+
+ ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
+ mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
+}
+
+/*
+ * Document me.
+ */
+static void
+ppc403_aic_disable_and_ack(unsigned int irq)
+{
+ int bit, word;
+
+ bit = irq & 0x1f;
+ word = irq >> 5;
+
+ ppc_cached_irq_mask[word] &= ~(1 << (31 - bit));
+ mtdcr(DCRN_EXIER, ppc_cached_irq_mask[word]);
+ mtdcr(DCRN_EXISR, (1 << (31 - bit)));
+}
+
+/*
+ * Document me.
+ */
+static void
+ppc405_uic_enable(unsigned int irq)
+{
+ /* XXX - Implement me. */
+}
+
+/*
+ * Document me.
+ */
+static void
+ppc405_uic_disable(unsigned int irq)
+{
+ /* XXX - Implement me. */
+}
+
+/*
+ * Document me.
+ */
+static void
+ppc405_uic_disable_and_ack(unsigned int irq)
+{
+ /* XXX - Implement me. */
+}
diff --git a/arch/ppc/kernel/ppc4xx_pic.h b/arch/ppc/kernel/ppc4xx_pic.h
new file mode 100644
index 000000000..6de862a46
--- /dev/null
+++ b/arch/ppc/kernel/ppc4xx_pic.h
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ * Module name: ppc4xx_pic.h
+ *
+ * Description:
+ * Interrupt controller driver for PowerPC 4xx-based processors.
+ */
+
+#ifndef __PPC4XX_PIC_H__
+#define __PPC4XX_PIC_H__
+
+#include <asm/ptrace.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* External Global Variables */
+
+extern struct hw_interrupt_type *ppc4xx_pic;
+
+
+/* Function Prototypes */
+
+extern void ppc4xx_pic_init(void);
+extern int ppc4xx_pic_get_irq(struct pt_regs *regs);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PPC4XX_PIC_H__ */
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 397685d43..65e925034 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -260,10 +260,8 @@ EXPORT_SYMBOL(screen_info);
#endif
EXPORT_SYMBOL(int_control);
-#if !defined(CONFIG_4xx)
EXPORT_SYMBOL(timer_interrupt_intercept);
EXPORT_SYMBOL(timer_interrupt);
-#endif
extern unsigned long do_IRQ_intercept;
EXPORT_SYMBOL(do_IRQ_intercept);
EXPORT_SYMBOL(irq_desc);
@@ -272,3 +270,4 @@ EXPORT_SYMBOL(ppc_irq_dispatch_handler);
EXPORT_SYMBOL(decrementer_count);
EXPORT_SYMBOL(get_wchan);
EXPORT_SYMBOL(console_drivers);
+EXPORT_SYMBOL(do_bottom_half);
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index 64b171042..241b7c33c 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -287,11 +287,12 @@ int
copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
struct task_struct * p, struct pt_regs * regs)
{
+ unsigned long msr;
struct pt_regs * childregs, *kregs;
#ifdef __SMP__
extern void ret_from_smpfork(void);
#else
- extern void ret_from_syscall(void);
+ extern void ret_from_except(void);
#endif
/* Copy registers */
childregs = ((struct pt_regs *)
@@ -308,9 +309,10 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
#ifdef __SMP__
kregs->nip = (unsigned long)ret_from_smpfork;
#else
- kregs->nip = (unsigned long)ret_from_syscall;
+ kregs->nip = (unsigned long)ret_from_except;
#endif
- kregs->msr = MSR_KERNEL;
+ asm volatile("mfmsr %0" : "=r" (msr):);
+ kregs->msr = msr;
kregs->gpr[1] = (unsigned long)childregs - STACK_FRAME_OVERHEAD;
kregs->gpr[2] = (unsigned long)p;
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index caffdcf99..dccb066ff 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -29,8 +29,9 @@
#endif
#include <asm/bootx.h>
#include <asm/machdep.h>
-
+#ifdef CONFIG_OAK
#include "oak_setup.h"
+#endif /* CONFIG_OAK */
extern void pmac_init(unsigned long r3,
unsigned long r4,
@@ -71,7 +72,13 @@ extern void gemini_init(unsigned long r3,
extern boot_infos_t *boot_infos;
char saved_command_line[256];
unsigned char aux_device_present;
-struct int_control_struct int_control;
+struct int_control_struct int_control =
+{
+ __no_use_cli,
+ __no_use_sti,
+ __no_use_restore_flags,
+ __no_use_save_flags
+};
struct ide_machdep_calls ppc_ide_md;
int parse_bootinfo(void);
@@ -89,20 +96,13 @@ unsigned long SYSRQ_KEY;
struct machdep_calls ppc_md;
-/* copy of the residual data */
-#ifndef CONFIG_8xx
-extern unsigned char __res[sizeof(RESIDUAL)];
-#else
-extern unsigned char __res[sizeof(bd_t)];
-#endif
-
/*
* Perhaps we can put the pmac screen_info[] here
* on pmac as well so we don't need the ifdef's.
* Until we get multiple-console support in here
* that is. -- Cort
*/
-#ifndef CONFIG_8xx
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
struct screen_info screen_info = {
0, 25, /* orig-x, orig-y */
0, /* unused */
@@ -126,7 +126,7 @@ void __init pmac_find_display(void)
{
}
-#else /* CONFIG_8xx */
+#else /* CONFIG_4xx || CONFIG_8xx */
/* We need this to satisfy some external references until we can
* strip the kernel down.
@@ -142,7 +142,7 @@ struct screen_info screen_info = {
0, /* orig-video-isVGA */
16 /* orig-video-points */
};
-#endif /* CONFIG_8xx */
+#endif /* !CONFIG_4xx && !CONFIG_8xx */
void machine_restart(char *cmd)
{
@@ -193,6 +193,7 @@ int get_cpuinfo(char *buffer)
unsigned long len = 0;
unsigned long bogosum = 0;
unsigned long i;
+ unsigned int pvr;
unsigned short maj, min;
#ifdef __SMP__
@@ -215,45 +216,75 @@ int get_cpuinfo(char *buffer)
len += sprintf(len+buffer,"processor\t: %lu\n",i);
len += sprintf(len+buffer,"cpu\t\t: ");
- switch (GET_PVR >> 16)
+ pvr = GET_PVR;
+
+ switch (PVR_VER(pvr))
{
- case 1:
+ case 0x0001:
len += sprintf(len+buffer, "601\n");
break;
- case 3:
+ case 0x0003:
len += sprintf(len+buffer, "603\n");
break;
- case 4:
+ case 0x0004:
len += sprintf(len+buffer, "604\n");
break;
- case 6:
+ case 0x0006:
len += sprintf(len+buffer, "603e\n");
break;
- case 7:
- len += sprintf(len+buffer, "603ev\n");
+ case 0x0007:
+ len += sprintf(len+buffer, "603");
+ if (((pvr >> 12) & 0xF) == 1) {
+ pvr ^= 0x00001000; /* revision fix-up */
+ len += sprintf(len+buffer, "r\n");
+ } else {
+ len += sprintf(len+buffer, "ev\n");
+ }
break;
- case 8:
- len += sprintf(len+buffer, "750\n");
+ case 0x0008: /* 740/750(P) */
+ case 0x1008:
+ len += sprintf(len+buffer, "750%s\n",
+ PVR_VER(pvr) == 0x1008 ? "P" : "");
len += sprintf(len+buffer, "temperature \t: %lu C\n",
cpu_temp());
break;
- case 9:
- len += sprintf(len+buffer, "604e\n");
+ case 0x0009: /* 604e/604r */
+ case 0x000A:
+ len += sprintf(len+buffer, "604");
+
+ if (PVR_VER(pvr) == 0x000A ||
+ ((pvr >> 12) & 0xF) != 0) {
+ pvr &= ~0x00003000; /* revision fix-up */
+ len += sprintf(len+buffer, "r\n");
+ } else {
+ len += sprintf(len+buffer, "e\n");
+ }
break;
- case 10:
- len += sprintf(len+buffer, "604ev5 (MachV)\n");
+ case 0x000C:
+ len += sprintf(len+buffer, "7400\n");
break;
- case 12:
- len += sprintf(len+buffer, "7400 (G4)\n");
+ case 0x0020:
+ len += sprintf(len+buffer, "403G");
+ switch ((pvr >> 8) & 0xFF) {
+ case 0x02:
+ len += sprintf(len+buffer, "C\n");
+ break;
+ case 0x14:
+ len += sprintf(len+buffer, "CX\n");
+ break;
+ }
break;
- case 50:
+ case 0x0050:
len += sprintf(len+buffer, "821\n");
- case 80:
- len += sprintf(len+buffer, "860\n");
+ break;
+ case 0x0081:
+ len += sprintf(len+buffer, "8240\n");
+ break;
+ case 0x4011:
+ len += sprintf(len+buffer, "405GP\n");
break;
default:
- len += sprintf(len+buffer, "unknown (%lx)\n",
- GET_PVR>>16);
+ len += sprintf(len+buffer, "unknown (%08x)\n", pvr);
break;
}
@@ -292,6 +323,22 @@ int get_cpuinfo(char *buffer)
len += ppc_md.setup_residual(buffer + len);
}
+ switch (PVR_VER(pvr))
+ {
+ case 0x0020:
+ maj = PVR_MAJ(pvr) + 1;
+ min = PVR_MIN(pvr);
+ break;
+ case 0x1008:
+ maj = ((pvr >> 8) & 0xFF) - 1;
+ min = pvr & 0xFF;
+ break;
+ default:
+ maj = (pvr >> 8) & 0xFF;
+ min = pvr & 0xFF;
+ break;
+ }
+
len += sprintf(len+buffer, "revision\t: %hd.%hd\n", maj, min);
len += sprintf(buffer+len, "bogomips\t: %lu.%02lu\n",
@@ -362,11 +409,6 @@ unsigned long __init
identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
- int_control.int_sti = __no_use_sti;
- int_control.int_cli = __no_use_cli;
- int_control.int_save_flags = __no_use_save_flags;
- int_control.int_restore_flags = __no_use_restore_flags;
-
parse_bootinfo();
if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100);
@@ -674,25 +716,25 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
id->word72 = __le16_to_cpu(id->word72);
id->word73 = __le16_to_cpu(id->word73);
id->word74 = __le16_to_cpu(id->word74);
- id->word75 = __le16_to_cpu(id->word75);
+ id->queue_depth = __le16_to_cpu(id->queue_depth);
id->word76 = __le16_to_cpu(id->word76);
id->word77 = __le16_to_cpu(id->word77);
id->word78 = __le16_to_cpu(id->word78);
id->word79 = __le16_to_cpu(id->word79);
- id->word80 = __le16_to_cpu(id->word80);
- id->word81 = __le16_to_cpu(id->word81);
- id->command_sets = __le16_to_cpu(id->command_sets);
- id->word83 = __le16_to_cpu(id->word83);
- id->word84 = __le16_to_cpu(id->word84);
- id->word85 = __le16_to_cpu(id->word85);
- id->word86 = __le16_to_cpu(id->word86);
- id->word87 = __le16_to_cpu(id->word87);
+ id->major_rev_num = __le16_to_cpu(id->major_rev_num);
+ id->minor_rev_num = __le16_to_cpu(id->minor_rev_num);
+ id->command_set_1 = __le16_to_cpu(id->command_set_1);
+ id->command_set_2 = __le16_to_cpu(id->command_set_2);
+ id->cfsse = __le16_to_cpu(id->cfsse);
+ id->cfs_enable_1 = __le16_to_cpu(id->cfs_enable_1);
+ id->cfs_enable_2 = __le16_to_cpu(id->cfs_enable_2);
+ id->csf_default = __le16_to_cpu(id->csf_default);
id->dma_ultra = __le16_to_cpu(id->dma_ultra);
id->word89 = __le16_to_cpu(id->word89);
id->word90 = __le16_to_cpu(id->word90);
- id->word91 = __le16_to_cpu(id->word91);
+ id->CurAPMvalues = __le16_to_cpu(id->CurAPMvalues);
id->word92 = __le16_to_cpu(id->word92);
- id->word93 = __le16_to_cpu(id->word93);
+ id->hw_config = __le16_to_cpu(id->hw_config);
id->word94 = __le16_to_cpu(id->word94);
id->word95 = __le16_to_cpu(id->word95);
id->word96 = __le16_to_cpu(id->word96);
@@ -727,7 +769,6 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
id->word125 = __le16_to_cpu(id->word125);
id->word126 = __le16_to_cpu(id->word126);
id->word127 = __le16_to_cpu(id->word127);
- id->security = __le16_to_cpu(id->security);
for (i=0; i<127; i++)
id->reserved[i] = __le16_to_cpu(id->reserved[i]);
}
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index c2891e21f..386764ddd 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -446,6 +446,8 @@ void __init smp_callin(void)
*/
if ( _machine & (_MACH_gemini|_MACH_chrp|_MACH_prep) )
do_openpic_setup_cpu();
+ if ( _machine == _MACH_gemini )
+ gemini_init_l2();
while(!smp_commenced)
barrier();
__sti();
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index e21c30e14..b695da797 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -68,7 +68,7 @@ unsigned count_period_den; /* count_period_num / count_period_den us */
* with interrupts disabled.
* We set it up to overflow again in 1/HZ seconds.
*/
-void timer_interrupt(struct pt_regs * regs)
+int timer_interrupt(struct pt_regs * regs)
{
int dval, d;
unsigned long cpu = smp_processor_id();
@@ -141,6 +141,7 @@ void timer_interrupt(struct pt_regs * regs)
ppc_md.heartbeat();
hardirq_exit(cpu);
+ return 1; /* lets ret_from_int know we can do checks */
}
/*
diff --git a/arch/ppc/kernel/time.h b/arch/ppc/kernel/time.h
index a0a5c62d2..05d791546 100644
--- a/arch/ppc/kernel/time.h
+++ b/arch/ppc/kernel/time.h
@@ -6,8 +6,11 @@
* Paul Mackerras' version and mine for PReP and Pmac.
*/
+#include <linux/config.h>
#include <linux/mc146818rtc.h>
+#include <asm/processor.h>
+
/* time.c */
extern unsigned decrementer_count;
extern unsigned count_period_num;
@@ -22,13 +25,18 @@ int via_calibrate_decr(void);
/* Accessor functions for the decrementer register. */
static __inline__ unsigned int get_dec(void)
{
- unsigned int ret;
-
- asm volatile("mfspr %0,22" : "=r" (ret) :);
- return ret;
+#if defined(CONFIG_4xx)
+ return (mfspr(SPRN_PIT));
+#else
+ return (mfspr(SPRN_DEC));
+#endif
}
static __inline__ void set_dec(unsigned int val)
{
- asm volatile("mtspr 22,%0" : : "r" (val));
+#if defined(CONFIG_4xx)
+ mtspr(SPRN_PIT, val);
+#else
+ mtspr(SPRN_DEC, val);
+#endif
}
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 47fef50d4..04b4e2d36 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -194,7 +194,6 @@ void
ProgramCheckException(struct pt_regs *regs)
{
#if defined(CONFIG_4xx)
- unsigned int instr;
unsigned int esr = mfspr(SPRN_ESR);
if (esr & ESR_PTR) {
diff --git a/arch/ppc/mm/4xx_tlb.c b/arch/ppc/mm/4xx_tlb.c
new file mode 100644
index 000000000..b9d9d2119
--- /dev/null
+++ b/arch/ppc/mm/4xx_tlb.c
@@ -0,0 +1,397 @@
+/*
+ *
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ * Module name: 4xx_tlb.c
+ *
+ * Description:
+ * Routines for manipulating the TLB on PowerPC 400-class processors.
+ *
+ */
+
+#include <asm/processor.h>
+#include <asm/mmu.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+
+
+/* Preprocessor Defines */
+
+#if !defined(TRUE) || TRUE != 1
+#define TRUE 1
+#endif
+
+#if !defined(FALSE) || FALSE != 0
+#define FALSE 0
+#endif
+
+
+/* Function Macros */
+
+
+/* Type Definitios */
+
+typedef struct pin_entry_s {
+ unsigned int e_pinned: 1, /* This TLB entry is pinned down. */
+ e_used: 23; /* Number of users for this mapping. */
+} pin_entry_t;
+
+
+/* Global Variables */
+
+static pin_entry_t pin_table[PPC4XX_TLB_SIZE];
+
+
+/* Function Prototypes */
+
+
+void
+PPC4xx_tlb_pin(unsigned long va, unsigned long pa, int pagesz, int cache)
+{
+ int i, found = FALSE;
+ unsigned long tag, data;
+ unsigned long opid;
+
+ opid = mfspr(SPRN_PID);
+ mtspr(SPRN_PID, 0);
+
+ data = (pa & TLB_RPN_MASK) | TLB_WR;
+
+ if (cache)
+ data |= (TLB_EX | TLB_I);
+ else
+ data |= (TLB_G | TLB_I);
+
+ tag = (va & TLB_EPN_MASK) | TLB_VALID | pagesz;
+
+ for (i = 0; i < PPC4XX_TLB_SIZE; i++) {
+ if (pin_table[i].e_pinned == FALSE) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (found) {
+ /* printk("Pinning %#x -> %#x in entry %d...\n", va, pa, i); */
+ asm("tlbwe %0,%1,1" : : "r" (data), "r" (i));
+ asm("tlbwe %0,%1,0" : : "r" (tag), "r" (i));
+ asm("isync");
+ pin_table[i].e_pinned = found;
+ }
+
+ mtspr(SPRN_PID, opid);
+ return;
+}
+
+void
+PPC4xx_tlb_unpin(unsigned long va, unsigned long pa, int size)
+{
+ /* XXX - To beimplemented. */
+}
+
+void
+PPC4xx_tlb_flush_all(void)
+{
+ int i;
+ unsigned long flags, opid;
+
+ save_flags(flags);
+ cli();
+
+ opid = mfspr(SPRN_PID);
+ mtspr(SPRN_PID, 0);
+
+ for (i = 0; i < PPC4XX_TLB_SIZE; i++) {
+ unsigned long ov = 0;
+
+ if (pin_table[i].e_pinned)
+ continue;
+
+ asm("tlbwe %0,%1,0" : : "r" (ov), "r" (i));
+ asm("tlbwe %0,%1,1" : : "r" (ov), "r" (i));
+ }
+
+ asm("sync;isync");
+
+ mtspr(SPRN_PID, opid);
+ restore_flags(flags);
+}
+
+void
+PPC4xx_tlb_flush(unsigned long va, int pid)
+{
+ unsigned long i, tag, flags, found = 1, opid;
+
+ save_flags(flags);
+ cli();
+
+ opid = mfspr(SPRN_PID);
+ mtspr(SPRN_PID, pid);
+
+ asm("tlbsx. %0,0,%2;beq 1f;li %1,0;1:" : "=r" (i), "=r" (found) : "r" (va));
+
+ if (found && pin_table[i].e_pinned == 0) {
+ asm("tlbre %0,%1,0" : "=r" (tag) : "r" (i));
+ tag &= ~ TLB_VALID;
+ asm("tlbwe %0,%1,0" : : "r" (tag), "r" (i));
+ }
+
+ mtspr(SPRN_PID, opid);
+
+ restore_flags(flags);
+}
+
+#if 0
+/*
+ * TLB miss handling code.
+ */
+
+/*
+ * Handle TLB faults. We should push this back to assembly code eventually.
+ * Caller is responsible for turning off interrupts ...
+ */
+static inline void
+tlbDropin(unsigned long tlbhi, unsigned long tlblo) {
+ /*
+ * Avoid the divide at the slight cost of a little too
+ * much emphasis on the last few entries.
+ */
+ unsigned long rand = mfspr(SPRN_TBLO);
+ rand &= 0x3f;
+ rand += NTLB_WIRED;
+ if (rand >= NTLB)
+ rand -= NTLB_WIRED;
+
+ asm("tlbwe %0,%1,1" : : "r" (tlblo), "r" (rand));
+ asm("tlbwe %0,%1,0" : : "r" (tlbhi), "r" (rand));
+ asm("isync;sync");
+}
+
+static inline void
+mkTlbEntry(unsigned long addr, pte_t *pte) {
+ unsigned long tlbhi;
+ unsigned long tlblo;
+ int found = 1;
+ int idx;
+
+ /*
+ * Construct the TLB entry.
+ */
+ tlbhi = addr & ~(PAGE_SIZE-1);
+ tlblo = virt_to_phys(pte_page(*pte)) & TLBLO_RPN;
+ if (pte_val(*pte) & _PAGE_HWWRITE)
+ tlblo |= TLBLO_WR;
+ if (pte_val(*pte) & _PAGE_NO_CACHE)
+ tlblo |= TLBLO_I;
+ tlblo |= TLBLO_EX;
+ if (addr < KERNELBASE)
+ tlblo |= TLBLO_Z_USER;
+ tlbhi |= TLBHI_PGSZ_4K;
+ tlbhi |= TLBHI_VALID;
+
+ /*
+ * See if a match already exists in the TLB.
+ */
+ asm("tlbsx. %0,0,%2;beq 1f;li %1,0;1:" : "=r" (idx), "=r" (found) : "r" (tlbhi));
+ if (found) {
+ /*
+ * Found an existing entry. Just reuse the index.
+ */
+ asm("tlbwe %0,%1,0" : : "r" (tlbhi), "r" (idx));
+ asm("tlbwe %0,%1,1" : : "r" (tlblo), "r" (idx));
+ }
+ else {
+ /*
+ * Do the more expensive operation
+ */
+ tlbDropin(tlbhi, tlblo);
+ }
+}
+
+/*
+ * Mainline of the TLB miss handler. The above inline routines should fold into
+ * this one, eliminating most function call overhead.
+ */
+#ifdef TLBMISS_DEBUG
+volatile unsigned long miss_start;
+volatile unsigned long miss_end;
+#endif
+
+static inline int tlbMiss(struct pt_regs *regs, unsigned long badaddr, int wasWrite)
+{
+ int spid, ospid;
+ struct mm_struct *mm;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+
+ if (!user_mode(regs) && (badaddr >= KERNELBASE)) {
+ mm = task[0]->mm;
+ spid = 0;
+#ifdef TLBMISS_DEBUG
+ miss_start = 0;
+#endif
+ }
+ else {
+ mm = current->mm;
+ spid = mfspr(SPRN_PID);
+#ifdef TLBMISS_DEBUG
+ miss_start = 1;
+#endif
+ }
+#ifdef TLBMISS_DEBUG
+ store_cache_range((unsigned long)&miss_start, sizeof(miss_start));
+#endif
+
+ pgd = pgd_offset(mm, badaddr);
+ if (pgd_none(*pgd))
+ goto NOGOOD;
+
+ pmd = pmd_offset(pgd, badaddr);
+ if (pmd_none(*pmd))
+ goto NOGOOD;
+
+ pte = pte_offset(pmd, badaddr);
+ if (pte_none(*pte))
+ goto NOGOOD;
+ if (!pte_present(*pte))
+ goto NOGOOD;
+#if 1
+ prohibit_if_guarded(badaddr, sizeof(int));
+#endif
+ if (wasWrite) {
+ if (!pte_write(*pte)) {
+ goto NOGOOD;
+ }
+ set_pte(pte, pte_mkdirty(*pte));
+ }
+ set_pte(pte, pte_mkyoung(*pte));
+
+ ospid = mfspr(SPRN_PID);
+ mtspr(SPRN_PID, spid);
+ mkTlbEntry(badaddr, pte);
+ mtspr(SPRN_PID, ospid);
+
+#ifdef TLBMISS_DEBUG
+ miss_end = 0;
+ store_cache_range((unsigned long)&miss_end, sizeof(miss_end));
+#endif
+ return 0;
+
+NOGOOD:
+#ifdef TLBMISS_DEBUG
+ miss_end = 1;
+ store_cache_range((unsigned long)&miss_end, sizeof(miss_end));
+#endif
+ return 1;
+}
+
+/*
+ * End TLB miss handling code.
+ */
+/* ---------- */
+
+/*
+ * Used to flush the TLB if the page fault handler decides to change
+ * something.
+ */
+void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte) {
+ int spid;
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+
+ if (addr >= KERNELBASE)
+ spid = 0;
+ else
+ spid = vma->vm_mm->context;
+ tlbFlush1(addr, spid);
+
+ restore_flags(flags);
+}
+
+/*
+ * Given a virtual address in the current address space, make
+ * sure the associated physical page is present in memory,
+ * and if the data is to be modified, that any copy-on-write
+ * actions have taken place.
+ */
+unsigned long make_page_present(unsigned long p, int rw) {
+ pte_t *pte;
+ char c;
+
+ get_user(c, (char *) p);
+
+ pte = findPTE(current->mm, p);
+ if (pte_none(*pte) || !pte_present(*pte))
+ debug("make_page_present didn't load page", 0);
+
+ if (rw) {
+ /*
+ * You have to write-touch the page, so that
+ * zero-filled pages are forced to be copied
+ * rather than still pointing at the zero
+ * page.
+ */
+ extern void tlbFlush1(unsigned long, int);
+ tlbFlush1(p, get_context());
+ put_user(c, (char *) p);
+ if (!pte_write(*pte))
+ debug("make_page_present didn't make page writable", 0);
+
+ tlbFlush1(p, get_context());
+ }
+ return pte_page(*pte);
+}
+
+void DataTLBMissException(struct pt_regs *regs)
+{
+ unsigned long badaddr = mfspr(SPRN_DEAR);
+ int wasWrite = mfspr(SPRN_ESR) & 0x800000;
+ if (tlbMiss(regs, badaddr, wasWrite)) {
+ sti();
+ do_page_fault(regs, badaddr, wasWrite);
+ cli();
+ }
+}
+
+void InstructionTLBMissException(struct pt_regs *regs)
+{
+ if (!current) {
+ debug("ITLB Miss with no current task", regs);
+ sti();
+ bad_page_fault(regs, regs->nip);
+ cli();
+ return;
+ }
+ if (tlbMiss(regs, regs->nip, 0)) {
+ sti();
+ do_page_fault(regs, regs->nip, 0);
+ cli();
+ }
+}
+
+void DataPageFault(struct pt_regs *regs)
+{
+ unsigned long badaddr = mfspr(SPRN_DEAR);
+ int wasWrite = mfspr(SPRN_ESR) & 0x800000;
+ sti();
+ do_page_fault(regs, badaddr, wasWrite);
+ cli();
+}
+
+void InstructionPageFault(struct pt_regs *regs)
+{
+ if (!current) {
+ debug("ITLB fault with no current task", regs);
+ sti();
+ bad_page_fault(regs, regs->nip);
+ cli();
+ return;
+ }
+ sti();
+ do_page_fault(regs, regs->nip, 0);
+ cli();
+}
+#endif
diff --git a/arch/ppc/mm/4xx_tlb.h b/arch/ppc/mm/4xx_tlb.h
new file mode 100644
index 000000000..03fef109f
--- /dev/null
+++ b/arch/ppc/mm/4xx_tlb.h
@@ -0,0 +1,35 @@
+/*
+ *
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ * Module name: 4xx_tlb.h
+ *
+ * Description:
+ * Routines for manipulating the TLB on PowerPC 400-class processors.
+ *
+ */
+
+#ifndef __4XX_TLB_H__
+#define __4XX_TLB_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Function Prototypes */
+
+extern void PPC4xx_tlb_pin(unsigned long va, unsigned long pa,
+ int pagesz, int cache);
+extern void PPC4xx_tlb_unpin(unsigned long va, unsigned long pa,
+ int size);
+extern void PPC4xx_tlb_flush_all(void);
+extern void PPC4xx_tlb_flush(unsigned long va, int pid);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __4XX_TLB_H__ */
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 34117098e..c558ef051 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -59,6 +59,10 @@
#include "mem_pieces.h"
+#if defined(CONFIG_4xx)
+#include "4xx_tlb.h"
+#endif
+
#define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10)
int prom_trashed;
@@ -97,6 +101,9 @@ extern unsigned long *find_end_of_memory(void);
#ifdef CONFIG_8xx
unsigned long *m8xx_find_end_of_memory(void);
#endif /* CONFIG_8xx */
+#ifdef CONFIG_4xx
+unsigned long *oak_find_end_of_memory(void);
+#endif
static void mapin_ram(void);
void map_page(unsigned long va, unsigned long pa, int flags);
extern void die_if_kernel(char *,struct pt_regs *,long);
@@ -339,9 +346,7 @@ void si_meminfo(struct sysinfo *val)
continue;
val->sharedram += atomic_read(&mem_map[i].count) - 1;
}
- val->totalram <<= PAGE_SHIFT;
- val->sharedram <<= PAGE_SHIFT;
- return;
+ val->mem_unit = PAGE_SIZE;
}
void *
@@ -682,7 +687,7 @@ static void __init mapin_ram(void)
int i;
unsigned long v, p, s, f;
-#ifndef CONFIG_8xx
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
if (!__map_without_bats) {
unsigned long tot, mem_base, bl, done;
unsigned long max_size = (256<<20);
@@ -717,7 +722,7 @@ static void __init mapin_ram(void)
RAM_PAGE);
}
}
-#endif /* CONFIG_8xx */
+#endif /* !CONFIG_4xx && !CONFIG_8xx */
for (i = 0; i < phys_mem.n_regions; ++i) {
v = (ulong)__va(phys_mem.regions[i].address);
@@ -846,6 +851,31 @@ void free_initrd_mem(unsigned long start, unsigned long end)
* still be merged.
* -- Cort
*/
+#if defined(CONFIG_4xx)
+void __init
+MMU_init(void)
+{
+ PPC4xx_tlb_pin(KERNELBASE, 0, TLB_PAGESZ(PAGESZ_16M), 1);
+ PPC4xx_tlb_pin(OAKNET_IO_BASE, OAKNET_IO_BASE, TLB_PAGESZ(PAGESZ_4K), 0);
+ end_of_DRAM = oak_find_end_of_memory();
+
+ /* Map in all of RAM starting at KERNELBASE */
+
+ mapin_ram();
+
+ /* Zone 0 - kernel (above 0x80000000), zone 1 - user */
+
+ mtspr(SPRN_ZPR, 0x2aaaaaaa);
+ mtspr(SPRN_DCWR, 0x00000000); /* all caching is write-back */
+
+ /* Cache 128MB of space starting at KERNELBASE. */
+
+ mtspr(SPRN_DCCR, 0x00000000);
+ /* flush_instruction_cache(); XXX */
+ mtspr(SPRN_ICCR, 0x00000000);
+
+}
+#else
void __init MMU_init(void)
{
if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111);
@@ -947,6 +977,7 @@ void __init MMU_init(void)
#endif /* CONFIG_8xx */
if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211);
}
+#endif /* CONFIG_4xx */
/*
* Initialize the bootmem system and give it all the memory we
@@ -1037,29 +1068,21 @@ unsigned long __init find_available_memory(void)
*/
void __init paging_init(void)
{
+ unsigned int zones_size[MAX_NR_ZONES], i;
+
/*
* Grab some memory for bad_page and bad_pagetable to use.
*/
empty_bad_page = alloc_bootmem_pages(PAGE_SIZE);
empty_bad_page_table = alloc_bootmem_pages(PAGE_SIZE);
- {
- unsigned int zones_size[MAX_NR_ZONES], i;
- /*
- * All pages are DMA-able so this is wrong - the zone code is
- * assuming both regions have a value so this is necessary for
- * now.
- * -- Cort
- */
-#if 1
- for ( i = 1; i < MAX_NR_ZONES; i++ )
- zones_size[i] = 1<<MAX_ORDER;
- zones_size[0] = (virt_to_phys(end_of_DRAM) >> PAGE_SHIFT) -
- ((MAX_NR_ZONES-1)*(1<<MAX_ORDER));
-#else
- zones_size[0] = virt_to_phys(end_of_DRAM) >> PAGE_SHIFT;
-#endif
- free_area_init(zones_size);
- }
+
+ /*
+ * All pages are DMA-able so we put them all in the DMA zone.
+ */
+ zones_size[0] = virt_to_phys(end_of_DRAM) >> PAGE_SHIFT;
+ for (i = 1; i < MAX_NR_ZONES; i++)
+ zones_size[i] = 0;
+ free_area_init(zones_size);
}
void __init mem_init(void)
@@ -1404,7 +1427,7 @@ static void __init hash_init(void)
}
if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205);
}
-#else /* CONFIG_8xx */
+#elif defined(CONFIG_8xx)
/*
* This is a big hack right now, but it may turn into something real
* someday.
@@ -1432,4 +1455,29 @@ unsigned long __init *m8xx_find_end_of_memory(void)
set_phys_avail(&phys_mem);
return ret;
}
-#endif /* ndef CONFIG_8xx */
+#endif /* !CONFIG_4xx && !CONFIG_8xx */
+
+#ifdef CONFIG_OAK
+/*
+ * Return the virtual address representing the top of physical RAM
+ * on the Oak board.
+ */
+unsigned long __init *
+oak_find_end_of_memory(void)
+{
+ extern unsigned char __res[];
+
+ unsigned long *ret;
+ bd_t *bip = (bd_t *)__res;
+
+ phys_mem.regions[0].address = 0;
+ phys_mem.regions[0].size = bip->bi_memsize;
+ phys_mem.n_regions = 1;
+
+ ret = __va(phys_mem.regions[0].address +
+ phys_mem.regions[0].size);
+
+ set_phys_avail(&phys_mem);
+ return (ret);
+}
+#endif
diff --git a/arch/ppc/mm/mem_pieces.c b/arch/ppc/mm/mem_pieces.c
index 138b2a40f..e695d5a0a 100644
--- a/arch/ppc/mm/mem_pieces.c
+++ b/arch/ppc/mm/mem_pieces.c
@@ -209,8 +209,6 @@ set_phys_avail(struct mem_pieces *mp)
kstart = __pa(_stext); /* should be 0 */
ksize = PAGE_ALIGN(klimit - _stext);
- printk("kstart = 0x%08lx, ksize = 0x%08lx\n", kstart, ksize);
-
mem_pieces_remove(&phys_avail, kstart, ksize, 0);
mem_pieces_remove(&phys_avail, 0, 0x4000, 0);
diff --git a/arch/ppc/treeboot/Makefile b/arch/ppc/treeboot/Makefile
index 405634214..f84810e1e 100644
--- a/arch/ppc/treeboot/Makefile
+++ b/arch/ppc/treeboot/Makefile
@@ -21,9 +21,9 @@ MKEVIMG = mkevimg -l
MKIRIMG = mkirimg
CFLAGS = -O -fno-builtin -I$(TOPDIR)/include
-LD_ARGS = -e _start -T ld.script -Ttext 80200000 -Bstatic
+LD_ARGS = -e _start -T ld.script -Ttext 0x00200000 -Bstatic
-OBJS = crt0.o main.o misc.o string.o zlib.o irSect.o
+OBJS = crt0.o main.o misc.o irSect.o ../coffboot/string.o ../coffboot/zlib.o
LIBS =
treeboot: $(OBJS) ld.script
diff --git a/arch/ppc/treeboot/crt0.S b/arch/ppc/treeboot/crt0.S
index 1f2c1c094..e54ac2331 100644
--- a/arch/ppc/treeboot/crt0.S
+++ b/arch/ppc/treeboot/crt0.S
@@ -20,7 +20,7 @@
*
*/
-#include "../kernel/ppc_asm.h"
+#include "../kernel/ppc_asm.tmpl"
.text
diff --git a/arch/ppc/treeboot/main.c b/arch/ppc/treeboot/main.c
index 1b5ef3805..277b77047 100644
--- a/arch/ppc/treeboot/main.c
+++ b/arch/ppc/treeboot/main.c
@@ -24,13 +24,22 @@
*
*/
-#include "nonstdio.h"
-#include "zlib.h"
+#include <asm/board.h>
+
+#include "../coffboot/nonstdio.h"
+#include "../coffboot/zlib.h"
#include "irSect.h"
/* Preprocessor Defines */
+/*
+ * Location of the IBM boot ROM function pointer address for retrieving
+ * the board information structure.
+ */
+
+#define BOARD_INFO_VECTOR 0xFFFE0B50
+
#define RAM_SIZE (4 * 1024 * 1024)
#define RAM_PBASE 0x00000000
@@ -58,6 +67,17 @@
char *avail_ram; /* Indicates start of RAM available for heap */
char *end_avail; /* Indicates end of RAM available for heap */
+bd_t board_info;
+
+/*
+ * XXX - Until either the IBM boot ROM provides a way of passing arguments to
+ * the program it launches or until I/O is working in the boot loader,
+ * this is a good spot to pass in command line arguments to the kernel
+ * (e.g. console=tty0).
+ */
+
+static char *cmdline = "";
+
/* Function Prototypes */
@@ -75,10 +95,16 @@ void start(void)
{
void *options;
int ns, oh, i;
- unsigned sa, len;
+ unsigned long sa, len;
void *dst;
unsigned char *im;
- unsigned initrd_start, initrd_size;
+ unsigned long initrd_start, initrd_size;
+ bd_t *(*get_board_info)(void) =
+ (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR);
+ bd_t *bip = NULL;
+
+ if ((bip = get_board_info()) != NULL)
+ memcpy(&board_info, bip, sizeof(bd_t));
/* setup_bats(RAM_START); */
@@ -96,6 +122,7 @@ void start(void)
end_avail = (char *)initrd_start;
} else {
+ initrd_start = initrd_size = 0;
end_avail = (char *)RAM_END;
}
@@ -117,16 +144,20 @@ void start(void)
/* I'm not sure what the 0x200000 parameter is for, but it works. */
- gunzip(dst, 0x200000, cp, &len);
+ gunzip(dst, 0x200000, cp, (int *)&len);
} else {
memmove(dst, im, len);
}
- /* flush_cache(dst, len); */
+ flush_cache(dst, len);
sa = (unsigned long)dst;
- (*(void (*)())sa)();
+ (*(void (*)())sa)(&board_info,
+ initrd_start,
+ initrd_start + initrd_size,
+ cmdline,
+ cmdline + strlen(cmdline));
pause();
}
diff --git a/arch/ppc/treeboot/misc.S b/arch/ppc/treeboot/misc.S
index 27417563f..c51844329 100644
--- a/arch/ppc/treeboot/misc.S
+++ b/arch/ppc/treeboot/misc.S
@@ -6,6 +6,9 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+
+#include "../kernel/ppc_asm.tmpl"
+
.text
/*
@@ -15,14 +18,23 @@
*/
.global flush_cache
flush_cache:
- addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
- rlwinm. 4,4,27,5,31
- mtctr 4
- beqlr
-1: dcbf 0,3
- icbi 0,3
- addi 3,3,0x20
- bdnz 1b
+ mfpvr r5 # Get processor version register
+ extrwi r5,r5,16,0 # Get the version bits
+ cmpwi cr0,r5,0x0020 # Is this a 403-based processor?
+ beq 1f # Yes, it is
+ li r5,32 # It is not a 403, set to 32 bytes
+ addi r4,r4,32-1 # len += line_size - 1
+ srwi. r4,r4,5 # Convert from bytes to lines
+ b 2f
+1: li r5,16 # It is a 403, set to 16 bytes
+ addi r4,r4,16-1 # len += line_size - 1
+ srwi. r4,r4,4 # Convert from bytes to lines
+2: mtctr r4 # Set-up the counter register
+ beqlr # If it is 0, we are done
+3: dcbf r0,r3 # Flush and invalidate the data line
+ icbi r0,r3 # Invalidate the instruction line
+ add r3,r3,r5 # Move to the next line
+ bdnz 3b # Are we done yet?
sync
isync
- blr
+ blr # Return to the caller
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index 9fc97b5a9..426f80ff3 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -102,9 +102,11 @@ xmon_write(void *handle, void *ptr, int nb)
if (!scc_initialized)
xmon_init_scc();
for (i = 0; i < nb; ++i) {
+#ifdef CONFIG_ADB
while ((*sccc & TXRDY) == 0)
if (sys_ctrler == SYS_CTRLER_PMU)
pmu_poll();
+#endif /* CONFIG_ADB */
buf_access();
if ( console && (*p != '\r'))
printk("%c", *p);
@@ -195,9 +197,11 @@ xmon_read(void *handle, void *ptr, int nb)
if (!scc_initialized)
xmon_init_scc();
for (i = 0; i < nb; ++i) {
+#ifdef CONFIG_ADB
while ((*sccc & RXRDY) == 0)
if (sys_ctrler == SYS_CTRLER_PMU)
pmu_poll();
+#endif /* CONFIG_ADB */
buf_access();
#if 0
if ( 0/*console*/ )
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index f5a42cc29..1c6a812d2 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -469,7 +469,7 @@ backtrace(struct pt_regs *excp)
unsigned sp;
unsigned stack[2];
struct pt_regs regs;
- extern char ret_from_int, ret_from_syscall_1, ret_from_syscall_2;
+ extern char ret_from_intercept, ret_from_syscall_1, ret_from_syscall_2;
extern char lost_irq_ret, do_bottom_half_ret, do_signal_ret;
extern char ret_from_except;
@@ -483,7 +483,7 @@ backtrace(struct pt_regs *excp)
if (mread(sp, stack, sizeof(stack)) != sizeof(stack))
break;
printf("%x ", stack[1]);
- if (stack[1] == (unsigned) &ret_from_int
+ if (stack[1] == (unsigned) &ret_from_intercept
|| stack[1] == (unsigned) &ret_from_except
|| stack[1] == (unsigned) &ret_from_syscall_1
|| stack[1] == (unsigned) &ret_from_syscall_2
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
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index c1ef46648..448dad773 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -110,7 +110,7 @@ if [ "$CONFIG_PCI" = "y" ]; then
define_bool CONFIG_IDEDMA_AUTO y
define_bool CONFIG_IDEDMA_NEW_DRIVE_LISTINGS y
define_bool CONFIG_BLK_DEV_NS87415 y
- define_bool CONFIG_BLK_DEV_CMD646 y
+ define_bool CONFIG_BLK_DEV_CMD64X y
fi
fi
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 848984fef..59db5d4bc 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -139,7 +139,7 @@ CONFIG_BLK_DEV_IDEDMA=y
CONFIG_IDEDMA_AUTO=y
CONFIG_IDEDMA_NEW_DRIVE_LISTINGS=y
CONFIG_BLK_DEV_NS87415=y
-CONFIG_BLK_DEV_CMD646=y
+CONFIG_BLK_DEV_CMD64X=y
#
# Networking options
diff --git a/arch/sparc64/kernel/binfmt_elf32.c b/arch/sparc64/kernel/binfmt_elf32.c
index 252a685f4..76516f2f2 100644
--- a/arch/sparc64/kernel/binfmt_elf32.c
+++ b/arch/sparc64/kernel/binfmt_elf32.c
@@ -129,6 +129,13 @@ struct elf_prpsinfo32
char pr_psargs[ELF_PRARGSZ]; /* initial part of arg list */
};
+#include <linux/highuid.h>
+
+#undef NEW_TO_OLD_UID
+#undef NEW_TO_OLD_GID
+#define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
+#define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
+
#define elf_addr_t u32
#define elf_caddr_t u32
#undef start_thread
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index f62e3506d..df636ec6f 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.110 1999/11/19 05:52:50 davem Exp $
+/* $Id: entry.S,v 1.112 2000/01/14 07:12:31 davem Exp $
* arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points.
*
* Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -768,9 +768,9 @@ sunos_getpid:
/* SunOS getuid() returns uid in %o0 and euid in %o1 */
.globl sunos_getuid
sunos_getuid:
- call sys_geteuid
+ call sys32_geteuid16
nop
- call sys_getuid
+ call sys32_getuid16
stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1]
b,pt %xcc, ret_sys_call
stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0]
@@ -778,9 +778,9 @@ sunos_getuid:
/* SunOS getgid() returns gid in %o0 and egid in %o1 */
.globl sunos_getgid
sunos_getgid:
- call sys_getegid
+ call sys32_getegid16
nop
- call sys_getgid
+ call sys32_getgid16
stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1]
b,pt %xcc, ret_sys_call
stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0]
diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c
index ef0fb3e94..cba5cfac3 100644
--- a/arch/sparc64/kernel/ioctl32.c
+++ b/arch/sparc64/kernel/ioctl32.c
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.72 2000/01/04 15:43:45 davem Exp $
+/* $Id: ioctl32.c,v 1.73 2000/01/11 01:06:47 davem Exp $
* ioctl32.c: Conversion between 32bit and 64bit native ioctls.
*
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -594,6 +594,8 @@ static inline int dev_ifsioc(unsigned int fd, unsigned int cmd, unsigned long ar
err |= __put_user(ifr.ifr_map.irq, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.irq));
err |= __put_user(ifr.ifr_map.dma, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.dma));
err |= __put_user(ifr.ifr_map.port, &(((struct ifreq32 *)arg)->ifr_ifru.ifru_map.port));
+ if (err)
+ err = -EFAULT;
break;
}
}
@@ -667,7 +669,7 @@ static inline int hdio_getgeo(unsigned int fd, unsigned long arg)
err = copy_to_user ((struct hd_geometry32 *)arg, &geo, 4);
err |= __put_user (geo.start, &(((struct hd_geometry32 *)arg)->start));
}
- return err;
+ return err ? -EFAULT : 0;
}
struct fbcmap32 {
@@ -715,7 +717,7 @@ static inline int fbiogetputcmap(unsigned int fd, unsigned int cmd, unsigned lon
ret |= copy_to_user ((char *)A(g), green, f.count);
ret |= copy_to_user ((char *)A(b), blue, f.count);
}
- return ret;
+ return ret ? -EFAULT : 0;
}
struct fbcursor32 {
@@ -826,8 +828,10 @@ static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
err |= __get_user(green, &((struct fb_cmap32 *)arg)->green);
err |= __get_user(blue, &((struct fb_cmap32 *)arg)->blue);
err |= __get_user(transp, &((struct fb_cmap32 *)arg)->transp);
- if (err)
+ if (err) {
+ err = -EFAULT;
goto out;
+ }
err = -ENOMEM;
cmap.red = kmalloc(cmap.len * sizeof(__u16), GFP_KERNEL);
if (!cmap.red)
@@ -851,8 +855,10 @@ static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
err |= __copy_from_user(cmap.green, (char *)A(green), cmap.len * sizeof(__u16));
err |= __copy_from_user(cmap.blue, (char *)A(blue), cmap.len * sizeof(__u16));
if (cmap.transp) err |= __copy_from_user(cmap.transp, (char *)A(transp), cmap.len * sizeof(__u16));
- if (err)
+ if (err) {
+ err = -EFAULT;
goto out;
+ }
break;
default:
do {
@@ -896,6 +902,9 @@ static int fb_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
case FBIOPUTCMAP:
break;
}
+ if (err)
+ err = -EFAULT;
+
out: if (cmap.red) kfree(cmap.red);
if (cmap.green) kfree(cmap.green);
if (cmap.blue) kfree(cmap.blue);
@@ -1064,8 +1073,10 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
err |= __get_user(f->spec1, &((struct floppy_struct32 *)arg)->spec1);
err |= __get_user(f->fmt_gap, &((struct floppy_struct32 *)arg)->fmt_gap);
err |= __get_user((u64)f->name, &((struct floppy_struct32 *)arg)->name);
- if (err)
+ if (err) {
+ err = -EFAULT;
goto out;
+ }
break;
}
case FDSETDRVPRM32:
@@ -1097,8 +1108,10 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
err |= __copy_from_user(f->autodetect, ((struct floppy_drive_params32 *)arg)->autodetect, sizeof(f->autodetect));
err |= __get_user(f->checkfreq, &((struct floppy_drive_params32 *)arg)->checkfreq);
err |= __get_user(f->native_format, &((struct floppy_drive_params32 *)arg)->native_format);
- if (err)
+ if (err) {
+ err = -EFAULT;
goto out;
+ }
break;
}
case FDGETDRVSTAT32:
@@ -1221,6 +1234,9 @@ static int fd_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
default:
break;
}
+ if (err)
+ err = -EFAULT;
+
out: if (karg) kfree(karg);
return err;
}
@@ -1396,8 +1412,7 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
return err;
switch (cmd) {
case MTIOCPOS32:
- if (__put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno))
- return -EFAULT;
+ err = __put_user(pos.mt_blkno, &((struct mtpos32 *)arg)->mt_blkno);
break;
case MTIOCGET32:
err = __put_user(get.mt_type, &((struct mtget32 *)arg)->mt_type);
@@ -1422,7 +1437,7 @@ static int mt_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
case MTIOCSETCONFIG32:
break;
}
- return err;
+ return err ? -EFAULT: 0;
}
struct cdrom_read32 {
@@ -1438,11 +1453,21 @@ struct cdrom_read_audio32 {
__kernel_caddr_t32 buf;
};
+struct cdrom_generic_command32 {
+ unsigned char cmd[CDROM_PACKET_SIZE];
+ __kernel_caddr_t32 buffer;
+ unsigned int buflen;
+ int stat;
+ __kernel_caddr_t32 sense;
+ __kernel_caddr_t32 reserved[3];
+};
+
static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long arg)
{
mm_segment_t old_fs = get_fs();
struct cdrom_read cdread;
struct cdrom_read_audio cdreadaudio;
+ struct cdrom_generic_command cgc;
__kernel_caddr_t32 addr;
char *data = 0;
void *karg;
@@ -1477,6 +1502,17 @@ static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar
return -ENOMEM;
cdreadaudio.buf = data;
break;
+ case CDROM_SEND_PACKET:
+ karg = &cgc;
+ err = copy_from_user(cgc.cmd, &((struct cdrom_generic_command32 *)arg)->cmd, sizeof(cgc.cmd));
+ err |= __get_user(addr, &((struct cdrom_generic_command32 *)arg)->buffer);
+ err |= __get_user(cgc.buflen, &((struct cdrom_generic_command32 *)arg)->buflen);
+ if (err)
+ return -EFAULT;
+ if ((data = kmalloc(cgc.buflen, GFP_KERNEL)) == NULL)
+ return -ENOMEM;
+ cgc.buffer = data;
+ break;
default:
do {
static int count = 0;
@@ -1502,11 +1538,15 @@ static int cdrom_ioctl_trans(unsigned int fd, unsigned int cmd, unsigned long ar
case CDROMREADAUDIO:
err = copy_to_user((char *)A(addr), data, cdreadaudio.nframes * 2352);
break;
+ case CDROM_SEND_PACKET:
+ err = copy_to_user((char *)A(addr), data, cgc.buflen);
+ break;
default:
break;
}
-out: if (data) kfree(data);
- return err;
+out: if (data)
+ kfree(data);
+ return err ? -EFAULT : 0;
}
struct loop_info32 {
@@ -1558,7 +1598,7 @@ static int loop_status(unsigned int fd, unsigned int cmd, unsigned long arg)
}
break;
}
- return err;
+ return err ? -EFAULT : 0;
}
extern int tty_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg);
@@ -1835,6 +1875,7 @@ asmlinkage int sys32_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
case CDROMREADCOOKED:
case CDROMREADAUDIO:
case CDROMREADALL:
+ case CDROM_SEND_PACKET:
error = cdrom_ioctl_trans(fd, cmd, arg);
goto out;
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index c102a6205..01fea4f59 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.13 2000/01/06 23:51:49 davem Exp $
+/* $Id: pci.c,v 1.14 2000/01/13 00:05:43 davem Exp $
* pci.c: UltraSparc PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com)
@@ -228,6 +228,11 @@ int pci_assign_resource(struct pci_dev *dev, int i)
return -ENOSYS; /* :-)... actually implement this soon */
}
+int pcibios_enable_device(struct pci_dev *pdev)
+{
+ return 0;
+}
+
char * __init pcibios_setup(char *str)
{
if (!strcmp(str, "onboardfirst")) {
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index d66086bfa..c12b5182d 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1,4 +1,4 @@
-/* $Id: pci_psycho.c,v 1.7 1999/12/17 12:31:57 jj Exp $
+/* $Id: pci_psycho.c,v 1.9 2000/01/11 23:38:32 davem Exp $
* pci_psycho.c: PSYCHO/U2P specific PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -1278,6 +1278,11 @@ static void __init psycho_iommu_init(struct pci_controller_info *p)
p->iommu.page_table = (iopte_t *)tsbbase;
p->iommu.page_table_sz_bits = 17;
p->iommu.page_table_map_base = 0xc0000000;
+#ifndef NEW_PCI_DMA_MAP
+ memset((char *)tsbbase, 0, PAGE_SIZE << 5);
+#else
+ memset((char *)tsbbase, 0, PAGE_SIZE << 7);
+#endif
#ifndef NEW_PCI_DMA_MAP
iopte = (iopte_t *)tsbbase;
diff --git a/arch/sparc64/kernel/pci_sabre.c b/arch/sparc64/kernel/pci_sabre.c
index 3788f71d3..7409b3164 100644
--- a/arch/sparc64/kernel/pci_sabre.c
+++ b/arch/sparc64/kernel/pci_sabre.c
@@ -1,4 +1,4 @@
-/* $Id: pci_sabre.c,v 1.8 2000/01/06 23:51:49 davem Exp $
+/* $Id: pci_sabre.c,v 1.10 2000/01/11 23:38:35 davem Exp $
* pci_sabre.c: Sabre specific PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -1148,6 +1148,7 @@ static void __init sabre_iommu_init(struct pci_controller_info *p,
}
p->iommu.page_table = (iopte_t *)tsbbase;
p->iommu.page_table_map_base = dvma_offset;
+ memset((char *)tsbbase, 0, PAGE_SIZE << order);
#ifndef NEW_PCI_DMA_MAP
iopte = (iopte_t *)tsbbase;
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 66e2b0bbe..f0e512666 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -1,4 +1,4 @@
-/* $Id: signal32.c,v 1.56 1999/12/20 01:16:16 davem Exp $
+/* $Id: signal32.c,v 1.58 2000/01/14 09:40:08 jj Exp $
* arch/sparc64/kernel/signal32.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
diff --git a/arch/sparc64/kernel/sys32.S b/arch/sparc64/kernel/sys32.S
index 4b461fbee..34db8d056 100644
--- a/arch/sparc64/kernel/sys32.S
+++ b/arch/sparc64/kernel/sys32.S
@@ -1,4 +1,4 @@
-/* $Id: sys32.S,v 1.9 1999/12/21 14:09:18 jj Exp $
+/* $Id: sys32.S,v 1.11 2000/01/11 17:33:29 jj Exp $
* sys32.S: I-cache tricks for 32-bit compatability layer simple
* conversions.
*
@@ -20,7 +20,7 @@ sys32_mmap:
.align 32
.globl sys32_lseek
- .globl sys32_chmod, sys32_chown, sys32_lchown, sys32_mknod
+ .globl sys32_chmod, sys32_mknod
sys32_lseek:
sra %o1, 0, %o1
sethi %hi(sys_lseek), %g1
@@ -32,20 +32,6 @@ sys32_chmod:
orcc %g2, %lo(0xffff), %g2
jmpl %g1 + %lo(sys_chmod), %g0
and %o1, %g2, %o1
-sys32_chown:
- sethi %hi(0xffff), %g2
- sethi %hi(sys_chown), %g1
- orcc %g2, %lo(0xffff), %g2
- and %o1, %g2, %o1
- jmpl %g1 + %lo(sys_chown), %g0
- and %o2, %g2, %o2
-sys32_lchown:
- sethi %hi(0xffff), %g2
- sethi %hi(sys_lchown), %g1
- orcc %g2, %lo(0xffff), %g2
- and %o1, %g2, %o1
- jmpl %g1 + %lo(sys_lchown), %g0
- and %o2, %g2, %o2
sys32_mknod:
sethi %hi(0xffff), %g2
sethi %hi(sys_mknod), %g1
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index 486a09d99..af4743ec1 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.32 2000/01/05 01:00:40 davem Exp $
+/* $Id: sys_sparc.c,v 1.33 2000/01/11 17:33:25 jj Exp $
* linux/arch/sparc64/kernel/sys_sparc.c
*
* This file contains various random system calls that
@@ -22,6 +22,7 @@
#include <linux/smp.h>
#include <linux/smp_lock.h>
#include <linux/malloc.h>
+#include <linux/ipc.h>
#include <asm/uaccess.h>
#include <asm/ipc.h>
@@ -98,7 +99,7 @@ asmlinkage int sys_ipc (unsigned call, int first, int second, unsigned long thir
err = -EFAULT;
if(get_user(fourth.__pad, (void **)ptr))
goto out;
- err = sys_semctl (first, second, (int)third, fourth);
+ err = sys_semctl (first, second | IPC_64, (int)third, fourth);
goto out;
}
default:
@@ -118,7 +119,7 @@ asmlinkage int sys_ipc (unsigned call, int first, int second, unsigned long thir
err = sys_msgget ((key_t) first, second);
goto out;
case MSGCTL:
- err = sys_msgctl (first, second, (struct msqid_ds *) ptr);
+ err = sys_msgctl (first, second | IPC_64, (struct msqid_ds *) ptr);
goto out;
default:
err = -EINVAL;
@@ -136,7 +137,7 @@ asmlinkage int sys_ipc (unsigned call, int first, int second, unsigned long thir
err = sys_shmget (first, second, (int)third);
goto out;
case SHMCTL:
- err = sys_shmctl (first, second, (struct shmid_ds *) ptr);
+ err = sys_shmctl (first, second | IPC_64, (struct shmid_ds *) ptr);
goto out;
default:
err = -EINVAL;
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index f9be1320e..408368060 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.127 2000/01/04 23:54:41 davem Exp $
+/* $Id: sys_sparc32.c,v 1.130 2000/01/14 09:40:07 jj Exp $
* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -43,6 +43,7 @@
#include <linux/stat.h>
#include <linux/filter.h>
#include <linux/highmem.h>
+#include <linux/highuid.h>
#include <asm/types.h>
#include <asm/ipc.h>
@@ -76,6 +77,181 @@
__ret; \
})
+extern asmlinkage long sys_chown(const char *, uid_t,gid_t);
+extern asmlinkage long sys_lchown(const char *, uid_t,gid_t);
+extern asmlinkage long sys_fchown(unsigned int, uid_t,gid_t);
+extern asmlinkage long sys_setregid(gid_t, gid_t);
+extern asmlinkage long sys_setgid(gid_t);
+extern asmlinkage long sys_setreuid(uid_t, uid_t);
+extern asmlinkage long sys_setuid(uid_t);
+extern asmlinkage long sys_setresuid(uid_t, uid_t, uid_t);
+extern asmlinkage long sys_setresgid(gid_t, gid_t, gid_t);
+extern asmlinkage long sys_setfsuid(uid_t);
+extern asmlinkage long sys_setfsgid(gid_t);
+
+/* For this source file, we want overflow handling. */
+
+#undef high2lowuid
+#undef high2lowgid
+#undef low2highuid
+#undef low2highgid
+#undef SET_UID16
+#undef SET_GID16
+#undef NEW_TO_OLD_UID
+#undef NEW_TO_OLD_GID
+#undef SET_OLDSTAT_UID
+#undef SET_OLDSTAT_GID
+#undef SET_STAT_UID
+#undef SET_STAT_GID
+
+#define high2lowuid(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid)
+#define high2lowgid(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid)
+#define low2highuid(uid) ((uid) == (u16)-1) ? (uid_t)-1 : (uid_t)(uid)
+#define low2highgid(gid) ((gid) == (u16)-1) ? (gid_t)-1 : (gid_t)(gid)
+#define SET_UID16(var, uid) var = high2lowuid(uid)
+#define SET_GID16(var, gid) var = high2lowgid(gid)
+#define NEW_TO_OLD_UID(uid) high2lowuid(uid)
+#define NEW_TO_OLD_GID(gid) high2lowgid(gid)
+#define SET_OLDSTAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
+#define SET_OLDSTAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
+#define SET_STAT_UID(stat, uid) (stat).st_uid = high2lowuid(uid)
+#define SET_STAT_GID(stat, gid) (stat).st_gid = high2lowgid(gid)
+
+asmlinkage long sys32_chown16(const char * filename, u16 user, u16 group)
+{
+ return sys_chown(filename, low2highuid(user), low2highgid(group));
+}
+
+asmlinkage long sys32_lchown16(const char * filename, u16 user, u16 group)
+{
+ return sys_lchown(filename, low2highuid(user), low2highgid(group));
+}
+
+asmlinkage long sys32_fchown16(unsigned int fd, u16 user, u16 group)
+{
+ return sys_fchown(fd, low2highuid(user), low2highgid(group));
+}
+
+asmlinkage long sys32_setregid16(u16 rgid, u16 egid)
+{
+ return sys_setregid(low2highgid(rgid), low2highgid(egid));
+}
+
+asmlinkage long sys32_setgid16(u16 gid)
+{
+ return sys_setgid((gid_t)gid);
+}
+
+asmlinkage long sys32_setreuid16(u16 ruid, u16 euid)
+{
+ return sys_setreuid(low2highuid(ruid), low2highuid(euid));
+}
+
+asmlinkage long sys32_setuid16(u16 uid)
+{
+ return sys_setuid((uid_t)uid);
+}
+
+asmlinkage long sys32_setresuid16(u16 ruid, u16 euid, u16 suid)
+{
+ return sys_setresuid(low2highuid(ruid), low2highuid(euid),
+ low2highuid(suid));
+}
+
+asmlinkage long sys32_getresuid16(u16 *ruid, u16 *euid, u16 *suid)
+{
+ int retval;
+
+ if (!(retval = put_user(high2lowuid(current->uid), ruid)) &&
+ !(retval = put_user(high2lowuid(current->euid), euid)))
+ retval = put_user(high2lowuid(current->suid), suid);
+
+ return retval;
+}
+
+asmlinkage long sys32_setresgid16(u16 rgid, u16 egid, u16 sgid)
+{
+ return sys_setresgid(low2highgid(rgid), low2highgid(egid),
+ low2highgid(sgid));
+}
+
+asmlinkage long sys32_getresgid16(u16 *rgid, u16 *egid, u16 *sgid)
+{
+ int retval;
+
+ if (!(retval = put_user(high2lowgid(current->gid), rgid)) &&
+ !(retval = put_user(high2lowgid(current->egid), egid)))
+ retval = put_user(high2lowgid(current->sgid), sgid);
+
+ return retval;
+}
+
+asmlinkage long sys32_setfsuid16(u16 uid)
+{
+ return sys_setfsuid((uid_t)uid);
+}
+
+asmlinkage long sys32_setfsgid16(u16 gid)
+{
+ return sys_setfsgid((gid_t)gid);
+}
+
+asmlinkage long sys32_getgroups16(int gidsetsize, u16 *grouplist)
+{
+ u16 groups[NGROUPS];
+ int i,j;
+
+ if (gidsetsize < 0)
+ return -EINVAL;
+ i = current->ngroups;
+ if (gidsetsize) {
+ if (i > gidsetsize)
+ return -EINVAL;
+ for(j=0;j<i;j++)
+ groups[j] = current->groups[j];
+ if (copy_to_user(grouplist, groups, sizeof(u16)*i))
+ return -EFAULT;
+ }
+ return i;
+}
+
+asmlinkage long sys32_setgroups16(int gidsetsize, u16 *grouplist)
+{
+ u16 groups[NGROUPS];
+ int i;
+
+ if (!capable(CAP_SETGID))
+ return -EPERM;
+ if ((unsigned) gidsetsize > NGROUPS)
+ return -EINVAL;
+ if (copy_from_user(groups, grouplist, gidsetsize * sizeof(u16)))
+ return -EFAULT;
+ for (i = 0 ; i < gidsetsize ; i++)
+ current->groups[i] = (gid_t)groups[i];
+ current->ngroups = gidsetsize;
+ return 0;
+}
+
+asmlinkage long sys32_getuid16(void)
+{
+ return high2lowuid(current->uid);
+}
+
+asmlinkage long sys32_geteuid16(void)
+{
+ return high2lowuid(current->euid);
+}
+
+asmlinkage long sys32_getgid16(void)
+{
+ return high2lowgid(current->gid);
+}
+
+asmlinkage long sys32_getegid16(void)
+{
+ return high2lowgid(current->egid);
+}
+
/* In order to reduce some races, while at the same time doing additional
* checking and hopefully speeding things up, we copy filenames to the
* kernel data space before using them..
@@ -191,6 +367,17 @@ struct semid_ds32 {
unsigned short sem_nsems; /* no. of semaphores in array */
};
+struct semid64_ds32 {
+ struct ipc64_perm sem_perm; /* this structure is the same on sparc32 and sparc64 */
+ unsigned int __pad1;
+ __kernel_time_t32 sem_otime;
+ unsigned int __pad2;
+ __kernel_time_t32 sem_ctime;
+ u32 sem_nsems;
+ u32 __unused1;
+ u32 __unused2;
+};
+
struct msqid_ds32
{
struct ipc_perm32 msg_perm;
@@ -208,16 +395,51 @@ struct msqid_ds32
__kernel_ipc_pid_t32 msg_lrpid;
};
+struct msqid64_ds32 {
+ struct ipc64_perm msg_perm;
+ unsigned int __pad1;
+ __kernel_time_t32 msg_stime;
+ unsigned int __pad2;
+ __kernel_time_t32 msg_rtime;
+ unsigned int __pad3;
+ __kernel_time_t32 msg_ctime;
+ unsigned int msg_cbytes;
+ unsigned int msg_qnum;
+ unsigned int msg_qbytes;
+ __kernel_pid_t32 msg_lspid;
+ __kernel_pid_t32 msg_lrpid;
+ unsigned int __unused1;
+ unsigned int __unused2;
+};
+
+
struct shmid_ds32 {
- struct ipc_perm32 shm_perm;
- int shm_segsz;
- __kernel_time_t32 shm_atime;
- __kernel_time_t32 shm_dtime;
- __kernel_time_t32 shm_ctime;
- __kernel_ipc_pid_t32 shm_cpid;
- __kernel_ipc_pid_t32 shm_lpid;
- unsigned short shm_nattch;
+ struct ipc_perm32 shm_perm;
+ int shm_segsz;
+ __kernel_time_t32 shm_atime;
+ __kernel_time_t32 shm_dtime;
+ __kernel_time_t32 shm_ctime;
+ __kernel_ipc_pid_t32 shm_cpid;
+ __kernel_ipc_pid_t32 shm_lpid;
+ unsigned short shm_nattch;
+};
+
+struct shmid64_ds32 {
+ struct ipc64_perm shm_perm;
+ unsigned int __pad1;
+ __kernel_time_t32 shm_atime;
+ unsigned int __pad2;
+ __kernel_time_t32 shm_dtime;
+ unsigned int __pad3;
+ __kernel_time_t32 shm_ctime;
+ __kernel_size_t32 shm_segsz;
+ __kernel_pid_t32 shm_cpid;
+ __kernel_pid_t32 shm_lpid;
+ unsigned int shm_nattch;
+ unsigned int __unused1;
+ unsigned int __unused2;
};
+
/*
* sys32_ipc() is the de-multiplexer for the SysV IPC calls in 32bit emulation..
@@ -245,6 +467,34 @@ static int do_sys32_semctl(int first, int second, int third, void *uptr)
IPCOP_MASK (GETPID) | IPCOP_MASK (GETNCNT) | IPCOP_MASK (GETZCNT) |
IPCOP_MASK (GETALL) | IPCOP_MASK (SETALL) | IPCOP_MASK (IPC_RMID))) {
err = sys_semctl (first, second, third, fourth);
+ } else if (third & IPC_64) {
+ struct semid64_ds s;
+ struct semid64_ds32 *usp = (struct semid64_ds32 *)A(pad);
+ mm_segment_t old_fs;
+ int need_back_translation;
+
+ if (third == (IPC_SET|IPC_64)) {
+ err = get_user (s.sem_perm.uid, &usp->sem_perm.uid);
+ err |= __get_user (s.sem_perm.gid, &usp->sem_perm.gid);
+ err |= __get_user (s.sem_perm.mode, &usp->sem_perm.mode);
+ if (err)
+ goto out;
+ fourth.__pad = &s;
+ }
+ need_back_translation =
+ (IPCOP_MASK (third) &
+ (IPCOP_MASK (SEM_STAT) | IPCOP_MASK (IPC_STAT))) != 0;
+ if (need_back_translation)
+ fourth.__pad = &s;
+ old_fs = get_fs ();
+ set_fs (KERNEL_DS);
+ err = sys_semctl (first, second, third, fourth);
+ set_fs (old_fs);
+ if (need_back_translation) {
+ int err2 = copy_to_user (&usp->sem_perm, &s.sem_perm, sizeof(struct ipc64_perm) + 2*sizeof(time_t));
+ err2 |= __put_user (s.sem_nsems, &usp->sem_nsems);
+ if (err2) err = -EFAULT;
+ }
} else {
struct semid_ds s;
struct semid_ds32 *usp = (struct semid_ds32 *)A(pad);
@@ -270,10 +520,10 @@ static int do_sys32_semctl(int first, int second, int third, void *uptr)
set_fs (old_fs);
if (need_back_translation) {
int err2 = put_user (s.sem_perm.key, &usp->sem_perm.key);
- err2 |= __put_user (s.sem_perm.uid, &usp->sem_perm.uid);
- err2 |= __put_user (s.sem_perm.gid, &usp->sem_perm.gid);
- err2 |= __put_user (s.sem_perm.cuid, &usp->sem_perm.cuid);
- err2 |= __put_user (s.sem_perm.cgid, &usp->sem_perm.cgid);
+ err2 |= __put_user (high2lowuid(s.sem_perm.uid), &usp->sem_perm.uid);
+ err2 |= __put_user (high2lowgid(s.sem_perm.gid), &usp->sem_perm.gid);
+ err2 |= __put_user (high2lowuid(s.sem_perm.cuid), &usp->sem_perm.cuid);
+ err2 |= __put_user (high2lowgid(s.sem_perm.cgid), &usp->sem_perm.cgid);
err2 |= __put_user (s.sem_perm.mode, &usp->sem_perm.mode);
err2 |= __put_user (s.sem_perm.seq, &usp->sem_perm.seq);
err2 |= __put_user (s.sem_otime, &usp->sem_otime);
@@ -357,6 +607,34 @@ static int do_sys32_msgctl (int first, int second, void *uptr)
(IPCOP_MASK (IPC_INFO) | IPCOP_MASK (MSG_INFO) |
IPCOP_MASK (IPC_RMID))) {
err = sys_msgctl (first, second, (struct msqid_ds *)uptr);
+ } else if (second & IPC_64) {
+ struct msqid64_ds m;
+ struct msqid64_ds32 *up = (struct msqid64_ds32 *)uptr;
+ mm_segment_t old_fs;
+
+ if (second == (IPC_SET|IPC_64)) {
+ err = get_user (m.msg_perm.uid, &up->msg_perm.uid);
+ err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);
+ err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);
+ err |= __get_user (m.msg_qbytes, &up->msg_qbytes);
+ if (err)
+ goto out;
+ }
+ old_fs = get_fs ();
+ set_fs (KERNEL_DS);
+ err = sys_msgctl (first, second, (struct msqid_ds *)&m);
+ set_fs (old_fs);
+ if (IPCOP_MASK (second) &
+ (IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
+ int err2 = copy_to_user(&up->msg_perm, &m.msg_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
+ err2 |= __put_user (m.msg_cbytes, &up->msg_cbytes);
+ err2 |= __put_user (m.msg_qnum, &up->msg_qnum);
+ err2 |= __put_user (m.msg_qbytes, &up->msg_qbytes);
+ err2 |= __put_user (m.msg_lspid, &up->msg_lspid);
+ err2 |= __put_user (m.msg_lrpid, &up->msg_lrpid);
+ if (err2)
+ err = -EFAULT;
+ }
} else {
struct msqid_ds m;
struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;
@@ -377,10 +655,10 @@ static int do_sys32_msgctl (int first, int second, void *uptr)
if (IPCOP_MASK (second) &
(IPCOP_MASK (MSG_STAT) | IPCOP_MASK (IPC_STAT))) {
int err2 = put_user (m.msg_perm.key, &up->msg_perm.key);
- err2 |= __put_user (m.msg_perm.uid, &up->msg_perm.uid);
- err2 |= __put_user (m.msg_perm.gid, &up->msg_perm.gid);
- err2 |= __put_user (m.msg_perm.cuid, &up->msg_perm.cuid);
- err2 |= __put_user (m.msg_perm.cgid, &up->msg_perm.cgid);
+ err2 |= __put_user (high2lowuid(m.msg_perm.uid), &up->msg_perm.uid);
+ err2 |= __put_user (high2lowgid(m.msg_perm.gid), &up->msg_perm.gid);
+ err2 |= __put_user (high2lowuid(m.msg_perm.cuid), &up->msg_perm.cuid);
+ err2 |= __put_user (high2lowgid(m.msg_perm.cgid), &up->msg_perm.cgid);
err2 |= __put_user (m.msg_perm.mode, &up->msg_perm.mode);
err2 |= __put_user (m.msg_perm.seq, &up->msg_perm.seq);
err2 |= __put_user (m.msg_stime, &up->msg_stime);
@@ -423,12 +701,45 @@ static int do_sys32_shmctl (int first, int second, void *uptr)
if (IPCOP_MASK (second) &
(IPCOP_MASK (IPC_INFO) | IPCOP_MASK (SHM_LOCK) | IPCOP_MASK (SHM_UNLOCK) |
IPCOP_MASK (IPC_RMID))) {
+ if (second == (IPC_INFO|IPC_64))
+ second = IPC_INFO; /* So that we don't have to translate it */
err = sys_shmctl (first, second, (struct shmid_ds *)uptr);
+ } else if ((second & IPC_64) && second != (SHM_INFO|IPC_64)) {
+ struct shmid64_ds s;
+ struct shmid64_ds32 *up = (struct shmid64_ds32 *)uptr;
+ mm_segment_t old_fs;
+
+ if (second == (IPC_SET|IPC_64)) {
+ err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
+ err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
+ err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);
+ if (err)
+ goto out;
+ }
+ old_fs = get_fs ();
+ set_fs (KERNEL_DS);
+ err = sys_shmctl (first, second, (struct shmid_ds *)&s);
+ set_fs (old_fs);
+ if (err < 0)
+ goto out;
+
+ /* Mask it even in this case so it becomes a CSE. */
+ if (IPCOP_MASK (second) &
+ (IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
+ int err2 = copy_to_user (&up->shm_perm, &s.shm_perm, sizeof(struct ipc64_perm) + 3*sizeof(time_t));
+ err2 |= __put_user (s.shm_segsz, &up->shm_segsz);
+ err2 |= __put_user (s.shm_nattch, &up->shm_nattch);
+ err2 |= __put_user (s.shm_cpid, &up->shm_cpid);
+ err2 |= __put_user (s.shm_lpid, &up->shm_lpid);
+ if (err2)
+ err = -EFAULT;
+ }
} else {
struct shmid_ds s;
struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;
mm_segment_t old_fs;
+ second &= ~IPC_64;
if (second == IPC_SET) {
err = get_user (s.shm_perm.uid, &up->shm_perm.uid);
err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);
@@ -462,10 +773,10 @@ static int do_sys32_shmctl (int first, int second, void *uptr)
} else if (IPCOP_MASK (second) &
(IPCOP_MASK (SHM_STAT) | IPCOP_MASK (IPC_STAT))) {
int err2 = put_user (s.shm_perm.key, &up->shm_perm.key);
- err2 |= __put_user (s.shm_perm.uid, &up->shm_perm.uid);
- err2 |= __put_user (s.shm_perm.gid, &up->shm_perm.gid);
- err2 |= __put_user (s.shm_perm.cuid, &up->shm_perm.cuid);
- err2 |= __put_user (s.shm_perm.cgid, &up->shm_perm.cgid);
+ err2 |= __put_user (high2lowuid(s.shm_perm.uid), &up->shm_perm.uid);
+ err2 |= __put_user (high2lowuid(s.shm_perm.gid), &up->shm_perm.gid);
+ err2 |= __put_user (high2lowuid(s.shm_perm.cuid), &up->shm_perm.cuid);
+ err2 |= __put_user (high2lowuid(s.shm_perm.cgid), &up->shm_perm.cgid);
err2 |= __put_user (s.shm_perm.mode, &up->shm_perm.mode);
err2 |= __put_user (s.shm_perm.seq, &up->shm_perm.seq);
err2 |= __put_user (s.shm_atime, &up->shm_atime);
@@ -1244,8 +1555,8 @@ static int cp_new_stat32(struct inode *inode, struct stat32 *statbuf)
err |= put_user(ino, &statbuf->st_ino);
err |= put_user(mode, &statbuf->st_mode);
err |= put_user(nlink, &statbuf->st_nlink);
- err |= put_user(uid, &statbuf->st_uid);
- err |= put_user(gid, &statbuf->st_gid);
+ err |= put_user(high2lowuid(uid), &statbuf->st_uid);
+ err |= put_user(high2lowgid(gid), &statbuf->st_gid);
err |= put_user(kdev_t_to_nr(rdev), &statbuf->st_rdev);
err |= put_user(size, &statbuf->st_size);
err |= put_user(atime, &statbuf->st_atime);
@@ -1392,11 +1703,11 @@ static void *do_ncp_super_data_conv(void *raw_data)
n->dir_mode = n32->dir_mode;
n->file_mode = n32->file_mode;
- n->gid = n32->gid;
- n->uid = n32->uid;
+ n->gid = low2highgid(n32->gid);
+ n->uid = low2highuid(n32->uid);
memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
n->wdog_pid = n32->wdog_pid;
- n->mounted_uid = n32->mounted_uid;
+ n->mounted_uid = low2highuid(n32->mounted_uid);
return raw_data;
}
@@ -1415,9 +1726,9 @@ static void *do_smb_super_data_conv(void *raw_data)
struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
s->version = s32->version;
- s->mounted_uid = s32->mounted_uid;
- s->uid = s32->uid;
- s->gid = s32->gid;
+ s->mounted_uid = low2highuid(s32->mounted_uid);
+ s->uid = low2highuid(s32->uid);
+ s->gid = low2highgid(s32->gid);
s->file_mode = s32->file_mode;
s->dir_mode = s32->dir_mode;
return raw_data;
@@ -1853,91 +2164,6 @@ sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo)
return ret;
}
-extern asmlinkage int sys_setreuid(uid_t ruid, uid_t euid);
-
-asmlinkage int sys32_setreuid(__kernel_uid_t32 ruid, __kernel_uid_t32 euid)
-{
- uid_t sruid, seuid;
-
- sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
- seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
- return sys_setreuid(sruid, seuid);
-}
-
-extern asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
-
-asmlinkage int sys32_setresuid(__kernel_uid_t32 ruid,
- __kernel_uid_t32 euid,
- __kernel_uid_t32 suid)
-{
- uid_t sruid, seuid, ssuid;
-
- sruid = (ruid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)ruid);
- seuid = (euid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)euid);
- ssuid = (suid == (__kernel_uid_t32)-1) ? ((uid_t)-1) : ((uid_t)suid);
- return sys_setresuid(sruid, seuid, ssuid);
-}
-
-extern asmlinkage int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
-
-asmlinkage int sys32_getresuid(__kernel_uid_t32 *ruid, __kernel_uid_t32 *euid, __kernel_uid_t32 *suid)
-{
- uid_t a, b, c;
- int ret;
- mm_segment_t old_fs = get_fs();
-
- set_fs (KERNEL_DS);
- ret = sys_getresuid(&a, &b, &c);
- set_fs (old_fs);
- if (put_user (a, ruid) || put_user (b, euid) || put_user (c, suid))
- return -EFAULT;
- return ret;
-}
-
-extern asmlinkage int sys_setregid(gid_t rgid, gid_t egid);
-
-asmlinkage int sys32_setregid(__kernel_gid_t32 rgid, __kernel_gid_t32 egid)
-{
- gid_t srgid, segid;
-
- srgid = (rgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)rgid);
- segid = (egid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)egid);
- return sys_setregid(srgid, segid);
-}
-
-extern asmlinkage int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
-
-asmlinkage int sys32_setresgid(__kernel_gid_t32 rgid,
- __kernel_gid_t32 egid,
- __kernel_gid_t32 sgid)
-{
- gid_t srgid, segid, ssgid;
-
- srgid = (rgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)rgid);
- segid = (egid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)egid);
- ssgid = (sgid == (__kernel_gid_t32)-1) ? ((gid_t)-1) : ((gid_t)sgid);
- return sys_setresgid(srgid, segid, ssgid);
-}
-
-extern asmlinkage int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
-
-asmlinkage int sys32_getresgid(__kernel_gid_t32 *rgid, __kernel_gid_t32 *egid, __kernel_gid_t32 *sgid)
-{
- gid_t a, b, c;
- int ret;
- mm_segment_t old_fs = get_fs();
-
- set_fs (KERNEL_DS);
- ret = sys_getresgid(&a, &b, &c);
- set_fs (old_fs);
- if (!ret) {
- ret = put_user (a, rgid);
- ret |= put_user (b, egid);
- ret |= put_user (c, sgid);
- }
- return ret;
-}
-
struct tms32 {
__kernel_clock_t32 tms_utime;
__kernel_clock_t32 tms_stime;
@@ -1968,43 +2194,6 @@ asmlinkage long sys32_times(struct tms32 *tbuf)
return ret;
}
-extern asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist);
-
-asmlinkage int sys32_getgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
-{
- gid_t gl[NGROUPS];
- int ret, i;
- mm_segment_t old_fs = get_fs ();
-
- set_fs (KERNEL_DS);
- ret = sys_getgroups(gidsetsize, gl);
- set_fs (old_fs);
- if (gidsetsize && ret > 0 && ret <= NGROUPS)
- for (i = 0; i < ret; i++, grouplist++)
- if (__put_user (gl[i], grouplist))
- return -EFAULT;
- return ret;
-}
-
-extern asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist);
-
-asmlinkage int sys32_setgroups(int gidsetsize, __kernel_gid_t32 *grouplist)
-{
- gid_t gl[NGROUPS];
- int ret, i;
- mm_segment_t old_fs = get_fs ();
-
- if ((unsigned) gidsetsize > NGROUPS)
- return -EINVAL;
- for (i = 0; i < gidsetsize; i++, grouplist++)
- if (__get_user (gl[i], grouplist))
- return -EFAULT;
- set_fs (KERNEL_DS);
- ret = sys_setgroups(gidsetsize, gl);
- set_fs (old_fs);
- return ret;
-}
-
#define RLIM_INFINITY32 0x7fffffff
#define RESOURCE32(x) ((x > RLIM_INFINITY32) ? RLIM_INFINITY32 : x)
@@ -3554,6 +3743,8 @@ static int nfs_exp32_trans(struct nfsctl_arg *karg, struct nfsctl_arg32 *arg32)
&arg32->ca32_export.ex32_anon_uid);
err |= __get_user(karg->ca_export.ex_anon_gid,
&arg32->ca32_export.ex32_anon_gid);
+ karg->ca_export.ex_anon_uid = high2lowuid(karg->ca_export.ex_anon_uid);
+ karg->ca_export.ex_anon_gid = high2lowgid(karg->ca_export.ex_anon_gid);
return err;
}
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S
index 27355da96..b66a116b4 100644
--- a/arch/sparc64/kernel/systbls.S
+++ b/arch/sparc64/kernel/systbls.S
@@ -1,4 +1,4 @@
-/* $Id: systbls.S,v 1.62 2000/01/04 23:54:43 davem Exp $
+/* $Id: systbls.S,v 1.65 2000/01/14 07:12:34 davem Exp $
* systbls.S: System call entry point tables for OS compatibility.
* The native Linux system call table lives here also.
*
@@ -21,30 +21,30 @@
sys_call_table32:
/*0*/ .word sys_nis_syscall, sparc_exit, sys_fork, sys_read, sys_write
/*5*/ .word sparc32_open, sys_close, sys32_wait4, sys_creat, sys_link
-/*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys32_chown, sys32_mknod
-/*15*/ .word sys32_chmod, sys32_lchown, sparc_brk, sys_perfctr, sys32_lseek
-/*20*/ .word sys_getpid, sys_capget, sys_capset, sys_setuid, sys_getuid
+/*10*/ .word sys_unlink, sunos_execv, sys_chdir, sys32_chown16, sys32_mknod
+/*15*/ .word sys32_chmod, sys32_lchown16, sparc_brk, sys_perfctr, sys32_lseek
+/*20*/ .word sys_getpid, sys_capget, sys_capset, sys32_setuid16, sys32_getuid16
/*25*/ .word sys_time, sys_ptrace, sys_alarm, sys32_sigaltstack, sys32_pause
-/*30*/ .word sys32_utime, sys_nis_syscall, sys_nis_syscall, sys_access, sys_nice
- .word sys_nis_syscall, sys_sync, sys_kill, sys32_newstat, sys32_sendfile
-/*40*/ .word sys32_newlstat, sys_dup, sys_pipe, sys32_times, sys_nis_syscall
- .word sys_umount, sys_setgid, sys_getgid, sys_signal, sys_geteuid
-/*50*/ .word sys_getegid, sys_acct, sys_nis_syscall, sys_nis_syscall, sys32_ioctl
+/*30*/ .word sys32_utime, sys_lchown, sys_fchown, sys_access, sys_nice
+ .word sys_chown, sys_sync, sys_kill, sys32_newstat, sys32_sendfile
+/*40*/ .word sys32_newlstat, sys_dup, sys_pipe, sys32_times, sys_getuid
+ .word sys_umount, sys32_setgid16, sys32_getgid16, sys_signal, sys32_geteuid16
+/*50*/ .word sys32_getegid16, sys_acct, sys_nis_syscall, sys_getgid, sys32_ioctl
.word sys_reboot, sys32_mmap2, sys_symlink, sys_readlink, sys32_execve
/*60*/ .word sys_umask, sys_chroot, sys32_newfstat, sys_fstat64, sys_getpagesize
- .word sys_msync, sys_vfork, sys32_pread, sys32_pwrite, sys_nis_syscall
-/*70*/ .word sys_nis_syscall, sys32_mmap, sys_nis_syscall, sys_munmap, sys_mprotect
- .word sys_nis_syscall, sys_vhangup, sys32_truncate64, sys_nis_syscall, sys32_getgroups
-/*80*/ .word sys32_setgroups, sys_getpgrp, sys_nis_syscall, sys32_setitimer, sys32_ftruncate64
- .word sys_swapon, sys32_getitimer, sys_nis_syscall, sys_sethostname, sys_nis_syscall
-/*90*/ .word sys_dup2, sys_nis_syscall, sys32_fcntl, sys32_select, sys_nis_syscall
+ .word sys_msync, sys_vfork, sys32_pread, sys32_pwrite, sys_geteuid
+/*70*/ .word sys_getegid, sys32_mmap, sys_setreuid, sys_munmap, sys_mprotect
+ .word sys_setregid, sys_vhangup, sys32_truncate64, sys_getgroups, sys32_getgroups16
+/*80*/ .word sys32_setgroups16, sys_getpgrp, sys_setgroups, sys32_setitimer, sys32_ftruncate64
+ .word sys_swapon, sys32_getitimer, sys_setuid, sys_sethostname, sys_setgid
+/*90*/ .word sys_dup2, sys_setfsuid, sys32_fcntl, sys32_select, sys_setfsgid
.word sys_fsync, sys_setpriority, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
/*100*/ .word sys_getpriority, sys32_rt_sigreturn, sys32_rt_sigaction, sys32_rt_sigprocmask, sys32_rt_sigpending
- .word sys32_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_nis_syscall, sys_nis_syscall
-/*110*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
+ .word sys32_rt_sigtimedwait, sys32_rt_sigqueueinfo, sys32_rt_sigsuspend, sys_setresuid, sys_getresuid
+/*110*/ .word sys_setresgid, sys_getresgid, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall
.word sys_nis_syscall, sys32_gettimeofday, sys32_getrusage, sys_nis_syscall, sys_getcwd
-/*120*/ .word sys32_readv, sys32_writev, sys32_settimeofday, sys_fchown, sys_fchmod
- .word sys_nis_syscall, sys32_setreuid, sys32_setregid, sys_rename, sys_truncate
+/*120*/ .word sys32_readv, sys32_writev, sys32_settimeofday, sys32_fchown16, sys_fchmod
+ .word sys_nis_syscall, sys32_setreuid16, sys32_setregid16, sys_rename, sys_truncate
/*130*/ .word sys_ftruncate, sys_flock, sys_lstat64, sys_nis_syscall, sys_nis_syscall
.word sys_nis_syscall, sys_mkdir, sys_rmdir, sys32_utimes, sys_stat64
/*140*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys32_getrlimit
@@ -64,7 +64,7 @@ sys_call_table32:
/*210*/ .word sys_nis_syscall, sys_nis_syscall, sys_waitpid, sys_swapoff, sys32_sysinfo
.word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex
/*220*/ .word sys32_sigprocmask, sys32_create_module, sys32_delete_module, sys32_get_kernel_syms, sys_getpgid
- .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid
+ .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16
/*230*/ .word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_nis_syscall
.word sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
/*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
@@ -99,8 +99,8 @@ sys_call_table:
/*90*/ .word sys_dup2, sys_nis_syscall, sys_fcntl, sys_select, sys_nis_syscall
.word sys_fsync, sys_setpriority, sys_socket, sys_connect, sys_accept
/*100*/ .word sys_getpriority, sys_rt_sigreturn, sys_rt_sigaction, sys_rt_sigprocmask, sys_rt_sigpending
- .word sys_rt_sigtimedwait, sys_rt_sigqueueinfo, sys_rt_sigsuspend, sys_nis_syscall, sys_nis_syscall
-/*110*/ .word sys_nis_syscall, sys_nis_syscall, sys_nis_syscall, sys_recvmsg, sys_sendmsg
+ .word sys_rt_sigtimedwait, sys_rt_sigqueueinfo, sys_rt_sigsuspend, sys_setresuid, sys_getresuid
+/*110*/ .word sys_setresgid, sys_getresgid, sys_nis_syscall, sys_recvmsg, sys_sendmsg
.word sys_nis_syscall, sys_gettimeofday, sys_getrusage, sys_getsockopt, sys_getcwd
/*120*/ .word sys_readv, sys_writev, sys_settimeofday, sys_fchown, sys_fchmod
.word sys_recvfrom, sys_setreuid, sys_setregid, sys_rename, sys_truncate
@@ -143,7 +143,7 @@ sunos_sys_table:
.word sys_close, sunos_wait4, sys_creat
.word sys_link, sys_unlink, sunos_execv
.word sys_chdir, sunos_nosys, sys32_mknod
- .word sys32_chmod, sys32_lchown, sunos_brk
+ .word sys32_chmod, sys32_lchown16, sunos_brk
.word sunos_nosys, sys32_lseek, sunos_getpid
.word sunos_nosys, sunos_nosys, sunos_nosys
.word sunos_getuid, sunos_nosys, sys_ptrace
@@ -164,8 +164,8 @@ sunos_sys_table:
.word sunos_nosys, sunos_sbrk, sunos_sstk
.word sunos_mmap, sunos_vadvise, sys_munmap
.word sys_mprotect, sunos_madvise, sys_vhangup
- .word sunos_nosys, sunos_mincore, sys32_getgroups
- .word sys32_setgroups, sys_getpgrp, sunos_setpgrp
+ .word sunos_nosys, sunos_mincore, sys32_getgroups16
+ .word sys32_setgroups16, sys_getpgrp, sunos_setpgrp
.word sys32_setitimer, sunos_nosys, sys_swapon
.word sys32_getitimer, sys_gethostname, sys_sethostname
.word sunos_getdtablesize, sys_dup2, sunos_nop
@@ -179,9 +179,9 @@ sunos_sys_table:
.word sys32_sigstack, sys32_recvmsg, sys32_sendmsg
.word sunos_nosys, sys32_gettimeofday, sys32_getrusage
.word sunos_getsockopt, sunos_nosys, sunos_readv
- .word sunos_writev, sys32_settimeofday, sys_fchown
- .word sys_fchmod, sys32_recvfrom, sys32_setreuid
- .word sys_setregid, sys_rename, sys_truncate
+ .word sunos_writev, sys32_settimeofday, sys32_fchown16
+ .word sys_fchmod, sys32_recvfrom, sys32_setreuid16
+ .word sys32_setregid16, sys_rename, sys_truncate
.word sys_ftruncate, sys_flock, sunos_nosys
.word sys32_sendto, sys_shutdown, sys_socketpair
.word sys_mkdir, sys_rmdir, sys32_utimes
diff --git a/arch/sparc64/mm/asyncd.c b/arch/sparc64/mm/asyncd.c
index a64b09e86..f23a04ede 100644
--- a/arch/sparc64/mm/asyncd.c
+++ b/arch/sparc64/mm/asyncd.c
@@ -1,4 +1,4 @@
-/* $Id: asyncd.c,v 1.10 1999/12/15 22:25:02 davem Exp $
+/* $Id: asyncd.c,v 1.11 2000/01/08 20:22:19 davem Exp $
* The asyncd kernel daemon. This handles paging on behalf of
* processes that receive page faults due to remote (async) memory
* accesses.
@@ -263,10 +263,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(); /* acquire gloabl_irq_lock */
}
restore_flags(flags);
diff --git a/arch/sparc64/solaris/entry64.S b/arch/sparc64/solaris/entry64.S
index 53d825e6d..eb9cf3d26 100644
--- a/arch/sparc64/solaris/entry64.S
+++ b/arch/sparc64/solaris/entry64.S
@@ -1,4 +1,4 @@
-/* $Id: entry64.S,v 1.5 1998/03/26 08:46:15 jj Exp $
+/* $Id: entry64.S,v 1.6 2000/01/12 02:59:26 davem Exp $
* entry64.S: Solaris syscall emulation entry point.
*
* Copyright (C) 1996,1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -183,15 +183,15 @@ solaris_getpid:
.globl solaris_getuid
solaris_getuid:
- lduh [%g6 + AOFF_task_euid], %o1
- lduh [%g6 + AOFF_task_uid], %o0
+ lduw [%g6 + AOFF_task_euid], %o1
+ lduw [%g6 + AOFF_task_uid], %o0
b,pt %xcc, ret_from_solaris
stx %o1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1]
.globl solaris_getgid
solaris_getgid:
- lduh [%g6 + AOFF_task_egid], %o1
- lduh [%g6 + AOFF_task_gid], %o0
+ lduw [%g6 + AOFF_task_egid], %o1
+ lduw [%g6 + AOFF_task_gid], %o0
b,pt %xcc, ret_from_solaris
stx %o1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1]
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
index 86b0df283..e15ef157c 100644
--- a/arch/sparc64/solaris/fs.c
+++ b/arch/sparc64/solaris/fs.c
@@ -1,4 +1,4 @@
-/* $Id: fs.c,v 1.15 2000/01/04 23:54:47 davem Exp $
+/* $Id: fs.c,v 1.16 2000/01/12 02:59:27 davem Exp $
* fs.c: fs related syscall emulation for Solaris
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -708,71 +708,6 @@ asmlinkage int solaris_ulimit(int cmd, int val)
return -EINVAL;
}
-static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
-{
- struct inode * inode;
- struct iattr newattrs;
- int error;
-
- error = -ENOENT;
- if (!(inode = dentry->d_inode)) {
- printk("chown_common: NULL inode\n");
- goto out;
- }
- error = -EROFS;
- if (IS_RDONLY(inode))
- goto out;
- error = -EPERM;
- if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
- goto out;
- if (user == (uid_t) -1)
- user = inode->i_uid;
- if (group == (gid_t) -1)
- group = inode->i_gid;
- newattrs.ia_mode = inode->i_mode;
- newattrs.ia_uid = user;
- newattrs.ia_gid = group;
- newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME;
- /*
- * If the owner has been changed, remove the setuid bit
- */
- if (inode->i_mode & S_ISUID) {
- newattrs.ia_mode &= ~S_ISUID;
- newattrs.ia_valid |= ATTR_MODE;
- }
- /*
- * If the group has been changed, remove the setgid bit
- *
- * Don't remove the setgid bit if no group execute bit.
- * This is a file marked for mandatory locking.
- */
- if (((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))) {
- newattrs.ia_mode &= ~S_ISGID;
- newattrs.ia_valid |= ATTR_MODE;
- }
- error = DQUOT_TRANSFER(dentry, &newattrs);
-out:
- return error;
-}
-
-/* Linux chown works like Solaris lchown. Solaris chown does follow symlink */
-asmlinkage int solaris_chown(u32 filename, s32 user, s32 group)
-{
- struct dentry * dentry;
- int error;
-
- lock_kernel();
- dentry = namei((const char *)A(filename));
-
- error = PTR_ERR(dentry);
- if (!IS_ERR(dentry)) {
- error = chown_common(dentry, user, group);
- dput(dentry);
- }
- unlock_kernel();
- return error;
-}
-
/* At least at the time I'm writing this, Linux doesn't have ACLs, so we
just fake this */
asmlinkage int solaris_acl(u32 filename, int cmd, int nentries, u32 aclbufp)
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index a07fc7cc2..04e676907 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.19 1999/12/15 17:51:25 jj Exp $
+/* $Id: misc.c,v 1.20 2000/01/12 02:59:26 davem Exp $
* misc.c: Miscelaneous syscall emulation for Solaris
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -401,18 +401,6 @@ asmlinkage int solaris_sysconf(int id)
}
}
-asmlinkage int solaris_setreuid(s32 ruid, s32 euid)
-{
- int (*sys_setreuid)(uid_t, uid_t) = (int (*)(uid_t, uid_t))SYS(setreuid);
- return sys_setreuid(ruid, euid);
-}
-
-asmlinkage int solaris_setregid(s32 rgid, s32 egid)
-{
- int (*sys_setregid)(gid_t, gid_t) = (int (*)(gid_t, gid_t))SYS(setregid);
- return sys_setregid(rgid, egid);
-}
-
asmlinkage int solaris_procids(int cmd, s32 pid, s32 pgid)
{
int ret;
diff --git a/arch/sparc64/solaris/systbl.S b/arch/sparc64/solaris/systbl.S
index 7c7c7b8b1..17562bafd 100644
--- a/arch/sparc64/solaris/systbl.S
+++ b/arch/sparc64/solaris/systbl.S
@@ -1,4 +1,4 @@
-/* $Id: systbl.S,v 1.8 1999/02/11 18:34:02 davem Exp $
+/* $Id: systbl.S,v 1.10 2000/01/12 02:59:26 davem Exp $
* systbl.S: System call entry point table for Solaris compatibility.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -40,7 +40,7 @@ solaris_sys_table:
.word CHAIN(time) /* time 13 */
.word solaris_mknod /* mknod sox 14 */
.word CHAIN(chmod) /* chmod so 15 */
- .word solaris_chown /* chown sdd 16 */
+ .word CHAIN(chown) /* chown sdd 16 */
.word solaris_brk /* brk/break x 17 */
.word solaris_stat /* stat sp 18 */
.word CHAIN(lseek) /* seek/lseek ddd 19 */
@@ -230,8 +230,8 @@ solaris_sys_table:
.word CHAIN(nanosleep) /* nanosleep dd 199 */
.word solaris_facl /* facl dddp 200 */
.word solaris_unimplemented /* 201 */
- .word solaris_setreuid /* setreuid dd 202 */
- .word solaris_setregid /* setregid dd 203 */
+ .word CHAIN(setreuid) /* setreuid dd 202 */
+ .word CHAIN(setregid) /* setregid dd 203 */
.word solaris_unimplemented /* 204 */
.word solaris_unimplemented /* 205 */
.word solaris_unimplemented /* 206 */