summaryrefslogtreecommitdiffstats
path: root/arch/ia64
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-07-18 23:31:08 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-07-18 23:31:08 +0000
commite8f9b6396e79654ea5932f64131cafbe8caadfb1 (patch)
tree90cf8b3a2475a774369eda22247cab7874fd7bbf /arch/ia64
parentd4c419dfaa853f5db107973976d4215ae648e976 (diff)
Merge with Linux 2.4.0-test5-pre2.
Diffstat (limited to 'arch/ia64')
-rw-r--r--arch/ia64/Makefile2
-rw-r--r--arch/ia64/config.in42
-rw-r--r--arch/ia64/dig/setup.c1
-rw-r--r--arch/ia64/hp/hpsim_setup.c6
-rw-r--r--arch/ia64/ia32/Makefile2
-rw-r--r--arch/ia64/ia32/binfmt_elf32.c61
-rw-r--r--arch/ia64/ia32/ia32_entry.S22
-rw-r--r--arch/ia64/ia32/ia32_ioctl.c102
-rw-r--r--arch/ia64/ia32/sys_ia32.c109
-rw-r--r--arch/ia64/kernel/Makefile39
-rw-r--r--arch/ia64/kernel/efi_stub.S9
-rw-r--r--arch/ia64/kernel/entry.S114
-rw-r--r--arch/ia64/kernel/fw-emu.c2
-rw-r--r--arch/ia64/kernel/gate.S3
-rw-r--r--arch/ia64/kernel/head.S7
-rw-r--r--arch/ia64/kernel/ivt.S31
-rw-r--r--arch/ia64/kernel/mca.c3
-rw-r--r--arch/ia64/kernel/mca_asm.S5
-rw-r--r--arch/ia64/kernel/pal.S18
-rw-r--r--arch/ia64/kernel/process.c61
-rw-r--r--arch/ia64/kernel/ptrace.c20
-rw-r--r--arch/ia64/kernel/setup.c24
-rw-r--r--arch/ia64/kernel/signal.c5
-rw-r--r--arch/ia64/kernel/smp.c4
-rw-r--r--arch/ia64/kernel/sys_ia64.c9
-rw-r--r--arch/ia64/kernel/time.c14
-rw-r--r--arch/ia64/kernel/unaligned.c10
-rw-r--r--arch/ia64/kernel/unwind.c12
-rw-r--r--arch/ia64/lib/Makefile24
-rw-r--r--arch/ia64/lib/copy_user.S4
-rw-r--r--arch/ia64/lib/idiv.S184
-rw-r--r--arch/ia64/lib/memcpy.S86
-rw-r--r--arch/ia64/mm/tlb.c2
-rw-r--r--arch/ia64/tools/Makefile8
-rw-r--r--arch/ia64/tools/print_offsets.awk5
-rw-r--r--arch/ia64/tools/print_offsets.c12
-rw-r--r--arch/ia64/vmlinux.lds.S1
37 files changed, 643 insertions, 420 deletions
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
index a87cb7c08..50357e2f7 100644
--- a/arch/ia64/Makefile
+++ b/arch/ia64/Makefile
@@ -11,6 +11,8 @@
NM := $(CROSS_COMPILE)nm -B
AWK := awk
+export AWK
+
LINKFLAGS = -static -T arch/$(ARCH)/vmlinux.lds
AFLAGS += -Wa,-x
EXTRA =
diff --git a/arch/ia64/config.in b/arch/ia64/config.in
index 09131fac7..8b8dd761c 100644
--- a/arch/ia64/config.in
+++ b/arch/ia64/config.in
@@ -1,6 +1,3 @@
-# For a description of the syntax of this configuration file,
-# see Documentation/kbuild/config-language.txt.
-#
mainmenu_name "Kernel configuration of Linux for IA-64 machines"
mainmenu_option next_comment
@@ -71,6 +68,8 @@ bool 'Sysctl support' CONFIG_SYSCTL
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
+
bool 'PCI support' CONFIG_PCI
source drivers/pci/Config.in
@@ -83,17 +82,21 @@ fi
source drivers/parport/Config.in
+fi # !HP_SIM
+
endmenu
+if [ "$CONFIG_NET" = "y" ]; then
+ source net/Config.in
+fi
+
+if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
+
source drivers/mtd/Config.in
source drivers/pnp/Config.in
source drivers/block/Config.in
source drivers/i2o/Config.in
-if [ "$CONFIG_NET" = "y" ]; then
- source net/Config.in
-fi
-
mainmenu_option next_comment
comment 'ATA/IDE/MFM/RLL support'
@@ -107,6 +110,8 @@ else
fi
endmenu
+fi # !HP_SIM
+
mainmenu_option next_comment
comment 'SCSI support'
@@ -114,10 +119,11 @@ tristate 'SCSI support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then
source drivers/scsi/Config.in
- bool 'Simulated SCSI disk' CONFIG_SCSI_SIM
fi
endmenu
+if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
+
if [ "$CONFIG_NET" = "y" ]; then
mainmenu_option next_comment
comment 'Network device support'
@@ -149,7 +155,10 @@ if [ "$CONFIG_CD_NO_IDESCSI" != "n" ]; then
fi
endmenu
+fi # !HP_SIM
+
source drivers/char/Config.in
+
#source drivers/misc/Config.in
source fs/Config.in
@@ -167,6 +176,8 @@ if [ "$CONFIG_VT" = "y" ]; then
endmenu
fi
+if [ "$CONFIG_IA64_HP_SIM" = "n" ]; then
+
mainmenu_option next_comment
comment 'Sound'
@@ -178,6 +189,21 @@ endmenu
source drivers/usb/Config.in
+fi # !HP_SIM
+
+if [ "$CONFIG_IA64_HP_SIM" != "n" -o "$CONFIG_IA64_GENERIC" != "n" ]; then
+ mainmenu_option next_comment
+ comment 'Simulated drivers'
+
+ tristate 'Simulated Ethernet ' CONFIG_SIMETH
+ bool 'Simulated serial driver support' CONFIG_SIM_SERIAL
+ if [ "$CONFIG_SCSI" != "n" ]; then
+ bool 'Simulated SCSI disk' CONFIG_SCSI_SIM
+ fi
+ endmenu
+fi
+
+
mainmenu_option next_comment
comment 'Kernel hacking'
diff --git a/arch/ia64/dig/setup.c b/arch/ia64/dig/setup.c
index 4d22f46a4..45c1f96f5 100644
--- a/arch/ia64/dig/setup.c
+++ b/arch/ia64/dig/setup.c
@@ -19,7 +19,6 @@
#include <linux/console.h>
#include <linux/timex.h>
#include <linux/sched.h>
-#include <linux/mc146818rtc.h>
#include <asm/io.h>
#include <asm/machvec.h>
diff --git a/arch/ia64/hp/hpsim_setup.c b/arch/ia64/hp/hpsim_setup.c
index dfa83e135..aaa87c4dc 100644
--- a/arch/ia64/hp/hpsim_setup.c
+++ b/arch/ia64/hp/hpsim_setup.c
@@ -63,6 +63,12 @@ ia64_ctl_trace (long on)
}
void __init
+hpsim_pci_fixup (void)
+{
+}
+
+
+void __init
hpsim_setup (char **cmdline_p)
{
ROOT_DEV = to_kdev_t(0x0801); /* default to first SCSI drive */
diff --git a/arch/ia64/ia32/Makefile b/arch/ia64/ia32/Makefile
index 1b18cca58..4f3312c01 100644
--- a/arch/ia64/ia32/Makefile
+++ b/arch/ia64/ia32/Makefile
@@ -10,7 +10,7 @@
all: ia32.o
O_TARGET := ia32.o
-O_OBJS := ia32_entry.o sys_ia32.o ia32_signal.o ia32_support.o ia32_traps.o binfmt_elf32.o
+O_OBJS := ia32_entry.o sys_ia32.o ia32_ioctl.o ia32_signal.o ia32_support.o ia32_traps.o binfmt_elf32.o
clean::
diff --git a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
index bd29c97e7..6c63e33a7 100644
--- a/arch/ia64/ia32/binfmt_elf32.c
+++ b/arch/ia64/ia32/binfmt_elf32.c
@@ -6,7 +6,8 @@
* 06/16/00 A. Mallick initialize csd/ssd/tssd/cflg for ia32_load_state
*/
#include <linux/config.h>
-#include <linux/posix_types.h>
+
+#include <linux/types.h>
#include <asm/signal.h>
#include <asm/ia32.h>
@@ -16,7 +17,9 @@
/* Override some function names */
#undef start_thread
#define start_thread ia32_start_thread
+#define elf_format elf32_format
#define init_elf_binfmt init_elf32_binfmt
+#define exit_elf_binfmt exit_elf32_binfmt
#undef CONFIG_BINFMT_ELF
#ifdef CONFIG_BINFMT_ELF32
@@ -28,10 +31,12 @@
# define CONFIG_BINFMT_ELF_MODULE CONFIG_BINFMT_ELF32_MODULE
#endif
-void ia64_elf32_init(struct pt_regs *regs);
-#define ELF_PLAT_INIT(_r) ia64_elf32_init(_r)
+extern void ia64_elf32_init(struct pt_regs *regs);
+extern void put_dirty_page(struct task_struct * tsk, struct page *page, unsigned long address);
+#define ELF_PLAT_INIT(_r) ia64_elf32_init(_r)
#define setup_arg_pages(bprm) ia32_setup_arg_pages(bprm)
+#define elf_map elf_map32
/* Ugly but avoids duplication */
#include "../../../fs/binfmt_elf.c"
@@ -201,3 +206,53 @@ int ia32_setup_arg_pages(struct linux_binprm *bprm)
return 0;
}
+
+static unsigned long
+ia32_mm_addr(unsigned long addr)
+{
+ struct vm_area_struct *vma;
+
+ if ((vma = find_vma(current->mm, addr)) == NULL)
+ return(ELF_PAGESTART(addr));
+ if (vma->vm_start > addr)
+ return(ELF_PAGESTART(addr));
+ return(ELF_PAGEALIGN(addr));
+}
+
+/*
+ * Normally we would do an `mmap' to map in the process's text section.
+ * This doesn't work with IA32 processes as the ELF file might specify
+ * a non page size aligned address. Instead we will just allocate
+ * memory and read the data in from the file. Slightly less efficient
+ * but it works.
+ */
+extern long ia32_do_mmap (struct file *filep, unsigned int len, unsigned int prot,
+ unsigned int flags, unsigned int fd, unsigned int offset);
+
+static unsigned long
+elf_map32 (struct file *filep, unsigned long addr, struct elf_phdr *eppnt, int prot, int type)
+{
+ unsigned long retval;
+
+ if (eppnt->p_memsz >= (1UL<<32) || addr > (1UL<<32) - eppnt->p_memsz)
+ return -EINVAL;
+
+#if 1
+ set_brk(ia32_mm_addr(addr), addr + eppnt->p_memsz);
+ memset((char *) addr + eppnt->p_filesz, 0, eppnt->p_memsz - eppnt->p_filesz);
+ kernel_read(filep, eppnt->p_offset, (char *) addr, eppnt->p_filesz);
+ retval = (unsigned long) addr;
+#else
+ /* doesn't work yet... */
+# define IA32_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_EXEC_PAGESIZE-1))
+# define IA32_PAGEOFFSET(_v) ((_v) & (ELF_EXEC_PAGESIZE-1))
+# define IA32_PAGEALIGN(_v) (((_v) + ELF_EXEC_PAGESIZE - 1) & ~(ELF_EXEC_PAGESIZE - 1))
+
+ down(&current->mm->mmap_sem);
+ retval = ia32_do_mmap(filep, IA32_PAGESTART(addr),
+ eppnt->p_filesz + IA32_PAGEOFFSET(eppnt->p_vaddr), prot, type,
+ eppnt->p_offset - IA32_PAGEOFFSET(eppnt->p_vaddr));
+ up(&current->mm->mmap_sem);
+#endif
+ return retval;
+}
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
index 5bf5ad2c3..a9dc378cf 100644
--- a/arch/ia64/ia32/ia32_entry.S
+++ b/arch/ia64/ia32/ia32_entry.S
@@ -63,13 +63,13 @@ END(ia32_ret_from_syscall)
GLOBAL_ENTRY(ia32_trace_syscall)
PT_REGS_UNWIND_INFO(0)
br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch syscall args
-.Lret4: br.call.sptk.few rp=b6 // do the syscall
-.Lret5: cmp.lt p6,p0=r8,r0 // syscall failed?
+.ret0: br.call.sptk.few rp=b6 // do the syscall
+.ret1: cmp.lt p6,p0=r8,r0 // syscall failed?
adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8
;;
st8.spill [r2]=r8 // store return value in slot for r8
br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch return value
-.Lret6: br.cond.sptk.many ia64_leave_kernel // rp MUST be != ia64_leave_kernel!
+.ret2: br.cond.sptk.many ia64_leave_kernel // rp MUST be != ia64_leave_kernel!
END(ia32_trace_syscall)
GLOBAL_ENTRY(sys32_vfork)
@@ -80,7 +80,7 @@ END(sys32_vfork)
GLOBAL_ENTRY(sys32_fork)
UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2))
- alloc r16=ar.pfs,2,2,3,0
+ alloc r16=ar.pfs,2,2,4,0
mov out0=SIGCHLD // out0 = clone_flags
;;
.fork1:
@@ -90,13 +90,11 @@ GLOBAL_ENTRY(sys32_fork)
UNW(.body)
- adds out2=IA64_SWITCH_STACK_SIZE+16,sp
- adds r2=IA64_SWITCH_STACK_SIZE+IA64_PT_REGS_R12_OFFSET+16,sp
- ;;
- ld8 out1=[r2] // fetch usp from pt_regs.r12
+ mov out1=0
+ mov out2=0
+ adds out3=IA64_SWITCH_STACK_SIZE+16,sp
br.call.sptk.few rp=do_fork
-.ret1:
- mov ar.pfs=loc1
+.ret3: mov ar.pfs=loc1
UNW(.restore sp)
adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
mov rp=loc0
@@ -137,7 +135,7 @@ ia32_syscall_table:
data8 sys32_alarm
data8 sys_ni_syscall
data8 sys_ni_syscall
- data8 sys_ni_syscall /* 30 */
+ data8 ia32_utime /* 30 */
data8 sys_ni_syscall /* old stty syscall holder */
data8 sys_ni_syscall /* old gtty syscall holder */
data8 sys_access
@@ -161,7 +159,7 @@ ia32_syscall_table:
data8 sys_acct
data8 sys_umount /* recycled never used phys( */
data8 sys_ni_syscall /* old lock syscall holder */
- data8 sys_ioctl
+ data8 ia32_ioctl
data8 sys_fcntl /* 55 */
data8 sys_ni_syscall /* old mpx syscall holder */
data8 sys_setpgid
diff --git a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c
new file mode 100644
index 000000000..a5cd927b3
--- /dev/null
+++ b/arch/ia64/ia32/ia32_ioctl.c
@@ -0,0 +1,102 @@
+/*
+ * IA32 Architecture-specific ioctl shim code
+ *
+ * Copyright (C) 2000 VA Linux Co
+ * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
+ */
+
+#include <linux/types.h>
+#include <linux/dirent.h>
+#include <linux/msdos_fs.h>
+#include <linux/mtio.h>
+#include <linux/ncp_fs.h>
+#include <linux/capi.h>
+#include <linux/videodev.h>
+#include <linux/synclink.h>
+#include <linux/atmdev.h>
+#include <linux/atm_eni.h>
+#include <linux/atm_nicstar.h>
+#include <linux/atm_zatm.h>
+#include <linux/atm_idt77105.h>
+#include <linux/ppp_defs.h>
+#include <linux/if_ppp.h>
+#include <linux/ixjuser.h>
+#include <linux/i2o-dev.h>
+
+asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
+
+asmlinkage long ia32_ioctl(unsigned int fd, unsigned int cmd, unsigned int arg)
+{
+
+ switch (cmd) {
+
+ case VFAT_IOCTL_READDIR_BOTH:
+ case VFAT_IOCTL_READDIR_SHORT:
+ case MTIOCGET:
+ case MTIOCPOS:
+ case MTIOCGETCONFIG:
+ case MTIOCSETCONFIG:
+ case PPPIOCSCOMPRESS:
+ case PPPIOCGIDLE:
+ case NCP_IOC_GET_FS_INFO_V2:
+ case NCP_IOC_GETOBJECTNAME:
+ case NCP_IOC_SETOBJECTNAME:
+ case NCP_IOC_GETPRIVATEDATA:
+ case NCP_IOC_SETPRIVATEDATA:
+ case NCP_IOC_GETMOUNTUID2:
+ case CAPI_MANUFACTURER_CMD:
+ case VIDIOCGTUNER:
+ case VIDIOCSTUNER:
+ case VIDIOCGWIN:
+ case VIDIOCSWIN:
+ case VIDIOCGFBUF:
+ case VIDIOCSFBUF:
+ case MGSL_IOCSPARAMS:
+ case MGSL_IOCGPARAMS:
+ case ATM_GETNAMES:
+ case ATM_GETLINKRATE:
+ case ATM_GETTYPE:
+ case ATM_GETESI:
+ case ATM_GETADDR:
+ case ATM_RSTADDR:
+ case ATM_ADDADDR:
+ case ATM_DELADDR:
+ case ATM_GETCIRANGE:
+ case ATM_SETCIRANGE:
+ case ATM_SETESI:
+ case ATM_SETESIF:
+ case ATM_GETSTAT:
+ case ATM_GETSTATZ:
+ case ATM_GETLOOP:
+ case ATM_SETLOOP:
+ case ATM_QUERYLOOP:
+ case ENI_SETMULT:
+ case NS_GETPSTAT:
+ /* case NS_SETBUFLEV: This is a duplicate case with ZATM_GETPOOLZ */
+ case ZATM_GETPOOLZ:
+ case ZATM_GETPOOL:
+ case ZATM_SETPOOL:
+ case ZATM_GETTHIST:
+ case IDT77105_GETSTAT:
+ case IDT77105_GETSTATZ:
+ case IXJCTL_TONE_CADENCE:
+ case IXJCTL_FRAMES_READ:
+ case IXJCTL_FRAMES_WRITTEN:
+ case IXJCTL_READ_WAIT:
+ case IXJCTL_WRITE_WAIT:
+ case IXJCTL_DRYBUFFER_READ:
+ case I2OHRTGET:
+ case I2OLCTGET:
+ case I2OPARMSET:
+ case I2OPARMGET:
+ case I2OSWDL:
+ case I2OSWUL:
+ case I2OSWDEL:
+ case I2OHTML:
+ printk("%x:unimplemented IA32 ioctl system call\n", cmd);
+ return(-EINVAL);
+ default:
+ return(sys_ioctl(fd, cmd, (unsigned long)arg));
+
+ }
+}
diff --git a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
index 1e9876eb4..cbec84f2b 100644
--- a/arch/ia64/ia32/sys_ia32.c
+++ b/arch/ia64/ia32/sys_ia32.c
@@ -29,6 +29,7 @@
#include <linux/smp_lock.h>
#include <linux/sem.h>
#include <linux/msg.h>
+#include <linux/mm.h>
#include <linux/shm.h>
#include <linux/malloc.h>
#include <linux/uio.h>
@@ -207,7 +208,7 @@ sys32_newfstat(unsigned int fd, struct stat32 *statbuf)
unsigned long
do_mmap_fake(struct file *file, unsigned long addr, unsigned long len,
- unsigned long prot, unsigned long flags, unsigned long off)
+ unsigned long prot, unsigned long flags, loff_t off)
{
struct inode *inode;
void *front, *back;
@@ -224,11 +225,11 @@ do_mmap_fake(struct file *file, unsigned long addr, unsigned long len,
back = NULL;
if ((baddr = (addr & PAGE_MASK)) != addr && get_user(c, (char *)baddr) == 0) {
front = kmalloc(addr - baddr, GFP_KERNEL);
- memcpy(front, (void *)baddr, addr - baddr);
+ __copy_user(front, (void *)baddr, addr - baddr);
}
if (addr && ((addr + len) & ~PAGE_MASK) && get_user(c, (char *)(addr + len)) == 0) {
back = kmalloc(PAGE_SIZE - ((addr + len) & ~PAGE_MASK), GFP_KERNEL);
- memcpy(back, (char *)addr + len, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
+ __copy_user(back, (char *)addr + len, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
}
down(&current->mm->mmap_sem);
r = do_mmap(0, baddr, len + (addr - baddr), prot, flags | MAP_ANONYMOUS, 0);
@@ -238,15 +239,15 @@ do_mmap_fake(struct file *file, unsigned long addr, unsigned long len,
if (addr == 0)
addr = r;
if (back) {
- memcpy((char *)addr + len, back, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
+ __copy_user((char *)addr + len, back, PAGE_SIZE - ((addr + len) & ~PAGE_MASK));
kfree(back);
}
if (front) {
- memcpy((void *)baddr, front, addr - baddr);
+ __copy_user((void *)baddr, front, addr - baddr);
kfree(front);
}
if (flags & MAP_ANONYMOUS) {
- memset((char *)addr, 0, len);
+ clear_user((char *)addr, len);
return(addr);
}
if (!file)
@@ -256,19 +257,39 @@ do_mmap_fake(struct file *file, unsigned long addr, unsigned long len,
return -EINVAL;
if (!file->f_op->read)
return -EINVAL;
- lock_kernel();
- if (file->f_op->llseek) {
- if (file->f_op->llseek(file,off,0) != off) {
- unlock_kernel();
- return -EINVAL;
- }
- } else
- file->f_pos = off;
- unlock_kernel();
- r = file->f_op->read(file, (char *)addr, len, &file->f_pos);
+ r = file->f_op->read(file, (char *)addr, len, &off);
return (r < 0) ? -EINVAL : addr;
}
+long
+ia32_do_mmap (struct file *file, unsigned int addr, unsigned int len, unsigned int prot,
+ unsigned int flags, unsigned int fd, unsigned int offset)
+{
+ long error = -EFAULT;
+ unsigned int poff;
+
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+ if ((flags & MAP_FIXED) && ((addr & ~PAGE_MASK) || (offset & ~PAGE_MASK)))
+ error = do_mmap_fake(file, addr, len, prot, flags, (loff_t)offset);
+ else if (!addr && (offset & ~PAGE_MASK)) {
+ poff = offset & PAGE_MASK;
+ len += offset - poff;
+
+ down(&current->mm->mmap_sem);
+ error = do_mmap(file, addr, len, prot, flags, poff);
+ up(&current->mm->mmap_sem);
+
+ if (!IS_ERR(error))
+ error += offset - poff;
+ } else {
+ down(&current->mm->mmap_sem);
+ error = do_mmap(file, addr, len, prot, flags, offset);
+ up(&current->mm->mmap_sem);
+ }
+ return error;
+}
+
/*
* Linux/i386 didn't use to be able to handle more than
* 4 system call parameters, so these system calls used a memory
@@ -287,32 +308,22 @@ struct mmap_arg_struct {
asmlinkage long
sys32_mmap(struct mmap_arg_struct *arg)
{
- int error = -EFAULT;
- struct file * file = NULL;
struct mmap_arg_struct a;
+ struct file *file = NULL;
+ long retval;
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
if (!(a.flags & MAP_ANONYMOUS)) {
- error = -EBADF;
file = fget(a.fd);
if (!file)
- goto out;
- }
- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
-
- if ((a.flags & MAP_FIXED) && ((a.addr & ~PAGE_MASK) || (a.offset & ~PAGE_MASK))) {
- error = do_mmap_fake(file, a.addr, a.len, a.prot, a.flags, a.offset);
- } else {
- down(&current->mm->mmap_sem);
- error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
- up(&current->mm->mmap_sem);
+ return -EBADF;
}
+ retval = ia32_do_mmap(file, a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
if (file)
fput(file);
-out:
- return error;
+ return retval;
}
asmlinkage long
@@ -602,6 +613,40 @@ sys32_alarm(unsigned int seconds)
/* Translations due to time_t size differences. Which affects all
sorts of things, like timeval and itimerval. */
+struct utimbuf_32 {
+ int atime;
+ int mtime;
+};
+
+extern asmlinkage long sys_utimes(char * filename, struct timeval * utimes);
+extern asmlinkage long sys_gettimeofday (struct timeval *tv, struct timezone *tz);
+
+asmlinkage long
+ia32_utime(char * filename, struct utimbuf_32 *times32)
+{
+ mm_segment_t old_fs = get_fs();
+ struct timeval tv[2];
+ long ret;
+
+ if (times32) {
+ get_user(tv[0].tv_sec, &times32->atime);
+ tv[0].tv_usec = 0;
+ get_user(tv[1].tv_sec, &times32->mtime);
+ tv[1].tv_usec = 0;
+ set_fs (KERNEL_DS);
+ } else {
+ set_fs (KERNEL_DS);
+ ret = sys_gettimeofday(&tv[0], 0);
+ if (ret < 0)
+ goto out;
+ tv[1] = tv[0];
+ }
+ ret = sys_utimes(filename, tv);
+ out:
+ set_fs (old_fs);
+ return ret;
+}
+
extern struct timezone sys_tz;
extern int do_sys_settimeofday(struct timeval *tv, struct timezone *tz);
@@ -2359,7 +2404,7 @@ sys32_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
goto out;
}
ret = -ESRCH;
- if (!(child->flags & PF_PTRACED))
+ if (!(child->ptrace & PT_PTRACED))
goto out;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
index 3fb62560d..dfba2529a 100644
--- a/arch/ia64/kernel/Makefile
+++ b/arch/ia64/kernel/Makefile
@@ -9,35 +9,20 @@
all: kernel.o head.o init_task.o
-O_TARGET := kernel.o
-O_OBJS := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_sapic.o ivt.o \
- pal.o pci-dma.o process.o perfmon.o ptrace.o sal.o semaphore.o setup.o \
- signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o
-OX_OBJS := ia64_ksyms.o
-
-ifdef CONFIG_IA64_GENERIC
-O_OBJS += machvec.o
-endif
-
-ifdef CONFIG_IA64_PALINFO
-O_OBJS += palinfo.o
-endif
+obj-y := acpi.o entry.o gate.o efi.o efi_stub.o irq.o irq_ia64.o irq_sapic.o ivt.o \
+ pal.o pci-dma.o process.o perfmon.o ptrace.o sal.o semaphore.o setup.o \
+ signal.o sys_ia64.o traps.o time.o unaligned.o unwind.o
-ifdef CONFIG_PCI
-O_OBJS += pci.o
-endif
+obj-$(CONFIG_IA64_GENERIC) += machvec.o
+obj-$(CONFIG_IA64_PALINFO) += palinfo.o
+obj-$(CONFIG_PCI) += pci.o
+obj-$(CONFIG_SMP) += smp.o
+obj-$(CONFIG_IA64_MCA) += mca.o mca_asm.o
+obj-$(CONFIG_IA64_BRL_EMU) += brl_emu.o
-ifdef CONFIG_SMP
-O_OBJS += smp.o
-endif
-
-ifdef CONFIG_IA64_MCA
-O_OBJS += mca.o mca_asm.o
-endif
-
-ifdef CONFIG_IA64_BRL_EMU
-O_OBJS += brl_emu.o
-endif
+O_TARGET := kernel.o
+O_OBJS := $(obj-y)
+OX_OBJS := ia64_ksyms.o
clean::
diff --git a/arch/ia64/kernel/efi_stub.S b/arch/ia64/kernel/efi_stub.S
index 2bb45c790..1ee6ad05f 100644
--- a/arch/ia64/kernel/efi_stub.S
+++ b/arch/ia64/kernel/efi_stub.S
@@ -76,17 +76,14 @@ GLOBAL_ENTRY(efi_call_phys)
andcm r16=loc3,r16 // get psr with IT, DT, and RT bits cleared
mov out3=in4
br.call.sptk.few rp=ia64_switch_mode
-.ret0:
- mov out4=in5
+.ret0: mov out4=in5
mov out5=in6
mov out6=in7
br.call.sptk.few rp=b6 // call the EFI function
-.ret1:
- mov ar.rsc=r0 // put RSE in enforced lazy, LE mode
+.ret1: mov ar.rsc=r0 // put RSE in enforced lazy, LE mode
mov r16=loc3
br.call.sptk.few rp=ia64_switch_mode // return to virtual mode
-.ret2:
- mov ar.rsc=loc4 // restore RSE configuration
+.ret2: mov ar.rsc=loc4 // restore RSE configuration
mov ar.pfs=loc1
mov rp=loc0
mov gp=loc2
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index e56e3fc8e..3aadb43a0 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -17,8 +17,6 @@
* pSys: See entry.h.
* pNonSys: !pSys
* p2: (Alias of pKern!) True if any signals are pending.
- * p16/p17: Used by stubs calling ia64_do_signal to indicate if current task
- * has PF_PTRACED flag bit set. p16 is true if so, p17 is the complement.
*/
#include <linux/config.h>
@@ -62,27 +60,41 @@ ENTRY(ia64_execve)
br.ret.sptk.few rp
END(ia64_execve)
-GLOBAL_ENTRY(sys_clone)
+GLOBAL_ENTRY(sys_clone2)
UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2))
- alloc r16=ar.pfs,2,2,3,0;;
- mov loc0=rp
+ alloc r16=ar.pfs,3,2,4,0
DO_SAVE_SWITCH_STACK
+ mov loc0=rp
mov loc1=r16 // save ar.pfs across do_fork
UNW(.body)
- adds out2=IA64_SWITCH_STACK_SIZE+16,sp
- adds r2=IA64_SWITCH_STACK_SIZE+IA64_PT_REGS_R12_OFFSET+16,sp
- cmp.eq p8,p9=in1,r0 // usp == 0?
+ mov out1=in1
+ mov out2=in2
+ adds out3=IA64_SWITCH_STACK_SIZE+16,sp // out3 = &regs
mov out0=in0 // out0 = clone_flags
- ;;
-(p8) ld8 out1=[r2] // fetch usp from pt_regs.r12
-(p9) mov out1=in1
br.call.sptk.few rp=do_fork
-.ret1:
+.ret1: UNW(.restore sp)
+ adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
mov ar.pfs=loc1
- UNW(.restore sp)
+ mov rp=loc0
+ br.ret.sptk.many rp
+END(sys_clone2)
+
+GLOBAL_ENTRY(sys_clone)
+ UNW(.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(2))
+ alloc r16=ar.pfs,2,2,4,0
+ DO_SAVE_SWITCH_STACK
+ mov loc0=rp
+ mov loc1=r16 // save ar.pfs across do_fork
+ UNW(.body)
+ mov out1=in1
+ mov out2=0
+ adds out3=IA64_SWITCH_STACK_SIZE+16,sp // out3 = &regs
+ mov out0=in0 // out0 = clone_flags
+ br.call.sptk.few rp=do_fork
+.ret2: UNW(.restore sp)
adds sp=IA64_SWITCH_STACK_SIZE,sp // pop the switch stack
+ mov ar.pfs=loc1
mov rp=loc0
- ;;
br.ret.sptk.many rp
END(sys_clone)
@@ -387,9 +399,9 @@ GLOBAL_ENTRY(invoke_syscall_trace)
;; // WAW on CFM at the br.call
mov loc0=rp
br.call.sptk.many rp=save_switch_stack_with_current_frame // must preserve b6!!
-.ret2: mov loc2=b6
+.ret4: mov loc2=b6
br.call.sptk.few rp=syscall_trace
-.ret3: adds sp=IA64_SWITCH_STACK_SIZE,sp // drop switch_stack frame
+.ret5: adds sp=IA64_SWITCH_STACK_SIZE,sp // drop switch_stack frame
mov rp=loc0
mov ar.pfs=loc1
mov b6=loc2
@@ -408,26 +420,14 @@ END(invoke_syscall_trace)
// r15 = syscall number
// b6 = syscall entry point
//
- .global ia64_trace_syscall
.global ia64_strace_leave_kernel
-GLOBAL_ENTRY(ia64_strace_clear_r8)
- // this is where we return after cloning when PF_TRACESYS is on
- PT_REGS_UNWIND_INFO(0)
-# ifdef CONFIG_SMP
- br.call.sptk.few rp=invoke_schedule_tail
-# endif
- mov r8=0
- br strace_check_retval
-END(ia64_strace_clear_r8)
-
-ENTRY(ia64_trace_syscall)
+GLOBAL_ENTRY(ia64_trace_syscall)
PT_REGS_UNWIND_INFO(0)
br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch syscall args
-.ret4: br.call.sptk.few rp=b6 // do the syscall
+.ret6: br.call.sptk.few rp=b6 // do the syscall
strace_check_retval:
-.ret5: cmp.lt p6,p0=r8,r0 // syscall failed?
- ;;
+ cmp.lt p6,p0=r8,r0 // syscall failed?
adds r2=IA64_PT_REGS_R8_OFFSET+16,sp // r2 = &pt_regs.r8
adds r3=IA64_PT_REGS_R8_OFFSET+32,sp // r3 = &pt_regs.r10
mov r10=0
@@ -438,7 +438,7 @@ strace_save_retval:
.mem.offset 8,0; st8.spill [r3]=r10 // clear error indication in slot for r10
ia64_strace_leave_kernel:
br.call.sptk.few rp=invoke_syscall_trace // give parent a chance to catch return value
-.ret6: br.cond.sptk.many ia64_leave_kernel
+.rety: br.cond.sptk.many ia64_leave_kernel
strace_error:
ld8 r3=[r2] // load pt_regs.r8
@@ -468,18 +468,24 @@ END(ia64_trace_syscall)
#define rKRBS r22
#define rB6 r21
-GLOBAL_ENTRY(ia64_ret_from_syscall_clear_r8)
+GLOBAL_ENTRY(ia64_ret_from_clone)
PT_REGS_UNWIND_INFO(0)
#ifdef CONFIG_SMP
// In SMP mode, we need to call schedule_tail to complete the scheduling process.
// Called by ia64_switch_to after do_fork()->copy_thread(). r8 contains the
// address of the previously executing task.
br.call.sptk.few rp=invoke_schedule_tail
-.ret7:
-#endif
+.ret8:
+#endif
+ adds r2=IA64_TASK_PTRACE_OFFSET,r13
+ ;;
+ ld8 r2=[r2]
+ ;;
mov r8=0
+ tbit.nz p6,p0=r2,PT_TRACESYS_BIT
+(p6) br strace_check_retval
;; // added stop bits to prevent r8 dependency
-END(ia64_ret_from_syscall_clear_r8)
+END(ia64_ret_from_clone)
// fall through
GLOBAL_ENTRY(ia64_ret_from_syscall)
PT_REGS_UNWIND_INFO(0)
@@ -542,6 +548,7 @@ back_from_resched:
2:
// check & deliver pending signals:
(p2) br.call.spnt.few rp=handle_signal_delivery
+.ret9:
#if defined(CONFIG_ITANIUM_ASTEP_SPECIFIC) || defined(CONFIG_IA64_SOFTSDV_HACKS)
// Check for lost ticks
rsm psr.i
@@ -555,6 +562,7 @@ back_from_resched:
;;
cmp.ge p6,p7 = r2, r0
(p6) br.call.spnt.few rp=invoke_ia64_reset_itm
+.ret10:
;;
ssm psr.i
#endif
@@ -749,8 +757,7 @@ ENTRY(invoke_schedule_tail)
mov out0=r8 // Address of previous task
;;
br.call.sptk.few rp=schedule_tail
-.ret8:
- mov ar.pfs=loc1
+.ret11: mov ar.pfs=loc1
mov rp=loc0
br.ret.sptk.many rp
END(invoke_schedule_tail)
@@ -766,7 +773,7 @@ ENTRY(invoke_ia64_reset_itm)
;;
UNW(.body)
br.call.sptk.many rp=ia64_reset_itm
- ;;
+.ret12: ;;
mov ar.pfs=loc1
mov rp=loc0
br.ret.sptk.many rp
@@ -785,8 +792,7 @@ ENTRY(invoke_do_softirq)
;;
UNW(.body)
br.call.sptk.few rp=do_softirq
-.ret9:
- mov ar.pfs=loc1
+.ret13: mov ar.pfs=loc1
mov rp=loc0
br.ret.sptk.many rp
END(invoke_do_softirq)
@@ -802,8 +808,7 @@ ENTRY(invoke_schedule)
;;
UNW(.body)
br.call.sptk.few rp=schedule
-.ret10:
- mov ar.pfs=loc1
+.ret14: mov ar.pfs=loc1
mov rp=loc0
br.ret.sptk.many rp
END(invoke_schedule)
@@ -829,8 +834,7 @@ ENTRY(handle_signal_delivery)
st8 [sp]=r9,-16 // allocate space for ar.unat and save it
.body
br.call.sptk.few rp=ia64_do_signal
-.ret11:
- .restore sp
+.ret15: .restore sp
adds sp=16,sp // pop scratch stack space
;;
ld8 r9=[sp] // load new unat from sw->caller_unat
@@ -851,8 +855,7 @@ ENTRY(handle_signal_delivery)
(pSys) mov out2=1 // out2==1 => we're in a syscall
(pNonSys) mov out2=0 // out2==0 => not a syscall
br.call.sptk.few rp=ia64_do_signal
-.ret11:
- // restore the switch stack (ptrace may have modified it)
+.ret16: // restore the switch stack (ptrace may have modified it)
DO_LOAD_SWITCH_STACK( )
br.ret.sptk.many rp
#endif /* !CONFIG_IA64_NEW_UNWIND */
@@ -873,8 +876,7 @@ GLOBAL_ENTRY(sys_rt_sigsuspend)
st8 [sp]=r9,-16 // allocate space for ar.unat and save it
.body
br.call.sptk.few rp=ia64_rt_sigsuspend
-.ret12:
- .restore sp
+.ret17: .restore sp
adds sp=16,sp // pop scratch stack space
;;
ld8 r9=[sp] // load new unat from sw->caller_unat
@@ -893,8 +895,7 @@ GLOBAL_ENTRY(sys_rt_sigsuspend)
mov out1=in1 // sigsetsize
adds out2=16,sp // out1=&sigscratch
br.call.sptk.many rp=ia64_rt_sigsuspend
-.ret12:
- // restore the switch stack (ptrace may have modified it)
+.ret18: // restore the switch stack (ptrace may have modified it)
DO_LOAD_SWITCH_STACK( )
br.ret.sptk.many rp
#endif /* !CONFIG_IA64_NEW_UNWIND */
@@ -912,8 +913,7 @@ ENTRY(sys_rt_sigreturn)
;;
adds out0=16,sp // out0 = &sigscratch
br.call.sptk.few rp=ia64_rt_sigreturn
-.ret13:
- adds sp=16,sp // doesn't drop pt_regs, so don't mark it as restoring sp!
+.ret19: adds sp=16,sp // doesn't drop pt_regs, so don't mark it as restoring sp!
PT_REGS_UNWIND_INFO(0) // instead, create a new body section with the smaller frame
;;
ld8 r9=[sp] // load new ar.unat
@@ -937,8 +937,7 @@ ENTRY(sys_rt_sigreturn)
adds out0=16,sp // out0 = &sigscratch
br.call.sptk.few rp=ia64_rt_sigreturn
-.ret13:
- adds r3=IA64_SWITCH_STACK_CALLER_UNAT_OFFSET+16,sp
+.ret20: adds r3=IA64_SWITCH_STACK_CALLER_UNAT_OFFSET+16,sp
;;
ld8 r9=[r3] // load new ar.unat
mov b7=r8
@@ -957,9 +956,10 @@ GLOBAL_ENTRY(ia64_prepare_handle_unaligned)
//
PT_REGS_UNWIND_INFO(0)
mov r16=r0
+ UNW(.prologue)
DO_SAVE_SWITCH_STACK
br.call.sptk.few rp=ia64_handle_unaligned // stack frame setup in ivt
-.ret14:
+.ret21: .body
DO_LOAD_SWITCH_STACK(PT_REGS_UNWIND_INFO(0))
br.cond.sptk.many rp // goes to ia64_leave_kernel
END(ia64_prepare_handle_unaligned)
@@ -1206,7 +1206,7 @@ sys_call_table:
data8 sys_newstat // 1210
data8 sys_newlstat
data8 sys_newfstat
- data8 ia64_ni_syscall
+ data8 sys_clone2
data8 ia64_ni_syscall
data8 ia64_ni_syscall // 1215
data8 ia64_ni_syscall
diff --git a/arch/ia64/kernel/fw-emu.c b/arch/ia64/kernel/fw-emu.c
index 9e5ec1668..c34bbaeee 100644
--- a/arch/ia64/kernel/fw-emu.c
+++ b/arch/ia64/kernel/fw-emu.c
@@ -240,7 +240,7 @@ sal_emulator (long index, unsigned long in1, unsigned long in2,
if (index == SAL_FREQ_BASE) {
switch (in1) {
case SAL_FREQ_BASE_PLATFORM:
- r9 = 100000000;
+ r9 = 200000000;
break;
case SAL_FREQ_BASE_INTERVAL_TIMER:
diff --git a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
index f7f8d02ae..2b2a1c29e 100644
--- a/arch/ia64/kernel/gate.S
+++ b/arch/ia64/kernel/gate.S
@@ -120,8 +120,7 @@ back_from_setup_rbs:
stf.spill [base0]=f14,32
stf.spill [base1]=f15,32
br.call.sptk.few rp=b6 // call the signal handler
-.ret2:
- adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
+.ret0: adds base0=(BSP_OFF+SIGCONTEXT_OFF),sp
;;
ld8 r15=[base0],(CFM_OFF-BSP_OFF) // fetch sc_ar_bsp and advance to CFM_OFF
mov r14=ar.bsp
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
index d0bc7687f..b2abc48a4 100644
--- a/arch/ia64/kernel/head.S
+++ b/arch/ia64/kernel/head.S
@@ -139,7 +139,7 @@ alive_msg:
;;
#ifdef CONFIG_SMP
(isAP) br.call.sptk.few rp=smp_callin
-.ret1:
+.ret0:
(isAP) br.cond.sptk.few self
#endif
@@ -150,11 +150,10 @@ alive_msg:
#ifdef CONFIG_IA64_FW_EMU
// initialize PAL & SAL emulator:
br.call.sptk.few rp=sys_fw_init
- ;;
+.ret1:
#endif
br.call.sptk.few rp=start_kernel
-.ret2:
- addl r2=@ltoff(halt_msg),gp
+.ret2: addl r2=@ltoff(halt_msg),gp
;;
ld8 out0=[r2]
br.call.sptk.few b0=console_print
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index d58cd494e..9f611c5b0 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -170,10 +170,11 @@ ia64_ivt:
* The ITLB basically does the same as the VHPT handler except
* that we always insert exactly one instruction TLB entry.
*/
-#if 0
+#if 1
/*
- * This code works, but I don't want to enable it until I have numbers
- * that prove this to be a win.
+ * Attempt to lookup PTE through virtual linear page table.
+ * The speculative access will fail if there is no TLB entry
+ * for the L3 page table page we're trying to access.
*/
mov r31=pr // save predicates
;;
@@ -244,10 +245,11 @@ ia64_ivt:
* that we always insert exactly one data TLB entry.
*/
mov r16=cr.ifa // get address that caused the TLB miss
-#if 0
+#if 1
/*
- * This code works, but I don't want to enable it until I have numbers
- * that prove this to be a win.
+ * Attempt to lookup PTE through virtual linear page table.
+ * The speculative access will fail if there is no TLB entry
+ * for the L3 page table page we're trying to access.
*/
mov r31=pr // save predicates
;;
@@ -568,7 +570,7 @@ page_fault:
mov r3=255
adds r15=-1024,r15 // r15 contains the syscall number---subtract 1024
- adds r2=IA64_TASK_FLAGS_OFFSET,r13 // r2 = &current->flags
+ adds r2=IA64_TASK_PTRACE_OFFSET,r13 // r2 = &current->ptrace
;;
cmp.geu.unc p6,p7=r3,r15 // (syscall > 0 && syscall <= 1024+255) ?
@@ -581,7 +583,7 @@ page_fault:
ld8 r16=[r16] // load address of syscall entry point
mov rp=r15 // set the real return addr
;;
- ld8 r2=[r2] // r2 = current->flags
+ ld8 r2=[r2] // r2 = current->ptrace
mov b6=r16
// arrange things so we skip over break instruction when returning:
@@ -590,7 +592,7 @@ page_fault:
adds r17=24,sp // get pointer to cr_iip
;;
ld8 r18=[r16] // fetch cr_ipsr
- tbit.z p8,p0=r2,5 // (current->flags & PF_TRACESYS) == 0?
+ tbit.z p8,p0=r2,PT_TRACESYS_BIT // (current->ptrace & PF_TRACESYS) == 0?
;;
ld8 r19=[r17] // fetch cr_iip
extr.u r20=r18,41,2 // extract ei field
@@ -686,7 +688,7 @@ dispatch_illegal_op_fault:
SAVE_REST
;;
br.call.sptk.few rp=ia64_illegal_op_fault
- ;;
+.ret0: ;;
alloc r14=ar.pfs,0,0,3,0 // must be first in insn group
mov out0=r9
mov out1=r10
@@ -755,16 +757,16 @@ dispatch_to_ia32_handler:
ld4 out5=[r14],8 // r13 == ebp
;;
ld4 out3=[r14],8 // r14 == esi
- adds r2=IA64_TASK_FLAGS_OFFSET,r13 // r2 = &current->flags
+ adds r2=IA64_TASK_PTRACE_OFFSET,r13 // r2 = &current->ptrace
;;
ld4 out4=[r14] // R15 == edi
movl r16=ia32_syscall_table
;;
(p6) shladd r16=r8,3,r16 // Force ni_syscall if not valid syscall number
- ld8 r2=[r2] // r2 = current->flags
+ ld8 r2=[r2] // r2 = current->ptrace
;;
ld8 r16=[r16]
- tbit.z p8,p0=r2,5 // (current->flags & PF_TRACESYS) == 0?
+ tbit.z p8,p0=r2,PT_TRACESYS_BIT // (current->ptrace & PT_TRACESYS) == 0?
;;
mov b6=r16
movl r15=ia32_ret_from_syscall
@@ -780,8 +782,7 @@ non_ia32_syscall:
add out1=16,sp // pointer to pt_regs
;; // avoid WAW on CFM
br.call.sptk.few rp=ia32_bad_interrupt
- ;;
- movl r15=ia64_leave_kernel
+.ret1: movl r15=ia64_leave_kernel
;;
mov rp=r15
br.ret.sptk.many rp
diff --git a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
index 003b8dd69..b57d4702d 100644
--- a/arch/ia64/kernel/mca.c
+++ b/arch/ia64/kernel/mca.c
@@ -9,8 +9,7 @@
* Copyright (C) 1999 Silicon Graphics, Inc.
* Copyright (C) Vijay Chander(vijay@engr.sgi.com)
*
- * 00/03/29 C. Fleckenstein Fixed PAL/SAL update issues, began MCA bug fixes,
- * logging issues,
+ * 00/03/29 C. Fleckenstein Fixed PAL/SAL update issues, began MCA bug fixes, logging issues,
* added min save state dump, added INIT handler.
*/
#include <linux/config.h>
diff --git a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
index e4a9f0530..6b714108e 100644
--- a/arch/ia64/kernel/mca_asm.S
+++ b/arch/ia64/kernel/mca_asm.S
@@ -136,8 +136,7 @@ ia64_os_mca_virtual_begin:
movl r2=ia64_mca_ucmc_handler;;
mov b6=r2;;
br.call.sptk.few b0=b6
- ;;
-
+.ret0:
// Revert back to physical mode before going back to SAL
PHYSICAL_MODE_ENTER(r2, r3, ia64_os_mca_virtual_end, r4)
ia64_os_mca_virtual_end:
@@ -766,7 +765,7 @@ IVirtual_Switch:
;;
br.call.sptk.few rp=ia64_init_handler
- ;;
+.ret1:
return_from_init:
br.sptk return_from_init
diff --git a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S
index e6f44cfb6..147e2b8fe 100644
--- a/arch/ia64/kernel/pal.S
+++ b/arch/ia64/kernel/pal.S
@@ -74,14 +74,14 @@ GLOBAL_ENTRY(ia64_pal_call_static)
mov loc3 = psr
mov loc0 = rp
UNW(.body)
- adds r8 = .ret0-1b,r8
+ adds r8 = 1f-1b,r8
;;
rsm psr.i
mov b7 = loc2
mov rp = r8
;;
br.cond.sptk.few b7
-.ret0: mov psr.l = loc3
+1: mov psr.l = loc3
mov ar.pfs = loc1
mov rp = loc0
;;
@@ -116,8 +116,7 @@ GLOBAL_ENTRY(ia64_pal_call_stacked)
mov b7 = loc2
;;
br.call.sptk.many rp=b7 // now make the call
-.ret2:
- mov psr.l = loc3
+.ret0: mov psr.l = loc3
mov ar.pfs = loc1
mov rp = loc0
;;
@@ -161,7 +160,7 @@ GLOBAL_ENTRY(ia64_pal_call_phys_static)
mov r31 = in3 // copy arg3
;;
mov loc3 = psr // save psr
- adds r8 = .ret4-1b,r8 // calculate return address for call
+ adds r8 = 1f-1b,r8 // calculate return address for call
;;
mov loc4=ar.rsc // save RSE configuration
dep.z loc2=loc2,0,61 // convert pal entry point to physical
@@ -176,15 +175,14 @@ GLOBAL_ENTRY(ia64_pal_call_phys_static)
;;
andcm r16=loc3,r16 // removes bits to clear from psr
br.call.sptk.few rp=ia64_switch_mode
-.ret3:
- mov rp = r8 // install return address (physical)
+.ret1: mov rp = r8 // install return address (physical)
br.cond.sptk.few b7
-.ret4:
+1:
mov ar.rsc=r0 // put RSE in enforced lazy, LE mode
mov r16=loc3 // r16= original psr
br.call.sptk.few rp=ia64_switch_mode // return to virtual mode
-
-.ret5: mov psr.l = loc3 // restore init PSR
+.ret2:
+ mov psr.l = loc3 // restore init PSR
mov ar.pfs = loc1
mov rp = loc0
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
index 30bfcf101..3759e52f8 100644
--- a/arch/ia64/kernel/process.c
+++ b/arch/ia64/kernel/process.c
@@ -1,8 +1,8 @@
/*
* Architecture-specific setup.
*
- * Copyright (C) 1998, 1999 Hewlett-Packard Co
- * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1998-2000 Hewlett-Packard Co
+ * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
*/
#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */
#include <linux/config.h>
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/sched.h>
+#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
@@ -204,24 +205,22 @@ ia64_load_extra (struct task_struct *task)
* be copied as well.
*
* Observe that we copy the unat values that are in pt_regs and
- * switch_stack. Since the interpretation of unat is dependent upon
- * the address to which the registers got spilled, doing this is valid
- * only as long as we preserve the alignment of the stack. Since the
- * stack is always page aligned, we know this is the case.
- *
- * XXX Actually, the above isn't true when we create kernel_threads().
- * If we ever needs to create kernel_threads() that preserve the unat
- * values we'll need to fix this. Perhaps an easy workaround would be
- * to always clear the unat bits in the child thread.
+ * switch_stack. Spilling an integer to address X causes bit N in
+ * ar.unat to be set to the NaT bit of the register, with N=(X &
+ * 0x1ff)/8. Thus, copying the unat value preserves the NaT bits ONLY
+ * if the pt_regs structure in the parent is congruent to that of the
+ * child, modulo 512. Since the stack is page aligned and the page
+ * size is at least 4KB, this is always the case, so there is nothing
+ * to worry about.
*/
int
-copy_thread (int nr, unsigned long clone_flags, unsigned long usp,
+copy_thread (int nr, unsigned long clone_flags,
+ unsigned long user_stack_base, unsigned long user_stack_size,
struct task_struct *p, struct pt_regs *regs)
{
unsigned long rbs, child_rbs, rbs_size, stack_offset, stack_top, stack_used;
struct switch_stack *child_stack, *stack;
- extern char ia64_ret_from_syscall_clear_r8;
- extern char ia64_strace_clear_r8;
+ extern char ia64_ret_from_clone;
struct pt_regs *child_ptregs;
#ifdef CONFIG_SMP
@@ -251,10 +250,14 @@ copy_thread (int nr, unsigned long clone_flags, unsigned long usp,
/* copy the parent's register backing store to the child: */
memcpy((void *) child_rbs, (void *) rbs, rbs_size);
- child_ptregs->r8 = 0; /* child gets a zero return value */
- if (user_mode(child_ptregs))
- child_ptregs->r12 = usp; /* user stack pointer */
- else {
+ if (user_mode(child_ptregs)) {
+ if (user_stack_base) {
+ child_ptregs->r12 = user_stack_base + user_stack_size;
+ child_ptregs->ar_bspstore = user_stack_base;
+ child_ptregs->ar_rnat = 0;
+ child_ptregs->loadrs = 0;
+ }
+ } else {
/*
* Note: we simply preserve the relative position of
* the stack pointer here. There is no need to
@@ -265,13 +268,10 @@ copy_thread (int nr, unsigned long clone_flags, unsigned long usp,
child_ptregs->r12 = (unsigned long) (child_ptregs + 1); /* kernel sp */
child_ptregs->r13 = (unsigned long) p; /* set `current' pointer */
}
- if (p->flags & PF_TRACESYS)
- child_stack->b0 = (unsigned long) &ia64_strace_clear_r8;
- else
- child_stack->b0 = (unsigned long) &ia64_ret_from_syscall_clear_r8;
+ child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
child_stack->ar_bspstore = child_rbs + rbs_size;
- /* copy the thread_struct: */
+ /* copy parts of thread_struct: */
p->thread.ksp = (unsigned long) child_stack - 16;
/*
* NOTE: The calling convention considers all floating point
@@ -288,18 +288,11 @@ copy_thread (int nr, unsigned long clone_flags, unsigned long usp,
* would be a slight deviation from the normal Linux system
* call behavior where scratch registers are preserved across
* system calls (unless used by the system call itself).
- *
- * If we wanted to inherit the fph state from the parent to the
- * child, we would have to do something along the lines of:
- *
- * if (ia64_get_fpu_owner() == current && ia64_psr(regs)->mfh) {
- * p->thread.flags |= IA64_THREAD_FPH_VALID;
- * ia64_save_fpu(&p->thread.fph);
- * } else if (current->thread.flags & IA64_THREAD_FPH_VALID) {
- * memcpy(p->thread.fph, current->thread.fph, sizeof(p->thread.fph));
- * }
*/
- p->thread.flags = (current->thread.flags & ~IA64_THREAD_FPH_VALID);
+# define THREAD_FLAGS_TO_CLEAR (IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID)
+# define THREAD_FLAGS_TO_SET 0
+ p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR)
+ | THREAD_FLAGS_TO_SET);
return 0;
}
diff --git a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
index 0efd42bb8..ae8991c51 100644
--- a/arch/ia64/kernel/ptrace.c
+++ b/arch/ia64/kernel/ptrace.c
@@ -942,9 +942,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
ret = -EPERM;
if (request == PTRACE_TRACEME) {
/* are we already being traced? */
- if (current->flags & PF_PTRACED)
+ if (current->ptrace & PT_PTRACED)
goto out;
- current->flags |= PF_PTRACED;
+ current->ptrace |= PT_PTRACED;
ret = 0;
goto out;
}
@@ -976,9 +976,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
(current->gid != child->gid)) && !capable(CAP_SYS_PTRACE))
goto out_tsk;
/* the same process cannot be attached many times */
- if (child->flags & PF_PTRACED)
+ if (child->ptrace & PT_PTRACED)
goto out_tsk;
- child->flags |= PF_PTRACED;
+ child->ptrace |= PT_PTRACED;
if (child->p_pptr != current) {
unsigned long flags;
@@ -993,7 +993,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
goto out_tsk;
}
ret = -ESRCH;
- if (!(child->flags & PF_PTRACED))
+ if (!(child->ptrace & PT_PTRACED))
goto out_tsk;
if (child->state != TASK_STOPPED) {
if (request != PTRACE_KILL)
@@ -1083,9 +1083,9 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
if (data > _NSIG)
goto out_tsk;
if (request == PTRACE_SYSCALL)
- child->flags |= PF_TRACESYS;
+ child->ptrace |= PT_TRACESYS;
else
- child->flags &= ~PF_TRACESYS;
+ child->ptrace &= ~PT_TRACESYS;
child->exit_code = data;
/* make sure the single step/take-branch tra bits are not set: */
@@ -1126,7 +1126,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
if (data > _NSIG)
goto out_tsk;
- child->flags &= ~PF_TRACESYS;
+ child->ptrace &= ~PT_TRACESYS;
if (request == PTRACE_SINGLESTEP) {
ia64_psr(ia64_task_regs(child))->ss = 1;
} else {
@@ -1147,7 +1147,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
if (data > _NSIG)
goto out_tsk;
- child->flags &= ~(PF_PTRACED|PF_TRACESYS);
+ child->ptrace &= ~(PT_PTRACED|PT_TRACESYS);
child->exit_code = data;
write_lock_irqsave(&tasklist_lock, flags);
REMOVE_LINKS(child);
@@ -1180,7 +1180,7 @@ sys_ptrace (long request, pid_t pid, unsigned long addr, unsigned long data,
void
syscall_trace (void)
{
- if ((current->flags & (PF_PTRACED|PF_TRACESYS)) != (PF_PTRACED|PF_TRACESYS))
+ if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) != (PT_PTRACED|PT_TRACESYS))
return;
current->exit_code = SIGTRAP;
set_current_state(TASK_STOPPED);
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 09850fdd8..fcb4e6190 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -241,18 +241,18 @@ get_cpuinfo (char *buffer)
sprintf(cp, " 0x%lx", mask);
p += sprintf(p,
- "CPU# %lu\n"
- "\tvendor : %s\n"
- "\tfamily : %s\n"
- "\tmodel : %s\n"
- "\trevision : %u\n"
- "\tarchrev : %u\n"
- "\tfeatures :%s\n" /* don't change this---it _is_ right! */
- "\tcpu number : %lu\n"
- "\tcpu regs : %u\n"
- "\tcpu MHz : %lu.%06lu\n"
- "\titc MHz : %lu.%06lu\n"
- "\tBogoMIPS : %lu.%02lu\n\n",
+ "processor : %lu\n"
+ "vendor : %s\n"
+ "family : %s\n"
+ "model : %s\n"
+ "revision : %u\n"
+ "archrev : %u\n"
+ "features :%s\n" /* don't change this---it _is_ right! */
+ "cpu number : %lu\n"
+ "cpu regs : %u\n"
+ "cpu MHz : %lu.%06lu\n"
+ "itc MHz : %lu.%06lu\n"
+ "BogoMIPS : %lu.%02lu\n\n",
c - cpu_data, c->vendor, family, model, c->revision, c->archrev,
features,
c->ppn, c->number, c->proc_freq / 1000000, c->proc_freq % 1000000,
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index 8a46377c9..ca0f7a981 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -218,7 +218,7 @@ ia64_rt_sigreturn (struct sigscratch *scr)
* be corrupted.
*/
retval = (long) &ia64_leave_kernel;
- if (current->flags & PF_TRACESYS)
+ if (current->ptrace & PT_TRACESYS)
/*
* strace expects to be notified after sigreturn
* returns even though the context to which we return
@@ -492,7 +492,7 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
if (!signr)
break;
- if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+ if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
/* Let the debugger run. */
current->exit_code = signr;
current->thread.siginfo = &info;
@@ -570,7 +570,6 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
/* FALLTHRU */
default:
- lock_kernel();
sigaddset(&current->signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c
index f6ae656e4..cee60fa97 100644
--- a/arch/ia64/kernel/smp.c
+++ b/arch/ia64/kernel/smp.c
@@ -183,7 +183,7 @@ handle_IPI(int irq, void *dev_id, struct pt_regs *regs)
int wait;
/* release the 'pointer lock' */
- data = smp_call_function_data;
+ data = (struct smp_call_struct *) smp_call_function_data;
func = data->func;
info = data->info;
wait = data->wait;
@@ -536,7 +536,7 @@ fork_by_hand(void)
* Don't care about the usp and regs settings since we'll never
* reschedule the forked task.
*/
- return do_fork(CLONE_VM|CLONE_PID, 0, 0);
+ return do_fork(CLONE_VM|CLONE_PID, 0, 0, 0);
}
/*
diff --git a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
index 0ccbe24a6..a3e5242fc 100644
--- a/arch/ia64/kernel/sys_ia64.c
+++ b/arch/ia64/kernel/sys_ia64.c
@@ -95,7 +95,6 @@ sys_pipe (long arg0, long arg1, long arg2, long arg3,
static inline unsigned long
do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, unsigned long pgoff)
{
- long start_low, end_low, starting_region, ending_region;
unsigned long loff, hoff;
struct file *file = 0;
/* the virtual address space that is mappable in each region: */
@@ -109,17 +108,15 @@ do_mmap2 (unsigned long addr, unsigned long len, int prot, int flags, int fd, un
return addr;
/* Don't permit mappings into or across the address hole in a region: */
- loff = REGION_OFFSET(addr);
- hoff = loff - (REGION_SIZE - OCTANT_SIZE/2);
+ loff = rgn_offset(addr);
+ hoff = loff - (RGN_SIZE - OCTANT_SIZE/2);
if ((len | loff | (loff + len)) >= OCTANT_SIZE/2
&& (len | hoff | (hoff + len)) >= OCTANT_SIZE/2)
return -EINVAL;
/* Don't permit mappings that would cross a region boundary: */
- starting_region = REGION_NUMBER(addr);
- ending_region = REGION_NUMBER(addr + len);
- if (starting_region != ending_region)
+ if (rgn_index(addr) != rgn_index(addr + len))
return -EINVAL;
flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
index d14ba0031..95b2b3fc3 100644
--- a/arch/ia64/kernel/time.c
+++ b/arch/ia64/kernel/time.c
@@ -24,7 +24,7 @@
#include <asm/system.h>
extern rwlock_t xtime_lock;
-extern volatile unsigned long lost_ticks;
+extern unsigned long wall_jiffies;
#ifdef CONFIG_IA64_DEBUG_IRQ
@@ -80,7 +80,7 @@ gettimeoffset (void)
return 0;
#else
unsigned long now = ia64_get_itc(), last_tick;
- unsigned long elapsed_cycles, lost = lost_ticks;
+ unsigned long elapsed_cycles, lost = jiffies - wall_jiffies;
last_tick = (itm.next[smp_processor_id()].count - (lost+1)*itm.delta);
# if 1
@@ -101,13 +101,15 @@ do_settimeofday (struct timeval *tv)
write_lock_irq(&xtime_lock);
{
/*
- * This is revolting. We need to set the xtime.tv_usec
+ * This is revolting. We need to set "xtime"
* correctly. However, the value in this location is
- * is value at the last tick. Discover what
- * correction gettimeofday would have done, and then
- * undo it!
+ * the value at the most recent update of wall time.
+ * Discover what correction gettimeofday would have
+ * done, and then undo it!
*/
tv->tv_usec -= gettimeoffset();
+ tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
+
while (tv->tv_usec < 0) {
tv->tv_usec += 1000000;
tv->tv_sec--;
diff --git a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
index a95b78f64..7ca1146a0 100644
--- a/arch/ia64/kernel/unaligned.c
+++ b/arch/ia64/kernel/unaligned.c
@@ -1428,9 +1428,15 @@ ia64_handle_unaligned(unsigned long ifa, struct pt_regs *regs)
if (unalign_count > 5 && jiffies - last_time > 5*HZ)
unalign_count = 0;
if (++unalign_count < 5) {
+ char buf[200]; /* comm[] is at most 16 bytes... */
+ size_t len;
+
last_time = jiffies;
- printk("%s(%d): unaligned trap accessing %016lx (ip=%016lx)\n",
- current->comm, current->pid, ifa, regs->cr_iip + ipsr->ri);
+ len = sprintf(buf, "%s(%d): unaligned access to 0x%016lx, ip=0x%016lx\n\r",
+ current->comm, current->pid, ifa, regs->cr_iip + ipsr->ri);
+ tty_write_message(current->tty, buf);
+ buf[len-1] = '\0'; /* drop '\r' */
+ printk("%s", buf); /* guard against command names containing %s!! */
}
}
diff --git a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c
index 7f3c203ad..739007a96 100644
--- a/arch/ia64/kernel/unwind.c
+++ b/arch/ia64/kernel/unwind.c
@@ -66,9 +66,12 @@
#define UNW_STATS 0 /* WARNING: this disabled interrupts for long time-spans!! */
#if UNW_DEBUG
+ static long unw_debug_level = 1;
+# define debug(level,format...) if (unw_debug_level > level) printk(format)
# define dprintk(format...) printk(format)
# define inline
#else
+# define debug(level,format...)
# define dprintk(format...)
#endif
@@ -1600,11 +1603,10 @@ find_save_locs (struct unw_frame_info *info)
int have_write_lock = 0;
struct unw_script *scr;
- if ((info->ip & (my_cpu_data.unimpl_va_mask | 0xf))
- || REGION_NUMBER(info->ip) != REGION_KERNEL)
+ if ((info->ip & (my_cpu_data.unimpl_va_mask | 0xf)) || rgn_index(info->ip) != RGN_KERNEL)
{
/* don't let obviously bad addresses pollute the cache */
- dprintk("unwind: rejecting bad ip=0x%lx\n", info->ip);
+ debug(1, "unwind: rejecting bad ip=0x%lx\n", info->ip);
info->rp = 0;
return -1;
}
@@ -1647,7 +1649,7 @@ unw_unwind (struct unw_frame_info *info)
/* restore the ip */
if (!info->rp) {
- dprintk("unwind: failed to locate return link (ip=0x%lx)!\n", info->ip);
+ debug(1, "unwind: failed to locate return link (ip=0x%lx)!\n", info->ip);
STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
return -1;
}
@@ -1657,7 +1659,7 @@ unw_unwind (struct unw_frame_info *info)
* We don't have unwind info for the gate page, so we consider that part
* of user-space for the purpose of unwinding.
*/
- dprintk("unwind: reached user-space (ip=0x%lx)\n", ip);
+ debug(1, "unwind: reached user-space (ip=0x%lx)\n", ip);
STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
return -1;
}
diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile
index 882bdaed9..318e314cc 100644
--- a/arch/ia64/lib/Makefile
+++ b/arch/ia64/lib/Makefile
@@ -7,40 +7,26 @@
L_TARGET = lib.a
-L_OBJS = __divdi3.o __divsi3.o __udivdi3.o __udivsi3.o \
- __moddi3.o __modsi3.o __umoddi3.o __umodsi3.o \
- checksum.o clear_page.o csum_partial_copy.o copy_page.o \
- copy_user.o clear_user.o memset.o strncpy_from_user.o \
- strlen.o strlen_user.o strnlen_user.o \
+L_OBJS = __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o \
+ checksum.o clear_page.o csum_partial_copy.o copy_page.o \
+ copy_user.o clear_user.o memcpy.o memset.o strncpy_from_user.o \
+ strlen.o strlen_user.o strnlen_user.o \
flush.o do_csum.o
LX_OBJS = io.o
-IGNORE_FLAGS_OBJS = __divdi3.o __divsi3.o __udivdi3.o __udivsi3.o \
- __moddi3.o __modsi3.o __umoddi3.o __umodsi3.o
+IGNORE_FLAGS_OBJS = __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o
include $(TOPDIR)/Rules.make
__divdi3.o: idiv.S
$(CC) $(AFLAGS) -c -o $@ $<
-__divsi3.o: idiv.S
- $(CC) $(AFLAGS) -c -DSINGLE -c -o $@ $<
-
__udivdi3.o: idiv.S
$(CC) $(AFLAGS) -c -DUNSIGNED -c -o $@ $<
-__udivsi3.o: idiv.S
- $(CC) $(AFLAGS) -c -DUNSIGNED -DSINGLE -c -o $@ $<
-
__moddi3.o: idiv.S
$(CC) $(AFLAGS) -c -DMODULO -c -o $@ $<
-__modsi3.o: idiv.S
- $(CC) $(AFLAGS) -c -DMODULO -DSINGLE -c -o $@ $<
-
__umoddi3.o: idiv.S
$(CC) $(AFLAGS) -c -DMODULO -DUNSIGNED -c -o $@ $<
-
-__umodsi3.o: idiv.S
- $(CC) $(AFLAGS) -c -DMODULO -DUNSIGNED -DSINGLE -c -o $@ $<
diff --git a/arch/ia64/lib/copy_user.S b/arch/ia64/lib/copy_user.S
index 4a0abaed0..e13febb22 100644
--- a/arch/ia64/lib/copy_user.S
+++ b/arch/ia64/lib/copy_user.S
@@ -116,7 +116,7 @@ GLOBAL_ENTRY(__copy_user)
cmp.lt p10,p7=COPY_BREAK,len // if len > COPY_BREAK then long copy
xor tmp=src,dst // same alignment test prepare
-(p10) br.cond.dptk.few long_memcpy
+(p10) br.cond.dptk.few long_copy_user
;; // RAW pr.rot/p16 ?
//
// Now we do the byte by byte loop with software pipeline
@@ -136,7 +136,7 @@ GLOBAL_ENTRY(__copy_user)
//
// Beginning of long mempcy (i.e. > 16 bytes)
//
-long_memcpy:
+long_copy_user:
tbit.nz p6,p7=src1,0 // odd alignement
and tmp=7,tmp
;;
diff --git a/arch/ia64/lib/idiv.S b/arch/ia64/lib/idiv.S
index af424c41b..da96863d3 100644
--- a/arch/ia64/lib/idiv.S
+++ b/arch/ia64/lib/idiv.S
@@ -1,162 +1,98 @@
/*
* Integer division routine.
*
- * Copyright (C) 1999 Hewlett-Packard Co
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999-2000 Hewlett-Packard Co
+ * Copyright (C) 1999-2000 David Mosberger-Tang <davidm@hpl.hp.com>
*/
-/* Simple integer division. It uses the straight forward division
- algorithm. This may not be the absolutely fastest way to do it,
- but it's not horrible either. According to ski, the worst case
- scenario of dividing 0xffffffffffffffff by 1 takes 133 cycles.
-
- An alternative would be to use an algorithm similar to the
- floating point division algorithm (Newton-Raphson iteration),
- but that approach is rather tricky (one has to be very careful
- to get the last bit right...).
-
- While this algorithm is straight-forward, it does use a couple
- of neat ia-64 specific tricks:
-
- - it uses the floating point unit to determine the initial
- shift amount (shift = floor(ld(x)) - floor(ld(y)))
-
- - it uses predication to avoid a branch in the case where
- x < y (this is what p8 is used for)
-
- - it uses rotating registers and the br.ctop branch to
- implement a software-pipelined loop that's unrolled
- twice (without any code expansion!)
-
- - the code is relatively well scheduled to avoid unnecessary
- nops while maximizing parallelism
-*/
#include <asm/asmmacro.h>
-#include <asm/break.h>
- .text
- .psr abi64
-#ifdef __BIG_ENDIAN__
- .psr msb
- .msb
-#else
- .psr lsb
- .lsb
-#endif
+/*
+ * Compute a 64-bit unsigned integer quotient.
+ *
+ * Use reciprocal approximation and Newton-Raphson iteration to compute the
+ * quotient. frcpa gives 8.6 significant bits, so we need 3 iterations
+ * to get more than the 64 bits of precision that we need for DImode.
+ *
+ * Must use max precision for the reciprocal computations to get 64 bits of
+ * precision.
+ *
+ * r32 holds the dividend. r33 holds the divisor.
+ */
#ifdef MODULO
# define OP mod
-# define Q r9
-# define R r8
#else
-# define OP div
-# define Q r8
-# define R r9
-#endif
-
-#ifdef SINGLE
-# define PREC si
-#else
-# define PREC di
+# define OP div
#endif
#ifdef UNSIGNED
-# define SGN u
-# define INT_TO_FP(a,b) fma.s0 a=b,f1,f0
-# define FP_TO_INT(a,b) fcvt.fxu.trunc.s0 a=b
+# define SGN u
+# define INT_TO_FP(a,b) fcvt.xuf.s1 a=b
+# define FP_TO_INT(a,b) fcvt.fxu.trunc.s1 a=b
#else
# define SGN
# define INT_TO_FP(a,b) fcvt.xf a=b
-# define FP_TO_INT(a,b) fcvt.fx.trunc.s0 a=b
+# define FP_TO_INT(a,b) fcvt.fx.trunc.s1 a=b
#endif
#define PASTE1(a,b) a##b
#define PASTE(a,b) PASTE1(a,b)
-#define NAME PASTE(PASTE(__,SGN),PASTE(OP,PASTE(PREC,3)))
+#define NAME PASTE(PASTE(__,SGN),PASTE(OP,di3))
GLOBAL_ENTRY(NAME)
UNW(.prologue)
- alloc r2=ar.pfs,2,6,0,8
- UNW(.save pr, r18)
- mov r18=pr
-#ifdef SINGLE
-# ifdef UNSIGNED
- zxt4 in0=in0
- zxt4 in1=in1
-# else
- sxt4 in0=in0
- sxt4 in1=in1
-# endif
- ;;
-#endif
-
-#ifndef UNSIGNED
- cmp.lt p6,p0=in0,r0 // x negative?
- cmp.lt p7,p0=in1,r0 // y negative?
+ .regstk 2,0,0,0
+ // Transfer inputs to FP registers.
+ setf.sig f8 = in0
+ setf.sig f9 = in1
+ UNW(.fframe 16)
+ UNW(.save.f 0x20)
+ stf.spill [sp] = f17,-16
+
+ // Convert the inputs to FP, to avoid FP software-assist faults.
+ INT_TO_FP(f8, f8)
;;
-(p6) sub in0=r0,in0 // make x positive
-(p7) sub in1=r0,in1 // ditto for y
- ;;
-#endif
-
- setf.sig f8=in0
- UNW(.save ar.lc, r3)
+ UNW(.save.f 0x10)
+ stf.spill [sp] = f16
UNW(.body)
-
- mov r3=ar.lc // save ar.lc
- setf.sig f9=in1
+ INT_TO_FP(f9, f9)
;;
- mov Q=0 // initialize q
- mov R=in0 // stash away x in a static register
- mov r16=1 // r16 = 1
- INT_TO_FP(f8,f8)
- cmp.eq p8,p0=0,in0 // x==0?
- cmp.eq p9,p0=0,in1 // y==0?
+ frcpa.s1 f17, p6 = f8, f9 // y = frcpa(b)
;;
- INT_TO_FP(f9,f9)
-(p8) br.dpnt.few .L3
-(p9) break __IA64_BREAK_KDB // attempted division by zero (should never happen)
- mov ar.ec=r0 // epilogue count = 0
+ /*
+ * This is the magic algorithm described in Section 8.6.2 of "IA-64
+ * and Elementary Functions" by Peter Markstein; HP Professional Books
+ * (http://www.hp.com/go/retailbooks/)
+ */
+(p6) fmpy.s1 f7 = f8, f17 // q = a*y
+(p6) fnma.s1 f6 = f9, f17, f1 // e = -b*y + 1
;;
- getf.exp r14=f8 // r14 = exponent of x
- getf.exp r15=f9 // r15 = exponent of y
- mov ar.lc=r0 // loop count = 0
+(p6) fma.s1 f16 = f7, f6, f7 // q1 = q*e + q
+(p6) fmpy.s1 f7 = f6, f6 // e1 = e*e
;;
- sub r17=r14,r15 // r17 = (exp of x - exp y) = shift amount
- cmp.ge p8,p0=r14,r15
+(p6) fma.s1 f16 = f16, f7, f16 // q2 = q1*e1 + q1
+(p6) fma.s1 f6 = f17, f6, f17 // y1 = y*e + y
;;
-
- .rotr y[2], mask[2] // in0 and in1 may no longer be valid after
- // the first write to a rotating register!
-
-(p8) shl y[1]=in1,r17 // y[1] = y<<shift
-(p8) shl mask[1]=r16,r17 // mask[1] = 1<<shift
-
-(p8) mov ar.lc=r17 // loop count = r17
+(p6) fma.s1 f6 = f6, f7, f6 // y2 = y1*e1 + y1
+(p6) fnma.s1 f7 = f9, f16, f8 // r = -b*q2 + a
;;
-.L1:
-(p8) cmp.geu.unc p9,p0=R,y[1]// p9 = (x >= y[1])
-(p8) shr.u mask[0]=mask[1],1 // prepare mask[0] and y[0] for next
-(p8) shr.u y[0]=y[1],1 // iteration
+(p6) fma.s1 f17 = f7, f6, f16 // q3 = r*y2 + q2
;;
-(p9) sub R=R,y[1] // if (x >= y[1]), subtract y[1] from x
-(p9) add Q=Q,mask[1] // and set corresponding bit in q (Q)
- br.ctop.dptk.few .L1 // repeated unless ar.lc-- == 0
+#ifdef MODULO
+ FP_TO_INT(f17, f17) // round quotient to an unsigned integer
+ ;;
+ INT_TO_FP(f17, f17) // renormalize
;;
-.L2:
-#ifndef UNSIGNED
-# ifdef MODULO
-(p6) sub R=r0,R // set sign of remainder according to x
-# else
-(p6) sub Q=r0,Q // set sign of quotient
+ fnma.s1 f17 = f17, f9, f8 // compute remainder
;;
-(p7) sub Q=r0,Q
-# endif
#endif
-.L3:
- mov ar.pfs=r2 // restore ar.pfs
- mov ar.lc=r3 // restore ar.lc
- mov pr=r18,0xffffffffffff0000 // restore p16-p63
- br.ret.sptk.few rp
+ UNW(.restore sp)
+ ldf.fill f16 = [sp], 16
+ FP_TO_INT(f8, f17) // round result to an (unsigned) integer
+ ;;
+ ldf.fill f17 = [sp]
+ getf.sig r8 = f8 // transfer result to result register
+ br.ret.sptk rp
END(NAME)
diff --git a/arch/ia64/lib/memcpy.S b/arch/ia64/lib/memcpy.S
new file mode 100644
index 000000000..3b16916d0
--- /dev/null
+++ b/arch/ia64/lib/memcpy.S
@@ -0,0 +1,86 @@
+#include <asm/asmmacro.h>
+
+GLOBAL_ENTRY(bcopy)
+ .regstk 3,0,0,0
+ mov r8=in0
+ mov in0=in1
+ ;;
+ mov in1=r8
+END(bcopy)
+ // FALL THROUGH
+GLOBAL_ENTRY(memcpy)
+
+# define MEM_LAT 4
+
+# define N MEM_LAT-1
+# define Nrot ((MEM_LAT + 7) & ~7)
+
+# define dst r2
+# define src r3
+# define len r9
+# define saved_pfs r10
+# define saved_lc r11
+# define saved_pr r16
+# define t0 r17
+# define cnt r18
+
+ UNW(.prologue)
+ UNW(.save ar.pfs, saved_pfs)
+ alloc saved_pfs=ar.pfs,3,Nrot,0,Nrot
+ lfetch [in1]
+
+ .rotr val[MEM_LAT]
+ .rotp p[MEM_LAT]
+
+ UNW(.save ar.lc, saved_lc)
+ mov saved_lc=ar.lc
+
+ or t0=in0,in1
+ UNW(.save pr, saved_pr)
+ mov saved_pr=pr
+
+ UNW(.body)
+
+ mov ar.ec=MEM_LAT
+
+ mov r8=in0 // return dst
+ shr cnt=in2,3 // number of 8-byte words to copy
+ mov pr.rot=1<<16
+ ;;
+ cmp.eq p6,p0=in2,r0 // zero length?
+ or t0=t0,in2
+(p6) br.ret.spnt.many rp // yes, return immediately
+
+ mov dst=in0 // copy because of rotation
+ mov src=in1 // copy because of rotation
+ adds cnt=-1,cnt // br.ctop is repeat/until
+ ;;
+ and t0=0x7,t0
+ mov ar.lc=cnt
+ ;;
+ cmp.ne p6,p0=t0,r0
+(p6) br.cond.spnt.few slow_memcpy
+
+1:
+(p[0]) ld8 val[0]=[src],8
+(p[N]) st8 [dst]=val[N],8
+ br.ctop.sptk.few 1b
+ ;;
+.exit:
+ mov ar.lc=saved_lc
+ mov pr=saved_pr,0xffffffffffff0000
+ mov ar.pfs=saved_pfs
+ br.ret.sptk.many rp
+
+slow_memcpy:
+ adds cnt=-1,in2
+ ;;
+ mov ar.lc=cnt
+ ;;
+1:
+(p[0]) ld1 val[0]=[src],1
+(p[N]) st1 [dst]=val[N],1
+ br.ctop.sptk.few 1b
+ br.sptk.few .exit
+
+END(memcpy)
diff --git a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
index 2a57d0ae3..026f88998 100644
--- a/arch/ia64/mm/tlb.c
+++ b/arch/ia64/mm/tlb.c
@@ -182,7 +182,7 @@ flush_tlb_range (struct mm_struct *mm, unsigned long start, unsigned long end)
unsigned long nbits;
if (mm != current->active_mm) {
- /* this doesn't happen often, if at all, so it's not worth optimizing for... */
+ /* this does happen, but perhaps it's not worth optimizing for? */
mm->context = 0;
return;
}
diff --git a/arch/ia64/tools/Makefile b/arch/ia64/tools/Makefile
index b3d2e74b9..0e6d78450 100644
--- a/arch/ia64/tools/Makefile
+++ b/arch/ia64/tools/Makefile
@@ -11,10 +11,10 @@ clean:
fastdep: offsets.h
@if ! cmp -s offsets.h ${TARGET}; then \
- echo "Updating ${TARGET}..."; \
+ echo -e "*** Updating ${TARGET}..."; \
cp offsets.h ${TARGET}; \
else \
- echo "${TARGET} is up to date"; \
+ echo "*** ${TARGET} is up to date"; \
fi
#
@@ -31,9 +31,11 @@ ifeq ($(CROSS_COMPILE),)
offsets.h: print_offsets
./print_offsets > offsets.h
-print_offsets: print_offsets.c
+print_offsets: print_offsets.c FORCE_RECOMPILE
$(CC) $(CFLAGS) print_offsets.c -o $@
+FORCE_RECOMPILE:
+
else
offsets.h: print_offsets.s
diff --git a/arch/ia64/tools/print_offsets.awk b/arch/ia64/tools/print_offsets.awk
index 5eb8bcb63..63136aa3a 100644
--- a/arch/ia64/tools/print_offsets.awk
+++ b/arch/ia64/tools/print_offsets.awk
@@ -9,9 +9,10 @@ BEGIN {
print " */"
#
# This is a cheesy hack. Make sure that
- # PF_PTRACED == 1<<PF_PTRACED_BIT.
+ # PT_PTRACED == 1<<PT_PTRACED_BIT.
#
- print "#define PF_PTRACED_BIT 4"
+ print "#define PT_PTRACED_BIT 0"
+ print "#define PT_TRACESYS_BIT 1"
}
# look for .tab:
diff --git a/arch/ia64/tools/print_offsets.c b/arch/ia64/tools/print_offsets.c
index d7d7e3e6f..3a7259b09 100644
--- a/arch/ia64/tools/print_offsets.c
+++ b/arch/ia64/tools/print_offsets.c
@@ -49,7 +49,7 @@ tab[] =
{ "UNW_FRAME_INFO_SIZE", sizeof (struct unw_frame_info) },
#endif
{ "", 0 }, /* spacer */
- { "IA64_TASK_FLAGS_OFFSET", offsetof (struct task_struct, flags) },
+ { "IA64_TASK_PTRACE_OFFSET", offsetof (struct task_struct, ptrace) },
{ "IA64_TASK_SIGPENDING_OFFSET", offsetof (struct task_struct, sigpending) },
{ "IA64_TASK_NEED_RESCHED_OFFSET", offsetof (struct task_struct, need_resched) },
{ "IA64_TASK_PROCESSOR_OFFSET", offsetof (struct task_struct, processor) },
@@ -175,10 +175,12 @@ main (int argc, char **argv)
"arch/ia64/tools/print_offsets.\n *\n */\n\n");
/* This is stretching things a bit, but entry.S needs the bit number
- for PF_PTRACED and it can't include <linux/sched.h> so this seems
- like a reasonably solution. At least the code won't break shoudl
- PF_PTRACED ever change. */
- printf ("#define PF_PTRACED_BIT\t\t\t%u\n\n", ffs (PF_PTRACED) - 1);
+ for PT_PTRACED and it can't include <linux/sched.h> so this seems
+ like a reasonably solution. At least the code won't break in
+ subtle ways should PT_PTRACED ever change. Ditto for
+ PT_TRACESYS_BIT. */
+ printf ("#define PT_PTRACED_BIT\t\t\t%u\n", ffs (PT_PTRACED) - 1);
+ printf ("#define PT_TRACESYS_BIT\t\t\t%u\n\n", ffs (PT_TRACESYS) - 1);
for (i = 0; i < sizeof (tab) / sizeof (tab[0]); ++i)
{
diff --git a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S
index 0e2dc7aaa..5c199bc1a 100644
--- a/arch/ia64/vmlinux.lds.S
+++ b/arch/ia64/vmlinux.lds.S
@@ -125,6 +125,7 @@ SECTIONS
/DISCARD/ : {
*(.text.exit)
*(.data.exit)
+ *(.exitcall.exit)
}
/* Stabs debugging sections. */