summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/kernel/Makefile2
-rw-r--r--arch/alpha/kernel/osf_sys.c18
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/boot/compressed/Makefile2
-rw-r--r--arch/i386/Makefile6
-rw-r--r--arch/i386/boot/compressed/Makefile3
-rw-r--r--arch/i386/config.in1
-rw-r--r--arch/i386/defconfig7
-rw-r--r--arch/i386/kernel/irq.c6
-rw-r--r--arch/i386/mm/init.c2
-rw-r--r--arch/ia64/Makefile2
-rw-r--r--arch/mips/kernel/sysirix.c54
-rw-r--r--arch/mips64/defconfig17
-rw-r--r--arch/mips64/defconfig-ip222
-rw-r--r--arch/mips64/defconfig-ip2717
-rw-r--r--arch/ppc/configs/common_defconfig19
-rw-r--r--arch/ppc/defconfig19
-rw-r--r--arch/ppc/kernel/Makefile4
-rw-r--r--arch/ppc/kernel/feature.c3
-rw-r--r--arch/ppc/kernel/head.S11
-rw-r--r--arch/ppc/kernel/irq.c159
-rw-r--r--arch/ppc/kernel/pci.c50
-rw-r--r--arch/ppc/kernel/pmac_pic.c1
-rw-r--r--arch/ppc/kernel/pmac_setup.c17
-rw-r--r--arch/ppc/kernel/ppc_htab.c12
-rw-r--r--arch/ppc/kernel/prom.c80
-rw-r--r--arch/ppc/kernel/setup.c10
-rw-r--r--arch/ppc/mm/init.c5
-rw-r--r--arch/ppc/xmon/start.c26
-rw-r--r--arch/ppc/xmon/xmon.c32
-rw-r--r--arch/sh/Makefile18
-rw-r--r--arch/sh/boot/Makefile2
-rw-r--r--arch/sh/config.in121
-rw-r--r--arch/sh/defconfig71
-rw-r--r--arch/sh/kernel/Makefile11
-rw-r--r--arch/sh/kernel/cf-enabler.c30
-rw-r--r--arch/sh/kernel/entry.S351
-rw-r--r--arch/sh/kernel/fpu.c266
-rw-r--r--arch/sh/kernel/head.S48
-rw-r--r--arch/sh/kernel/irq.c50
-rw-r--r--arch/sh/kernel/irq_imask.c106
-rw-r--r--arch/sh/kernel/irq_onchip.c38
-rw-r--r--arch/sh/kernel/pci-sh.c12
-rw-r--r--arch/sh/kernel/process.c157
-rw-r--r--arch/sh/kernel/semaphore.c161
-rw-r--r--arch/sh/kernel/setup.c85
-rw-r--r--arch/sh/kernel/signal.c28
-rw-r--r--arch/sh/kernel/sys_sh.c52
-rw-r--r--arch/sh/kernel/time.c138
-rw-r--r--arch/sh/kernel/traps.c23
-rw-r--r--arch/sh/mm/cache.c29
-rw-r--r--arch/sh/mm/fault.c23
-rw-r--r--arch/sh/mm/init.c93
-rw-r--r--arch/sh/mm/ioremap.c3
-rw-r--r--arch/sh/vmlinux.lds.S38
-rw-r--r--arch/sparc/kernel/sys_sunos.c28
-rw-r--r--arch/sparc64/kernel/entry.S14
-rw-r--r--arch/sparc64/kernel/head.S13
-rw-r--r--arch/sparc64/kernel/setup.c10
-rw-r--r--arch/sparc64/kernel/smp.c12
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c28
-rw-r--r--arch/sparc64/kernel/sys_sunos32.c26
-rw-r--r--arch/sparc64/lib/blockops.S38
-rw-r--r--arch/sparc64/mm/init.c86
-rw-r--r--arch/sparc64/mm/ultra.S56
65 files changed, 2123 insertions, 733 deletions
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
index 309a308a4..6c538f4ba 100644
--- a/arch/alpha/kernel/Makefile
+++ b/arch/alpha/kernel/Makefile
@@ -132,7 +132,7 @@ asm_offsets: check_asm
./check_asm > $(TOPDIR)/include/asm-alpha/asm_offsets.h
check_asm: check_asm.c
- gcc -o $@ $< -I$(TOPDIR)/include -D__KERNEL__ -ffixed-8
+ $(HOSTCC) -o $@ $< $(CPPFLAGS) -ffixed-8
clean::
rm -f check_asm
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index d9af71414..6a2ff8a9b 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -135,10 +135,8 @@ asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent *dirent,
{
int error;
struct file *file;
- struct inode *inode;
struct osf_dirent_callback buf;
- lock_kernel();
error = -EBADF;
file = fget(fd);
if (!file)
@@ -149,18 +147,8 @@ asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent *dirent,
buf.count = count;
buf.error = 0;
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out_putf;
-
- /*
- * Get the inode's semaphore to prevent changes
- * to the directory while we read it.
- */
- inode = file->f_dentry->d_inode;
- down(&inode->i_sem);
- error = file->f_op->readdir(file, &buf, osf_filldir);
- up(&inode->i_sem);
+ lock_kernel();
+ error = vfs_readdir(file, osf_filldir, &buf);
if (error < 0)
goto out_putf;
@@ -169,9 +157,9 @@ asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent *dirent,
error = count - buf.count;
out_putf:
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 0df16ffa4..bb0a34f92 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -100,7 +100,7 @@ ifeq ($(CONFIG_CPU_32),y)
endif
endif
-GCCLIB := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
+LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name)
ifeq ($(CONFIG_ARCH_A5K),y)
MACHINE = a5k
@@ -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.o arch/arm/lib/lib.a $(LIBS) $(GCCLIB)
+LIBS := arch/arm/lib/lib.o arch/arm/lib/lib.a $(LIBS) $(LIBGCC)
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 d92f2b093..fca3e8c92 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -73,7 +73,7 @@ endif
all: vmlinux
vmlinux: $(HEAD) $(OBJS) piggy.o vmlinux.lds
- $(LD) $(ZLDFLAGS) $(HEAD) $(OBJS) piggy.o $(GCCLIB) -o vmlinux
+ $(LD) $(ZLDFLAGS) $(HEAD) $(OBJS) piggy.o $(LIBGCC) -o vmlinux
$(HEAD): $(HEAD:.o=.S)
$(CC) $(AFLAGS) -traditional -c $(HEAD:.o=.S)
diff --git a/arch/i386/Makefile b/arch/i386/Makefile
index 4ba71ba06..2a84bf05f 100644
--- a/arch/i386/Makefile
+++ b/arch/i386/Makefile
@@ -21,12 +21,10 @@ OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
LDFLAGS=-e stext
LINKFLAGS =-T $(TOPDIR)/arch/i386/vmlinux.lds $(LDFLAGS)
-CFLAGS_PIPE := -pipe
+CFLAGS += -pipe
# only work around strength reduction bug(s) on older gcc versions
-CFLAGS_NSR := $(shell if $(CC) -march=i486 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo ""; else echo "-fno-strength-reduce"; fi)
-
-CFLAGS := $(CFLAGS) $(CFLAGS_PIPE) $(CFLAGS_NSR)
+CFLAGS += $(shell if ! $(CC) -march=i486 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strength-reduce"; fi)
# prevent gcc from keeping the stack 16 byte aligned
CFLAGS += $(shell if $(CC) -mpreferred-stack-boundary=2 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-mpreferred-stack-boundary=2"; fi)
diff --git a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile
index 6e4b4998d..b4b7de133 100644
--- a/arch/i386/boot/compressed/Makefile
+++ b/arch/i386/boot/compressed/Makefile
@@ -33,6 +33,9 @@ bvmlinux: piggy.o $(OBJECTS)
head.o: head.S
$(CC) $(AFLAGS) -traditional -c head.S
+misc.o: misc.c
+ $(CC) $(CFLAGS) -c misc.c
+
piggy.o: $(SYSTEM)
tmppiggy=_tmp_$$$$piggy; \
rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
diff --git a/arch/i386/config.in b/arch/i386/config.in
index 1d5c0d5f7..11a98fc58 100644
--- a/arch/i386/config.in
+++ b/arch/i386/config.in
@@ -47,6 +47,7 @@ if [ "$CONFIG_MK7" = "y" ]; then
define_bool CONFIG_X86_TSC y
define_bool CONFIG_X86_GOOD_APIC y
define_bool CONFIG_X86_USE_3DNOW y
+ define_bool CONFIG_X86_PGE y
fi
if [ "$CONFIG_DEVFS_FS" = "y" ]; then
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index f2517c27d..aa04c3685 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -76,6 +76,10 @@ CONFIG_BINFMT_MISC=y
CONFIG_PM=y
CONFIG_ACPI=y
# CONFIG_APM is not set
+
+#
+# Parallel port support
+#
# CONFIG_PARPORT is not set
#
@@ -282,6 +286,7 @@ CONFIG_NET_ETHERNET=y
CONFIG_NET_PCI=y
# CONFIG_PCNET32 is not set
# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
# CONFIG_DE4X5 is not set
# CONFIG_TULIP is not set
# CONFIG_DGRS is not set
@@ -308,7 +313,7 @@ CONFIG_EEPRO100=y
# CONFIG_NET_RADIO is not set
#
-# Token Ring driver support
+# Token Ring devices
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index 4163626f4..120c861e7 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -199,13 +199,13 @@ static void show(char * str)
printk(" %d",local_bh_count(i));
printk(" ]\nStack dumps:");
- for(i=0;i< smp_num_cpus;i++) {
+ for(i = 0; i < smp_num_cpus; i++) {
unsigned long esp;
- if(i==cpu)
+ if (i == cpu)
continue;
printk("\nCPU %d:",i);
esp = init_tss[i].esp0;
- if(esp==NULL) {
+ if (!esp) {
/* tss->esp0 is set to NULL in cpu_init(),
* it's initialized when the cpu returns to user
* space. -- manfreds
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index b9e535a71..c801285eb 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -320,7 +320,7 @@ static void __init pagetable_init(void)
if (vaddr >= end)
break;
#if CONFIG_X86_PAE
- pmd = (pmd_t *) alloc_bootmem_pages(PAGE_SIZE);
+ pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
#else
pmd = (pmd_t *)pgd;
diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile
index 7dd3caabc..24e274aa0 100644
--- a/arch/ia64/Makefile
+++ b/arch/ia64/Makefile
@@ -88,7 +88,7 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
vmlinux: arch/$(ARCH)/vmlinux.lds
arch/$(ARCH)/vmlinux.lds: arch/$(ARCH)/vmlinux.lds.S FORCE
- gcc -D__ASSEMBLY__ -E -C -P -I$(HPATH) -I$(HPATH)/asm-$(ARCH) \
+ $(CPP) -D__ASSEMBLY__ -C -P -I$(HPATH) -I$(HPATH)/asm-$(ARCH) \
arch/$(ARCH)/vmlinux.lds.S > $@
FORCE: ;
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index 0c07b8dd6..0d0fac150 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -1,4 +1,4 @@
-/* $Id: sysirix.c,v 1.24 2000/02/05 06:47:08 ralf Exp $
+/* $Id: sysirix.c,v 1.25 2000/03/07 15:45:28 ralf Exp $
*
* sysirix.c: IRIX system call emulation.
*
@@ -2023,12 +2023,10 @@ static int irix_filldir32(void *__buf, const char *name, int namlen,
asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count, int *eob)
{
struct file *file;
- struct inode *inode;
struct irix_dirent32 *lastdirent;
struct irix_dirent32_callback buf;
int error;
- lock_kernel();
#ifdef DEBUG_GETDENTS
printk("[%s:%ld] ngetdents(%d, %p, %d, %p) ", current->comm,
current->pid, fd, dirent, count, eob);
@@ -2038,26 +2036,14 @@ asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count
if (!file)
goto out;
- inode = file->f_dentry->d_inode;
- if (!inode)
- goto out_putf;
+ lock_kernel();
buf.current_dir = (struct irix_dirent32 *) dirent;
buf.previous = NULL;
buf.count = count;
buf.error = 0;
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out_putf;
-
- /*
- * Get the inode's semaphore to prevent changes
- * to the directory while we read it.
- */
- down(&inode->i_sem);
- error = file->f_op->readdir(file, &buf, irix_filldir32);
- up(&inode->i_sem);
+ error = vfs_readdir(file, irix_filldir32, &buf);
if (error < 0)
goto out_putf;
error = buf.error;
@@ -2079,9 +2065,9 @@ asmlinkage int irix_ngetdents(unsigned int fd, void * dirent, unsigned int count
error = count - buf.count;
out_putf:
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
@@ -2132,12 +2118,10 @@ static int irix_filldir64(void * __buf, const char * name, int namlen,
asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
{
struct file *file;
- struct inode *inode;
struct irix_dirent64 *lastdirent;
struct irix_dirent64_callback buf;
int error;
- lock_kernel();
#ifdef DEBUG_GETDENTS
printk("[%s:%d] getdents64(%d, %p, %d) ", current->comm,
current->pid, fd, dirent, cnt);
@@ -2146,13 +2130,7 @@ asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
if (!(file = fget(fd)))
goto out;
- inode = file->f_dentry->d_inode;
- if (!inode)
- goto out_f;
-
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out_f;
+ lock_kernel();
error = -EFAULT;
if(!access_ok(VERIFY_WRITE, dirent, cnt))
@@ -2166,9 +2144,7 @@ asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
buf.previous = NULL;
buf.count = cnt;
buf.error = 0;
- down(&inode->i_sem);
- error = file->f_op->readdir(file, &buf, irix_filldir64);
- up(&inode->i_sem);
+ error = vfs_readdir(file, irix_filldir64, &buf);
if (error < 0)
goto out_f;
lastdirent = buf.previous;
@@ -2183,21 +2159,19 @@ asmlinkage int irix_getdents64(int fd, void *dirent, int cnt)
error = cnt - buf.count;
out_f:
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
{
struct file *file;
- struct inode *inode;
struct irix_dirent64 *lastdirent;
struct irix_dirent64_callback buf;
int error;
- lock_kernel();
#ifdef DEBUG_GETDENTS
printk("[%s:%d] ngetdents64(%d, %p, %d) ", current->comm,
current->pid, fd, dirent, cnt);
@@ -2206,13 +2180,7 @@ asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
if (!(file = fget(fd)))
goto out;
- inode = file->f_dentry->d_inode;
- if (!inode)
- goto out_f;
-
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out_f;
+ lock_kernel();
error = -EFAULT;
if(!access_ok(VERIFY_WRITE, dirent, cnt) ||
@@ -2228,9 +2196,7 @@ asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
buf.previous = NULL;
buf.count = cnt;
buf.error = 0;
- down(&inode->i_sem);
- error = file->f_op->readdir(file, &buf, irix_filldir64);
- up(&inode->i_sem);
+ error = vfs_readdir(file, irix_filldir64, &buf);
if (error < 0)
goto out_f;
lastdirent = buf.previous;
@@ -2245,9 +2211,9 @@ asmlinkage int irix_ngetdents64(int fd, void *dirent, int cnt, int *eob)
error = cnt - buf.count;
out_f:
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig
index c4f4ba27a..21623e01f 100644
--- a/arch/mips64/defconfig
+++ b/arch/mips64/defconfig
@@ -14,6 +14,7 @@
CONFIG_SGI_IP27=y
# CONFIG_SGI_SN0_N_MODE is not set
# CONFIG_DISCONTIGMEM is not set
+# CONFIG_SMP is not set
CONFIG_BOOT_ELF64=y
CONFIG_ARC64=y
CONFIG_COHERENT_IO=y
@@ -129,7 +130,6 @@ CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
# CONFIG_CHR_DEV_ST is not set
-CONFIG_ST_EXTRA_DEVS=2
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
@@ -207,6 +207,7 @@ CONFIG_NETDEVICES=y
#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_NET_SB1000 is not set
@@ -221,7 +222,7 @@ CONFIG_SGI_IOC3_ETH=y
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
-# CONFIG_NET_EISA is not set
+# CONFIG_NET_PCI is not set
# CONFIG_NET_POCKET is not set
#
@@ -240,7 +241,7 @@ CONFIG_SGI_IOC3_ETH=y
# CONFIG_NET_RADIO is not set
#
-# Token Ring driver support
+# Token Ring devices
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
@@ -328,7 +329,7 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_USB is not set
#
-# Filesystems
+# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
@@ -347,20 +348,17 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_JOLIET is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_DEBUG is not set
# CONFIG_DEVPTS_FS is not set
# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
-# CONFIG_SYSV_FS_WRITE is not set
# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
#
# Network File Systems
@@ -369,7 +367,6 @@ CONFIG_EXT2_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
# CONFIG_NFSD 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/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22
index 4caa8e70d..a5de95ca5 100644
--- a/arch/mips64/defconfig-ip22
+++ b/arch/mips64/defconfig-ip22
@@ -159,7 +159,7 @@ CONFIG_NETDEVICES=y
# CONFIG_NET_RADIO is not set
#
-# Token Ring driver support
+# Token Ring devices
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27
index c4f4ba27a..21623e01f 100644
--- a/arch/mips64/defconfig-ip27
+++ b/arch/mips64/defconfig-ip27
@@ -14,6 +14,7 @@
CONFIG_SGI_IP27=y
# CONFIG_SGI_SN0_N_MODE is not set
# CONFIG_DISCONTIGMEM is not set
+# CONFIG_SMP is not set
CONFIG_BOOT_ELF64=y
CONFIG_ARC64=y
CONFIG_COHERENT_IO=y
@@ -129,7 +130,6 @@ CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
# CONFIG_CHR_DEV_ST is not set
-CONFIG_ST_EXTRA_DEVS=2
# CONFIG_BLK_DEV_SR is not set
# CONFIG_CHR_DEV_SG is not set
@@ -207,6 +207,7 @@ CONFIG_NETDEVICES=y
#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_NET_SB1000 is not set
@@ -221,7 +222,7 @@ CONFIG_SGI_IOC3_ETH=y
# CONFIG_NET_VENDOR_RACAL is not set
# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
-# CONFIG_NET_EISA is not set
+# CONFIG_NET_PCI is not set
# CONFIG_NET_POCKET is not set
#
@@ -240,7 +241,7 @@ CONFIG_SGI_IOC3_ETH=y
# CONFIG_NET_RADIO is not set
#
-# Token Ring driver support
+# Token Ring devices
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
@@ -328,7 +329,7 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_USB is not set
#
-# Filesystems
+# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
@@ -347,20 +348,17 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_JOLIET is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS is not set
-# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_DEBUG is not set
# CONFIG_DEVPTS_FS is not set
# CONFIG_QNX4FS_FS is not set
-# CONFIG_QNX4FS_RW is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
-# CONFIG_SYSV_FS_WRITE is not set
# CONFIG_UDF_FS is not set
-# CONFIG_UDF_RW is not set
# CONFIG_UFS_FS is not set
-# CONFIG_UFS_FS_WRITE is not set
#
# Network File Systems
@@ -369,7 +367,6 @@ CONFIG_EXT2_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
# CONFIG_NFSD 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/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig
index 4ba96bde9..c849bac82 100644
--- a/arch/ppc/configs/common_defconfig
+++ b/arch/ppc/configs/common_defconfig
@@ -92,7 +92,14 @@ CONFIG_BLK_DEV_IDESCSI=y
#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# 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_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_SL82C105=y
CONFIG_BLK_DEV_IDE_PMAC=y
CONFIG_BLK_DEV_IDEDMA_PMAC=y
@@ -194,6 +201,7 @@ CONFIG_SCSI_CONSTANTS=y
#
# SCSI low-level drivers
#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
@@ -249,7 +257,6 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20
CONFIG_SCSI_MESH=y
CONFIG_SCSI_MESH_SYNC_RATE=5
CONFIG_SCSI_MAC53C94=y
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
#
# IEEE 1394 (FireWire) support
@@ -266,6 +273,7 @@ CONFIG_NETDEVICES=y
#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_ETHERTAP is not set
# CONFIG_NET_SB1000 is not set
@@ -389,7 +397,7 @@ CONFIG_FB_MATROX_MYSTIQUE=y
CONFIG_FB_MATROX_G100=y
# CONFIG_FB_MATROX_MULTIHEAD is not set
CONFIG_FB_ATY=y
-CONFIG_FB_ATY128=y
+# CONFIG_FB_ATY128 is not set
CONFIG_FB_3DFX=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FBCON_ADVANCED is not set
@@ -448,6 +456,7 @@ CONFIG_PSMOUSE=y
# CONFIG_WATCHDOG is not set
CONFIG_NVRAM=y
# CONFIG_RTC is not set
+# CONFIG_EFI_RTC is not set
#
# Video For Linux
@@ -496,6 +505,8 @@ CONFIG_USB_OHCI=y
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_DABUSB is not set
# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RIO500 is not set
#
# USB HID
@@ -503,7 +514,7 @@ CONFIG_USB_OHCI=y
# CONFIG_USB_HID is not set
CONFIG_USB_KBD=y
CONFIG_USB_MOUSE=y
-# CONFIG_USB_GRAPHIRE is not set
+# CONFIG_USB_WACOM is not set
# CONFIG_USB_WMFORCE is not set
CONFIG_INPUT_KEYBDEV=y
CONFIG_INPUT_MOUSEDEV=y
diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig
index 4ba96bde9..c849bac82 100644
--- a/arch/ppc/defconfig
+++ b/arch/ppc/defconfig
@@ -92,7 +92,14 @@ CONFIG_BLK_DEV_IDESCSI=y
#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
+CONFIG_BLK_DEV_IDEPCI=y
+# CONFIG_IDEPCI_SHARE_IRQ is not set
+# 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_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_OPTI621 is not set
CONFIG_BLK_DEV_SL82C105=y
CONFIG_BLK_DEV_IDE_PMAC=y
CONFIG_BLK_DEV_IDEDMA_PMAC=y
@@ -194,6 +201,7 @@ CONFIG_SCSI_CONSTANTS=y
#
# SCSI low-level drivers
#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
@@ -249,7 +257,6 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20
CONFIG_SCSI_MESH=y
CONFIG_SCSI_MESH_SYNC_RATE=5
CONFIG_SCSI_MAC53C94=y
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
#
# IEEE 1394 (FireWire) support
@@ -266,6 +273,7 @@ CONFIG_NETDEVICES=y
#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_ETHERTAP is not set
# CONFIG_NET_SB1000 is not set
@@ -389,7 +397,7 @@ CONFIG_FB_MATROX_MYSTIQUE=y
CONFIG_FB_MATROX_G100=y
# CONFIG_FB_MATROX_MULTIHEAD is not set
CONFIG_FB_ATY=y
-CONFIG_FB_ATY128=y
+# CONFIG_FB_ATY128 is not set
CONFIG_FB_3DFX=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FBCON_ADVANCED is not set
@@ -448,6 +456,7 @@ CONFIG_PSMOUSE=y
# CONFIG_WATCHDOG is not set
CONFIG_NVRAM=y
# CONFIG_RTC is not set
+# CONFIG_EFI_RTC is not set
#
# Video For Linux
@@ -496,6 +505,8 @@ CONFIG_USB_OHCI=y
# CONFIG_USB_STORAGE is not set
# CONFIG_USB_DABUSB is not set
# CONFIG_USB_PLUSB is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RIO500 is not set
#
# USB HID
@@ -503,7 +514,7 @@ CONFIG_USB_OHCI=y
# CONFIG_USB_HID is not set
CONFIG_USB_KBD=y
CONFIG_USB_MOUSE=y
-# CONFIG_USB_GRAPHIRE is not set
+# CONFIG_USB_WACOM is not set
# CONFIG_USB_WMFORCE is not set
CONFIG_INPUT_KEYBDEV=y
CONFIG_INPUT_MOUSEDEV=y
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 0f7167622..73db2269e 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -98,7 +98,7 @@ ifeq ($(CONFIG_ALL_PPC),y)
OX_OBJS += prep_setup.o
endif
ifeq ($(CONFIG_GEMINI),y)
- O_OBJS += gemini_prom.o gemini_pci.o gemini_setup.o
+ O_OBJS += gemini_prom.o gemini_pci.o gemini_setup.o open_pic.o
endif
all: $(KHEAD) kernel.o
@@ -114,6 +114,8 @@ ppc_defs.h: mk_defs.c ppc_defs.head \
$(TOPDIR)/include/asm/ptrace.h
$(CC) $(CFLAGS) -S mk_defs.c
cp ppc_defs.head ppc_defs.h
+# for bk, this way we can write to the file even if it's not checked out
+ chmod u+w ppc_defs.h
grep '^#define' mk_defs.s >> ppc_defs.h
rm mk_defs.s
diff --git a/arch/ppc/kernel/feature.c b/arch/ppc/kernel/feature.c
index 156eb187e..d14c7380a 100644
--- a/arch/ppc/kernel/feature.c
+++ b/arch/ppc/kernel/feature.c
@@ -154,6 +154,9 @@ feature_init(void)
{
struct device_node *np;
+ if (_machine != _MACH_Pmac)
+ return;
+
np = find_devices("mac-io");
while (np != NULL) {
/* KeyLargo contains several (5 ?) FCR registers in mac-io,
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index b6d44ecb3..dab413c15 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -222,7 +222,7 @@ __after_prom_start:
mtspr IBAT0L,r8
mtspr IBAT0U,r11
#if 0 /* Useful debug code, please leave in for now so I don't have to
- * look at docs when I need to setup a BAT ;
+ * look at docs when I need to setup a BAT ...
*/
bl setup_screen_bat
#endif
@@ -256,6 +256,8 @@ __after_prom_start:
* prep needs the mmu to be turned on here, but pmac already has it on.
* this shouldn't bother the pmac since it just gets turned on again
* as we jump to our code at KERNELBASE. -- Cort
+ * Actually no, pmac doesn't have it on any more. BootX enters with MMU
+ * off, and in other cases, we now turn it off before changing BATs above.
*/
turn_on_mmu:
mfmsr r0
@@ -1423,6 +1425,7 @@ start_here:
li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
mtspr SRR0,r4
mtspr SRR1,r3
+ SYNC
rfi
/* Load up the kernel context */
2:
@@ -1433,6 +1436,7 @@ start_here:
tlbsync /* ... on all CPUs */
sync
#endif
+
bl load_up_mmu
/* Set up for using our exception vectors */
@@ -1448,6 +1452,7 @@ start_here:
ori r3,r3,start_kernel@l
mtspr SRR0,r3
mtspr SRR1,r4
+ SYNC
rfi /* enable MMU and jump to start_kernel */
/*
@@ -1530,11 +1535,11 @@ setup_screen_bat:
li r3,0
mtspr DBAT1U,r3
mtspr IBAT1U,r3
- lis r3, 0x9100
+ lis r3, 0x8200
ori r4,r3,0x2a
mtspr DBAT1L,r4
mtspr IBAT1L,r4
- ori r3,r3,(BL_8M<<2)|0x2 /* set up BAT registers for 604 */
+ ori r3,r3,(BL_16M<<2)|0x2 /* set up BAT registers for 604 */
mtspr DBAT1U,r3
mtspr IBAT1U,r3
blr
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index ffac1871a..f8e11ecc0 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -45,7 +45,9 @@
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/irq.h>
+#include <linux/proc_fs.h>
+#include <asm/uaccess.h>
#include <asm/bitops.h>
#include <asm/hydra.h>
#include <asm/system.h>
@@ -611,3 +613,160 @@ void __global_restore_flags(unsigned long flags)
}
#endif /* __SMP__ */
+static struct proc_dir_entry * root_irq_dir;
+static struct proc_dir_entry * irq_dir [NR_IRQS];
+static struct proc_dir_entry * smp_affinity_entry [NR_IRQS];
+
+unsigned int irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = 0xffffffff};
+
+#define HEX_DIGITS 8
+
+static int irq_affinity_read_proc (char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ if (count < HEX_DIGITS+1)
+ return -EINVAL;
+ return sprintf (page, "%08x\n", irq_affinity[(int)data]);
+}
+
+static unsigned int parse_hex_value (const char *buffer,
+ unsigned long count, unsigned long *ret)
+{
+ unsigned char hexnum [HEX_DIGITS];
+ unsigned long value;
+ int i;
+
+ if (!count)
+ return -EINVAL;
+ if (count > HEX_DIGITS)
+ count = HEX_DIGITS;
+ if (copy_from_user(hexnum, buffer, count))
+ return -EFAULT;
+
+ /*
+ * Parse the first 8 characters as a hex string, any non-hex char
+ * is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same.
+ */
+ value = 0;
+
+ for (i = 0; i < count; i++) {
+ unsigned int c = hexnum[i];
+
+ switch (c) {
+ case '0' ... '9': c -= '0'; break;
+ case 'a' ... 'f': c -= 'a'-10; break;
+ case 'A' ... 'F': c -= 'A'-10; break;
+ default:
+ goto out;
+ }
+ value = (value << 4) | c;
+ }
+out:
+ *ret = value;
+ return 0;
+}
+
+static int irq_affinity_write_proc (struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ int irq = (int) data, full_count = count, err;
+ unsigned long new_value;
+
+ if (!irq_desc[irq].handler->set_affinity)
+ return -EIO;
+
+ err = parse_hex_value(buffer, count, &new_value);
+
+#if CONFIG_SMP
+ /*
+ * Do not allow disabling IRQs completely - it's a too easy
+ * way to make the system unusable accidentally :-) At least
+ * one online CPU still has to be targeted.
+ */
+ if (!(new_value & cpu_online_map))
+ return -EINVAL;
+#endif
+
+ irq_affinity[irq] = new_value;
+ irq_desc[irq].handler->set_affinity(irq, new_value);
+
+ return full_count;
+}
+
+static int prof_cpu_mask_read_proc (char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ unsigned long *mask = (unsigned long *) data;
+ if (count < HEX_DIGITS+1)
+ return -EINVAL;
+ return sprintf (page, "%08lx\n", *mask);
+}
+
+static int prof_cpu_mask_write_proc (struct file *file, const char *buffer,
+ unsigned long count, void *data)
+{
+ unsigned long *mask = (unsigned long *) data, full_count = count, err;
+ unsigned long new_value;
+
+ err = parse_hex_value(buffer, count, &new_value);
+ if (err)
+ return err;
+
+ *mask = new_value;
+ return full_count;
+}
+
+#define MAX_NAMELEN 10
+
+static void register_irq_proc (unsigned int irq)
+{
+ struct proc_dir_entry *entry;
+ char name [MAX_NAMELEN];
+
+ if (!root_irq_dir || (irq_desc[irq].handler == NULL))
+ return;
+
+ memset(name, 0, MAX_NAMELEN);
+ sprintf(name, "%d", irq);
+
+ /* create /proc/irq/1234 */
+ irq_dir[irq] = proc_mkdir(name, root_irq_dir);
+
+ /* create /proc/irq/1234/smp_affinity */
+ entry = create_proc_entry("smp_affinity", 0700, irq_dir[irq]);
+
+ entry->nlink = 1;
+ entry->data = (void *)irq;
+ entry->read_proc = irq_affinity_read_proc;
+ entry->write_proc = irq_affinity_write_proc;
+
+ smp_affinity_entry[irq] = entry;
+}
+
+unsigned long prof_cpu_mask = -1;
+
+void init_irq_proc (void)
+{
+ struct proc_dir_entry *entry;
+ int i;
+
+ /* create /proc/irq */
+ root_irq_dir = proc_mkdir("irq", 0);
+
+ /* create /proc/irq/prof_cpu_mask */
+ entry = create_proc_entry("prof_cpu_mask", 0700, root_irq_dir);
+
+ entry->nlink = 1;
+ entry->data = (void *)&prof_cpu_mask;
+ entry->read_proc = prof_cpu_mask_read_proc;
+ entry->write_proc = prof_cpu_mask_write_proc;
+
+ /*
+ * Create entries for all existing IRQs.
+ */
+ for (i = 0; i < NR_IRQS; i++) {
+ if (irq_desc[i].handler == NULL)
+ continue;
+ register_irq_proc(i);
+ }
+}
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 8326bc369..773c99b5c 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -131,11 +131,6 @@ char __init *pcibios_setup(char *str)
return str;
}
-int pcibios_assign_resource(struct pci_dev *pdev, int resource)
-{
- return 0;
-}
-
/* the next two are stolen from the alpha port... */
void __init
pcibios_update_resource(struct pci_dev *dev, struct resource *root,
@@ -189,48 +184,3 @@ int pcibios_enable_device(struct pci_dev *dev)
}
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_pic.c b/arch/ppc/kernel/pmac_pic.c
index b0276ca2c..f2794ae5a 100644
--- a/arch/ppc/kernel/pmac_pic.c
+++ b/arch/ppc/kernel/pmac_pic.c
@@ -10,6 +10,7 @@
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/prom.h>
+#include <asm/pci-bridge.h>
#include "pmac_pic.h"
/* pmac */struct pmac_irq_hw {
diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c
index 5fef07e89..c2c4cbbf4 100644
--- a/arch/ppc/kernel/pmac_setup.c
+++ b/arch/ppc/kernel/pmac_setup.c
@@ -283,8 +283,6 @@ pmac_setup_arch(void)
ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000)
? "enabled" : "disabled");
- feature_init();
-
#ifdef CONFIG_KGDB
zs_kgdb_hook(0);
#endif
@@ -325,14 +323,15 @@ static void __init init_p2pbridge(void)
|| p2pbridge->parent == NULL
|| strcmp(p2pbridge->parent->name, "pci") != 0)
return;
-
if (pci_device_loc(p2pbridge, &bus, &devfn) < 0)
return;
-
- pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val);
+ if (ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val) < 0) {
+ printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n");
+ return;
+ }
val &= ~PCI_BRIDGE_CTL_MASTER_ABORT;
- pcibios_write_config_word(bus, devfn, PCI_BRIDGE_CONTROL, val);
- pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val);
+ ppc_md.pcibios_write_config_word(bus, devfn, PCI_BRIDGE_CONTROL, val);
+ ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val);
}
static void __init ohare_init(void)
@@ -703,8 +702,8 @@ pmac_progress(char *s, unsigned short hex)
{
if (disp_bi == 0)
return;
- drawstring(s);
- drawchar('\n');
+ prom_drawstring(s);
+ prom_drawchar('\n');
}
#endif CONFIG_BOOTX_TEXT
diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c
index da46f3c1c..441310e68 100644
--- a/arch/ppc/kernel/ppc_htab.c
+++ b/arch/ppc/kernel/ppc_htab.c
@@ -44,12 +44,6 @@ extern unsigned long htab_evicts;
extern unsigned long pte_misses;
extern unsigned long pte_errors;
-struct file_operations ppc_htab_operations = {
- llseek: ppc_htab_lseek,
- read: ppc_htab_read,
- write: ppc_htab_write,
-};
-
/* these will go into processor.h when I'm done debugging -- Cort */
#define MMCR0 952
#define MMCR0_PMC1_CYCLES (0x1<<7)
@@ -63,6 +57,12 @@ struct file_operations ppc_htab_operations = {
#define PMC1 953
#define PMC2 954
+struct file_operations ppc_htab_operations = {
+ llseek: ppc_htab_lseek,
+ read: ppc_htab_read,
+ write: ppc_htab_write,
+};
+
char *pmc1_lookup(unsigned long mmcr0)
{
switch ( mmcr0 & (0x7f<<7) )
diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c
index 4ee638f62..310e301e6 100644
--- a/arch/ppc/kernel/prom.c
+++ b/arch/ppc/kernel/prom.c
@@ -114,9 +114,9 @@ static struct device_node *allnodes = 0;
static void clearscreen(void);
static void flushscreen(void);
-void drawchar(char c);
-void drawstring(const char *c);
-static void drawhex(unsigned long v);
+void prom_drawchar(char c);
+void prom_drawstring(const char *c);
+void prom_drawhex(unsigned long v);
static void scrollscreen(void);
static void draw_byte(unsigned char c, long locX, long locY);
@@ -134,6 +134,8 @@ static long g_max_loc_Y = 0;
static unsigned char vga_font[cmapsz];
+int bootx_text_mapped = 1;
+
#endif /* CONFIG_BOOTX_TEXT */
@@ -257,7 +259,7 @@ prom_print(const char *msg)
{
#ifdef CONFIG_BOOTX_TEXT
if (RELOC(disp_bi) != 0)
- drawstring(msg);
+ prom_drawstring(msg);
#endif
return;
}
@@ -385,6 +387,7 @@ prom_init(int r3, int r4, prom_entry pp)
#ifdef CONFIG_BOOTX_TEXT
prom_print(RELOC("booting...\n"));
flushscreen();
+ RELOC(bootx_text_mapped) = 0;
#endif
return phys;
}
@@ -633,6 +636,7 @@ prom_init(int r3, int r4, prom_entry pp)
prom_welcome(PTRRELOC(RELOC(disp_bi)), phys);
prom_print(RELOC("booting...\n"));
}
+ RELOC(bootx_text_mapped) = 0;
#endif
return phys;
@@ -648,28 +652,30 @@ prom_welcome(boot_infos_t* bi, unsigned long phys)
prom_print(RELOC("Welcome to Linux, kernel " UTS_RELEASE "\n"));
prom_print(RELOC("\nstarted at : 0x"));
- drawhex(phys);
+ prom_drawhex(phys);
prom_print(RELOC("\nlinked at : 0x"));
- drawhex(KERNELBASE);
+ prom_drawhex(KERNELBASE);
prom_print(RELOC("\nframe buffer at : 0x"));
- drawhex((unsigned long)bi->dispDeviceBase);
+ prom_drawhex((unsigned long)bi->dispDeviceBase);
prom_print(RELOC(" (phys), 0x"));
- drawhex((unsigned long)bi->logicalDisplayBase);
+ prom_drawhex((unsigned long)bi->logicalDisplayBase);
prom_print(RELOC(" (log)"));
+ prom_print(RELOC("\nklimit : 0x"));
+ prom_drawhex(RELOC(klimit));
prom_print(RELOC("\nMSR : 0x"));
__asm__ __volatile__ ("mfmsr %0" : "=r" (flags));
- drawhex(flags);
+ prom_drawhex(flags);
__asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));
pvr >>= 16;
if (pvr > 1) {
prom_print(RELOC("\nHID0 : 0x"));
__asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
- drawhex(flags);
+ prom_drawhex(flags);
}
if (pvr == 8 || pvr == 12) {
prom_print(RELOC("\nICTC : 0x"));
__asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
- drawhex(flags);
+ prom_drawhex(flags);
}
prom_print(RELOC("\n\n"));
}
@@ -807,13 +813,18 @@ setup_disp_fake_bi(ihandle dp)
prom_print(RELOC("Initializing fake screen\n"));
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("width"), &width, sizeof(width));
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("height"), &height, sizeof(height));
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("depth"), &len, sizeof(len));
+ call_prom(RELOC("getprop"), 4, 1, dp, RELOC("width"),
+ &width, sizeof(width));
+ call_prom(RELOC("getprop"), 4, 1, dp, RELOC("height"),
+ &height, sizeof(height));
+ call_prom(RELOC("getprop"), 4, 1, dp, RELOC("depth"),
+ &depth, sizeof(depth));
pitch = width * ((depth + 7) / 8);
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("linebytes"), &len, sizeof(len));
+ call_prom(RELOC("getprop"), 4, 1, dp, RELOC("linebytes"),
+ &pitch, sizeof(pitch));
address = 0;
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("address"), &len, sizeof(len));
+ call_prom(RELOC("getprop"), 4, 1, dp, RELOC("address"),
+ &address, sizeof(address));
if (address == 0) {
prom_print(RELOC("Failed to get address\n"));
return;
@@ -837,7 +848,6 @@ setup_disp_fake_bi(ihandle dp)
bi->dispDeviceRect[0] = bi->dispDeviceRect[1] = 0;
bi->dispDeviceRect[2] = width;
bi->dispDeviceRect[3] = height;
- RELOC(disp_bi) = 0;
}
#endif
@@ -1844,6 +1854,7 @@ map_bootx_text(void)
disp_bi->logicalDisplayBase =
ioremap((unsigned long) disp_bi->dispDeviceBase,
disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3]);
+ bootx_text_mapped = 1;
}
/* Calc the base address of a given point (x,y) */
@@ -1940,11 +1951,14 @@ scrollscreen(void)
__pmac
void
-drawchar(char c)
+prom_drawchar(char c)
{
unsigned long offset = reloc_offset();
int cline = 0, x;
+ if (!RELOC(bootx_text_mapped))
+ return;
+
switch (c) {
case '\b':
if (RELOC(g_loc_X) > 0)
@@ -1988,27 +2002,33 @@ drawchar(char c)
__pmac
void
-drawstring(const char *c)
+prom_drawstring(const char *c)
{
+ unsigned long offset = reloc_offset();
+
+ if (!RELOC(bootx_text_mapped))
+ return;
while (*c)
- drawchar(*c++);
+ prom_drawchar(*c++);
}
__pmac
-static void
-drawhex(unsigned long v)
+void
+prom_drawhex(unsigned long v)
{
static char hex_table[] = "0123456789abcdef";
unsigned long offset = reloc_offset();
- drawchar(RELOC(hex_table)[(v >> 28) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 24) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 20) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 16) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 12) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 8) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 4) & 0x0000000FUL]);
- drawchar(RELOC(hex_table)[(v >> 0) & 0x0000000FUL]);
+ if (!RELOC(bootx_text_mapped))
+ return;
+ prom_drawchar(RELOC(hex_table)[(v >> 28) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 24) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 20) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 16) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 12) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 8) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 4) & 0x0000000FUL]);
+ prom_drawchar(RELOC(hex_table)[(v >> 0) & 0x0000000FUL]);
}
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 5a57ba8a2..73a6c2bf7 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -29,6 +29,7 @@
#endif
#include <asm/bootx.h>
#include <asm/machdep.h>
+#include <asm/feature.h>
#ifdef CONFIG_OAK
#include "oak_setup.h"
#endif /* CONFIG_OAK */
@@ -417,7 +418,7 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
parse_bootinfo();
-
+
if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100);
#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
@@ -687,6 +688,7 @@ void __init setup_arch(char **cmdline_p)
ppc_md.setup_arch();
if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
+ paging_init();
}
void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
@@ -733,12 +735,12 @@ void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
id->eide_dma_time = __le16_to_cpu(id->eide_dma_time);
id->eide_pio = __le16_to_cpu(id->eide_pio);
id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
- for (i=0; i<2 i++)
+ for (i=0; i<2; i++)
id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
- for (i=0; i<4 i++)
+ for (i=0; i<4; i++)
id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
id->queue_depth = __le16_to_cpu(id->queue_depth);
- for (i=0; i<4 i++)
+ for (i=0; i<4; i++)
id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
id->major_rev_num = __le16_to_cpu(id->major_rev_num);
id->minor_rev_num = __le16_to_cpu(id->minor_rev_num);
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 2faccd042..eaa5924a2 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -961,8 +961,9 @@ void __init MMU_init(void)
}
#endif
#if 0
- setbat(0, disp_bi->dispDeviceBase, disp_bi->dispDeviceBase, 0x100000, IO_PAGE);
- disp_bi->logicalDisplayBase = disp_bi->dispDeviceBase;
+// This is bogus, BAT must be aligned.
+// setbat(0, disp_bi->dispDeviceBase, disp_bi->dispDeviceBase, 0x100000, IO_PAGE);
+// disp_bi->logicalDisplayBase = disp_bi->dispDeviceBase;
#endif
ioremap_base = 0xf0000000;
break;
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index 8e924699f..95b19ba47 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -17,12 +17,12 @@
static volatile unsigned char *sccc, *sccd;
unsigned long TXRDY, RXRDY;
extern void xmon_printf(const char *fmt, ...);
-extern void drawchar(char);
-extern void drawstring(const char *str);
+extern void prom_drawchar(char);
+extern void prom_drawstring(const char *str);
static int xmon_expect(const char *str, unsigned int timeout);
static int console = 0;
-static int use_screen = 0;
+static int use_screen = 1; /* default */
static int via_modem = 0;
static int xmon_use_sccb = 0;
static struct device_node *macio_node;
@@ -48,6 +48,8 @@ xmon_map_scc(void)
{
volatile unsigned char *base;
+ use_screen = 0;
+
if ( _machine == _MACH_Pmac )
{
struct device_node *np;
@@ -58,7 +60,7 @@ xmon_map_scc(void)
/* needs to be hacked if xmon_printk is to be used
from within find_via_pmu() */
if (!via_modem && disp_bi && find_via_pmu()) {
- drawstring("xmon uses screen and keyboard\n");
+ prom_drawstring("xmon uses screen and keyboard\n");
use_screen = 1;
return;
}
@@ -122,7 +124,7 @@ xmon_write(void *handle, void *ptr, int nb)
if (use_screen) {
/* write it on the screen */
for (i = 0; i < nb; ++i)
- drawchar(*p++);
+ prom_drawchar(*p++);
return nb;
}
#endif
@@ -142,6 +144,7 @@ xmon_write(void *handle, void *ptr, int nb)
ct = 1;
--i;
} else {
+ prom_drawchar(c);
if (console)
printk("%c", c);
ct = 0;
@@ -187,15 +190,15 @@ xmon_get_pmu_key(void)
do {
if (--t < 0) {
on = 1 - on;
- drawchar(on? 0xdb: 0x20);
- drawchar('\b');
+ prom_drawchar(on? 0xdb: 0x20);
+ prom_drawchar('\b');
t = 200000;
}
pmu_poll();
} while (xmon_pmu_keycode == -1);
k = xmon_pmu_keycode;
if (on)
- drawstring(" \b");
+ prom_drawstring(" \b");
/* test for shift keys */
if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
@@ -284,6 +287,8 @@ xmon_init_scc()
{
int i, x;
+ if (macio_node != 0)
+ feature_set(macio_node, FEATURE_Serial_enable);
if (via_modem && macio_node != 0) {
unsigned int t0;
@@ -399,15 +404,12 @@ int xmon_expect(const char *str, unsigned int timeout)
for (;;) {
c = xmon_read_poll();
if (c == -1) {
- if (readtb() - t0 > timeout) {
- printk("timeout\n");
+ if (readtb() - t0 > timeout)
return 0;
- }
continue;
}
if (c == '\n')
break;
- printk("%c", c);
if (c != '\r' && lineptr < &line[sizeof(line) - 1])
*lineptr++ = c;
}
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index d18d74dfd..620df9aea 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -119,7 +119,8 @@ void
xmon(struct pt_regs *excp)
{
struct pt_regs regs;
- int msr, cmd;
+ int msr, cmd, i;
+ unsigned *sp;
if (excp == NULL) {
asm volatile ("stw 0,0(%0)\n\
@@ -135,6 +136,29 @@ xmon(struct pt_regs *excp)
excp = &regs;
}
+ prom_drawstring("xmon pc="); prom_drawhex(excp->nip);
+ prom_drawstring(" lr="); prom_drawhex(excp->link);
+ prom_drawstring(" msr="); prom_drawhex(excp->msr);
+ prom_drawstring(" trap="); prom_drawhex(excp->trap);
+ prom_drawstring(" sp="); prom_drawhex(excp->gpr[1]);
+ sp = &excp->gpr[0];
+ for (i = 0; i < 32; ++i) {
+ if ((i & 7) == 0)
+ prom_drawstring("\n");
+ prom_drawstring(" ");
+ prom_drawhex(sp[i]);
+ }
+ sp = (unsigned *) excp->gpr[1];
+ for (i = 0; i < 64; ++i) {
+ if ((i & 7) == 0) {
+ prom_drawstring("\n");
+ prom_drawhex(sp);
+ prom_drawstring(" ");
+ }
+ prom_drawstring(" ");
+ prom_drawhex(sp[i]);
+ }
+ prom_drawstring("\n");
msr = get_msr();
set_msr(msr & ~0x8000); /* disable interrupts */
remove_bpts();
@@ -521,7 +545,7 @@ void
excprint(struct pt_regs *fp)
{
printf("vector: %x at pc = %x %s",
- fp->trap, fp->nip,/* pretty_lookup_name(fp->nip)*/"");
+ fp->trap, fp->nip, pretty_lookup_name(fp->nip));
printf(", msr = %x, sp = %x [%x]\n",
fp->msr, fp->gpr[1], fp);
if (fp->trap == 0x300 || fp->trap == 0x600)
@@ -1390,6 +1414,10 @@ static char *lookup_name(unsigned long addr)
if ( !sysmap || !sysmap_size )
return NULL;
+ /* adjust if addr is relative to kernelbase */
+ if ( addr < PAGE_OFFSET )
+ addr += PAGE_OFFSET;
+
cmp = simple_strtoul(c, &c, 8);
strcpy( last, strsep( &c, "\n"));
while ( c < (sysmap+sysmap_size) )
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index 31fcf5d69..83591c86c 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.1 1999/09/18 16:55:51 gniibe Exp gniibe $
+# $Id: Makefile,v 1.2 1999/12/23 12:13:53 gniibe Exp gniibe $
#
# 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
@@ -15,21 +15,21 @@
#
# Select the object file format to substitute into the linker script.
#
-tool-prefix = sh-elf
+tool-prefix = sh-linux-gnu-
ifdef CONFIG_LITTLE_ENDIAN
CFLAGS += -ml
AFLAGS += -ml
# LINKFLAGS += -EL
LDFLAGS := -EL
-
-LD =$(CROSS_COMPILE)ld $(LDFLAGS)
-
endif
-ifdef CONFIG_CROSSCOMPILE
+# ifdef CONFIG_CROSSCOMPILE
CROSS_COMPILE = $(tool-prefix)
-endif
+# endif
+
+LD =$(CROSS_COMPILE)ld $(LDFLAGS)
+OBJCOPY=$(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
MODFLAGS +=
@@ -51,7 +51,7 @@ endif
# none has been choosen above.
#
LINKSCRIPT = arch/sh/vmlinux.lds
-LINKFLAGS += -T $(word 1,$(LINKSCRIPT)) -e __stext
+LINKFLAGS += -T $(word 1,$(LINKSCRIPT)) -e _stext
ifdef LOADADDR
LINKFLAGS += -Ttext $(word 1,$(LOADADDR))
@@ -73,7 +73,7 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
vmlinux: arch/sh/vmlinux.lds
arch/sh/vmlinux.lds: arch/sh/vmlinux.lds.S FORCE
- gcc -E -C -P -I$(HPATH) -Ush arch/sh/vmlinux.lds.S >arch/sh/vmlinux.lds
+ $(CPP) -C -P -I$(HPATH) -Ush arch/sh/vmlinux.lds.S >arch/sh/vmlinux.lds
FORCE: ;
diff --git a/arch/sh/boot/Makefile b/arch/sh/boot/Makefile
index e2ae36bde..8c087beb1 100644
--- a/arch/sh/boot/Makefile
+++ b/arch/sh/boot/Makefile
@@ -1,5 +1,5 @@
#
-# arch/mips/boot/Makefile
+# arch/sh/boot/Makefile
#
# 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
diff --git a/arch/sh/config.in b/arch/sh/config.in
index 6471e7aa8..8b74eeafa 100644
--- a/arch/sh/config.in
+++ b/arch/sh/config.in
@@ -4,6 +4,10 @@
#
mainmenu_name "Linux/SuperH Kernel Configuration"
+define_bool CONFIG_SUPERH 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
@@ -29,7 +33,6 @@ if [ "$CONFIG_CPU_SUBTYPE_SH7750" = "y" ]; then
fi
bool 'Little Endian' CONFIG_LITTLE_ENDIAN
hex 'Physical memory start address' CONFIG_MEMORY_START 08000000
-bool 'Use SH CPU internal real time clock' CONFIG_SH_CPU_RTC
endmenu
mainmenu_option next_comment
@@ -43,63 +46,139 @@ endmenu
mainmenu_option next_comment
comment 'General setup'
+
bool 'Networking support' CONFIG_NET
+
+bool 'Directy Connected Compact Flash support' CONFIG_CF_ENABLER
+
+bool 'PCI support' CONFIG_PCI
+if [ "$CONFIG_PCI" = "y" ]; then
+ choice ' PCI access mode' \
+ "BIOS CONFIG_PCI_GOBIOS \
+ Direct CONFIG_PCI_GODIRECT \
+ Any CONFIG_PCI_GOANY" Any
+ if [ "$CONFIG_PCI_GOBIOS" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
+ define_bool CONFIG_PCI_BIOS y
+ fi
+ if [ "$CONFIG_PCI_GODIRECT" = "y" -o "$CONFIG_PCI_GOANY" = "y" ]; then
+ define_bool CONFIG_PCI_DIRECT y
+ fi
+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 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
bool 'Sysctl support' CONFIG_SYSCTL
-
if [ "$CONFIG_PROC_FS" = "y" ]; then
choice 'Kernel core (/proc/kcore) format' \
"ELF CONFIG_KCORE_ELF \
A.OUT CONFIG_KCORE_AOUT" ELF
fi
-
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
-endmenu
-mainmenu_option next_comment
-comment 'Character devices'
-define_bool CONFIG_SERIAL n
-define_bool CONFIG_SERIAL_CONSOLE y
-bool 'SuperH SCI support' CONFIG_SH_SCI_SERIAL
-bool 'SuperH SCIF support' CONFIG_SH_SCIF_SERIAL
+source drivers/parport/Config.in
+
endmenu
-mainmenu_option next_comment
-comment 'Floppy, IDE, and other block devices'
+source drivers/block/Config.in
-tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
-if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then
- bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
+if [ "$CONFIG_NET" = "y" ]; then
+ source net/Config.in
fi
-tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
-tristate 'Network block device support' CONFIG_BLK_DEV_NBD
+mainmenu_option next_comment
+comment 'SCSI support'
+
+tristate 'SCSI support' CONFIG_SCSI
+
+if [ "$CONFIG_SCSI" != "n" ]; then
+ source drivers/scsi/Config.in
+fi
endmenu
+source drivers/ieee1394/Config.in
+
if [ "$CONFIG_NET" = "y" ]; then
- source net/Config.in
mainmenu_option next_comment
- comment 'Network device drivers'
+ comment 'Network device support'
+
+ bool 'Network device support' CONFIG_NETDEVICES
+ if [ "$CONFIG_NETDEVICES" = "y" ]; then
source drivers/net/Config.in
+ if [ "$CONFIG_ATM" = "y" ]; then
+ source drivers/atm/Config.in
+ fi
+ fi
endmenu
fi
mainmenu_option next_comment
+comment 'Character devices'
+
+bool 'Virtual terminal' CONFIG_VT
+if [ "$CONFIG_VT" = "y" ]; then
+ bool ' Support for console on virtual terminal' CONFIG_VT_CONSOLE
+fi
+
+tristate 'Serial support' CONFIG_SERIAL
+if [ "$CONFIG_SERIAL" = "y" -o "$CONFIG_SERIAL" = "m" ]; then
+ choice 'Serial interface type' \
+ "SCI CONFIG_SH_SCI_SERIAL \
+ SCIF CONFIG_SH_SCIF_SERIAL"
+fi
+if [ "$CONFIG_SERIAL" = "y" ]; then
+ bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE
+fi
comment 'Unix 98 PTY support'
bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS
if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then
int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
fi
+if [ "$CONFIG_PARPORT" != "n" ]; then
+ dep_tristate 'Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
+ if [ "$CONFIG_PRINTER" != "n" ]; then
+ bool ' Support for console on line printer' CONFIG_LP_CONSOLE
+ fi
+ dep_tristate 'Support for user-space parallel port device drivers' CONFIG_PPDEV $CONFIG_PARPORT
+fi
endmenu
+if [ "$CONFIG_HOTPLUG" = "y" -a "$CONFIG_PCMCIA" != "n" ]; then
+ source drivers/char/pcmcia/Config.in
+fi
+
+source drivers/misc/Config.in
+
source fs/Config.in
+if [ "$CONFIG_VT" = "y" ]; then
+ mainmenu_option next_comment
+ comment 'Console drivers'
+ bool 'VGA text console' CONFIG_VGA_CONSOLE
+ bool 'Video mode selection support' CONFIG_VIDEO_SELECT
+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ tristate 'MDA text console (dual-headed) (EXPERIMENTAL)' CONFIG_MDA_CONSOLE
+ source drivers/video/Config.in
+ fi
+ endmenu
+fi
+
+
mainmenu_option next_comment
-comment 'Watchdog'
+comment 'Sound'
-tristate 'Software watchdog' CONFIG_SOFT_WATCHDOG
+tristate 'Sound card support' CONFIG_SOUND
+if [ "$CONFIG_SOUND" != "n" ]; then
+ source drivers/sound/Config.in
+fi
endmenu
mainmenu_option next_comment
diff --git a/arch/sh/defconfig b/arch/sh/defconfig
index 37440e7c0..5fabcdedc 100644
--- a/arch/sh/defconfig
+++ b/arch/sh/defconfig
@@ -1,6 +1,8 @@
#
# Automatically generated make config: don't edit
#
+CONFIG_SUPERH=y
+CONFIG_UID16=y
#
# Code maturity level options
@@ -17,7 +19,6 @@ CONFIG_CPU_SH3=y
# CONFIG_CPU_SH4 is not set
CONFIG_LITTLE_ENDIAN=y
CONFIG_MEMORY_START=0c000000
-CONFIG_SH_CPU_RTC=y
#
# Loadable module support
@@ -28,6 +29,9 @@ CONFIG_SH_CPU_RTC=y
# General setup
#
# CONFIG_NET is not set
+CONFIG_CF_ENABLER=y
+# CONFIG_PCI is not set
+# CONFIG_HOTPLUG is not set
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_SYSCTL is not set
@@ -35,22 +39,56 @@ CONFIG_KCORE_ELF=y
# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
+# CONFIG_PARPORT is not set
#
-# Character devices
+# Block devices
#
-# CONFIG_SERIAL is not set
-CONFIG_SERIAL_CONSOLE=y
-CONFIG_SH_SCI_SERIAL=y
-# CONFIG_SH_SCIF_SERIAL is not set
+# CONFIG_BLK_DEV_FD is not set
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# 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
#
-# Floppy, IDE, and other block devices
+# IDE chipset support/bugfixes
#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_IDE_CHIPSETS is not set
+
+#
+# Additional Block Devices
+#
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_MD is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_LOOP is not set
-# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SH_SCI_SERIAL=y
+# CONFIG_SH_SCIF_SERIAL is not set
+CONFIG_SERIAL_CONSOLE=y
#
# Unix 98 PTY support
@@ -58,16 +96,20 @@ CONFIG_BLK_DEV_INITRD=y
# CONFIG_UNIX98_PTYS is not set
#
+# Misc devices
+#
+
+#
# Filesystems
#
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
# CONFIG_FAT_FS is not set
+# CONFIG_CRAMFS is not set
# CONFIG_ISO9660_FS is not set
# 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
@@ -75,6 +117,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
#
@@ -82,14 +125,12 @@ CONFIG_EXT2_FS=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-# CONFIG_SGI_PARTITION is not set
-# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
#
-# Watchdog
+# Sound
#
-# CONFIG_SOFT_WATCHDOG is not set
+# CONFIG_SOUND is not set
#
# Kernel hacking
diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile
index 6cf0b319e..efa2fb109 100644
--- a/arch/sh/kernel/Makefile
+++ b/arch/sh/kernel/Makefile
@@ -11,10 +11,19 @@
O_TARGET := kernel.o
O_OBJS := process.o signal.o entry.o traps.o irq.o irq_onchip.o \
- ptrace.o setup.o time.o sys_sh.o semaphore.o
+ ptrace.o setup.o time.o sys_sh.o semaphore.o pci-sh.o \
+ irq_imask.o
OX_OBJS := sh_ksyms.o
MX_OBJS :=
+ifdef CONFIG_CF_ENABLER
+O_OBJS += cf-enabler.o
+endif
+
+ifdef CONFIG_CPU_SH4
+O_OBJS += fpu.o
+endif
+
all: kernel.o head.o init_task.o
entry.o: entry.S
diff --git a/arch/sh/kernel/cf-enabler.c b/arch/sh/kernel/cf-enabler.c
new file mode 100644
index 000000000..80dc511b3
--- /dev/null
+++ b/arch/sh/kernel/cf-enabler.c
@@ -0,0 +1,30 @@
+/* $Id: cf-enabler.c,v 1.2 1999/12/20 10:14:40 gniibe Exp $
+ *
+ * linux/drivers/block/cf-enabler.c
+ *
+ * Copyright (C) 1999 Niibe Yutaka
+ *
+ * Enable the CF configuration.
+ */
+
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#define CF_CIS_BASE 0xb8000000
+/*
+ * 0xB8000000 : Attribute
+ * 0xB8001000 : Common Memory
+ * 0xBA000000 : I/O
+ */
+
+int __init cf_init(void)
+{
+ outw(0x0042, CF_CIS_BASE+0x0200);
+ make_imask_irq(14);
+ disable_irq(14);
+ return 0;
+}
+
+__initcall (cf_init);
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index a3e5a918c..77bb7938b 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -1,8 +1,8 @@
-/* $Id: entry.S,v 1.19 1999/10/31 13:19:35 gniibe Exp gniibe $
+/* $Id: entry.S,v 1.55 2000/03/05 01:48:58 gniibe Exp $
*
* linux/arch/sh/entry.S
*
- * Copyright (C) 1999 Niibe Yutaka
+ * Copyright (C) 1999, 2000 Niibe Yutaka
*
* 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
@@ -54,7 +54,8 @@ sigpending = 8
addr_limit = 12
need_resched = 20
-PF_TRACESYS = 0x20
+PF_TRACESYS = 0x00000020
+PF_USEDFPU = 0x00100000
ENOSYS = 38
@@ -207,37 +208,10 @@ error:
1: .long SYMBOL_NAME(do_exception_error)
2: .long 0xefffffff ! BL=0
-reschedule:
- mova SYMBOL_NAME(ret_from_syscall),r0
- mov.l 1f,r1
- jmp @r1
- lds r0,pr
- .balign 4
-1: .long SYMBOL_NAME(schedule)
-
badsys: mov #-ENOSYS,r0
rts ! go to ret_from_syscall..
mov.l r0,@(R0,r15)
-signal_return:
- ! We can reach here from an interrupt handler,
- ! so, we need to unblock interrupt.
- /* STI */
- mov.l 1f,r1
- stc sr,r0
- and r1,r0
- ldc r0,sr
- !
- mov r15,r4
- mov #0,r5
- mov.l 2f,r1
- mova restore_all,r0
- jmp @r1
- lds r0,pr
- .balign 4
-1: .long 0xefffffff ! BL=0
-2: .long SYMBOL_NAME(do_signal)
-
!
!
!
@@ -274,7 +248,7 @@ system_call:
ldc r2,sr
!
mov.l __n_sys,r1
- cmp/ge r1,r0
+ cmp/hs r1,r0
bt/s badsys
mov r0,r2
!
@@ -329,6 +303,9 @@ system_call:
3: .long SYMBOL_NAME(syscall_trace)
2: .long 0xefffffff ! BL=0
1: .long TRA
+__n_sys: .long NR_syscalls
+__sct: .long SYMBOL_NAME(sys_call_table)
+__tsk_flags: .long flags-8192 ! offset from stackbase to tsk->flags
led: .long 0xa8000000 ! For my board -- gN
.section .fixup,"ax"
@@ -343,30 +320,57 @@ fixup_syscall_argerr:
.long 8b,fixup_syscall_argerr
.previous
+reschedule:
+ mova SYMBOL_NAME(ret_from_syscall),r0
+ mov.l 1f,r1
+ jmp @r1
+ lds r0,pr
+ .balign 4
+1: .long SYMBOL_NAME(schedule)
ENTRY(ret_from_irq)
- mov.l @(SR,r15),r0 ! get original stack
+ mov.l @(SR,r15),r0 ! get status register
shll r0
shll r0 ! kernel space?
bt restore_all ! Yes, it's from kernel, go back soon
- ! XXX: Is it better to run through bottom half?
- ! In such a case, we should go "ret_from_syscall" instead
+ ! STI
+ mov.l 1f, $r1
+ stc $sr, $r2
+ and $r1, $r2
+ ldc $r2, $sr
+ !
bra ret_with_reschedule
nop
+ENTRY(ret_from_exception)
+ mov.l @(SR,r15),r0 ! get status register
+ shll r0
+ shll r0 ! kernel space?
+ bt restore_all ! Yes, it's from kernel, go back soon
+ ! STI
+ mov.l 1f, $r1
+ stc $sr, $r2
+ and $r1, $r2
+ ldc $r2, $sr
+ !
+ bra ret_from_syscall
+ nop
+ .balign 4
+1: .long 0xefffffff ! BL=0
+
+ .balign 4
ret: add r8,r15 ! pop off the arguments
mov.l r0,@(R0,r15) ! save the return value
/* fall through */
ENTRY(ret_from_syscall)
- mov.l __bh_mask,r0
+ mov.l __softirq_state,r0
mov.l @r0,r1
- mov.l __bh_active,r0
- mov.l @r0,r2
+ mov.l @(4,r0),r2
tst r2,r1
bt ret_with_reschedule
-handle_bottom_half:
- mov.l __dbh,r0
+handle_softirq:
+ mov.l __do_softirq,r0
jsr @r0
nop
ret_with_reschedule:
@@ -378,11 +382,44 @@ ret_with_reschedule:
bf reschedule
mov.l @(sigpending,r1),r0
tst #0xff,r0
- bf signal_return
- !
+ bt restore_all
+signal_return:
+ mov r15,r4
+ mov #0,r5
+ mov.l __do_signal,r1
+ mova restore_all,r0
+ jmp @r1
+ lds r0,pr
+ .balign 4
+__do_signal:
+ .long SYMBOL_NAME(do_signal)
+__softirq_state:
+ .long SYMBOL_NAME(softirq_state)
+__do_softirq:
+ .long SYMBOL_NAME(do_softirq)
+__minus8192:
+ .long -8192 ! offset from stackbase to tsk
+
+ .balign 4
restore_all:
- add #4,r15 ! skip syscall number
- mov.l @r15+,r11 ! SSR
+#if defined(__SH4__)
+ mov.l __fpu_prepare_fd, $r1
+ jsr @$r1
+ stc $sr, $r4
+#endif
+ add #4,r15 ! Skip syscall number
+ mov.l @r15+,r11 ! Got SSR into R11
+#if defined(__SH4__)
+ mov $r11, $r12
+#endif
+ !
+ mov.l 1f,r1
+ stc sr,r0
+ and r1,r0 ! Get IMASK+FD
+ mov.l 2f,r1
+ and r1,r11
+ or r0,r11 ! Inherit the IMASK+FD value of SR
+ !
mov.l @r15+,r10 ! original stack
mov.l @r15+,r0
mov.l @r15+,r1
@@ -398,6 +435,9 @@ restore_all:
ldc r14,sr ! here, change the register bank
mov r10,k0
mov r11,k1
+#if defined(__SH4__)
+ mov $r12, $k2
+#endif
mov.l @r15+,r8
mov.l @r15+,r9
mov.l @r15+,r10
@@ -410,21 +450,69 @@ restore_all:
lds.l @r15+,macl
lds.l @r15+,pr
ldc.l @r15+,spc
- mov k0,r15
ldc k1,ssr
+#if defined(__SH4__)
+ shll $k1
+ shll $k1
+ bf 9f ! user mode
+ /* Kernel to kernel transition */
+ mov.l 3f, $k1
+ tst $k1, $k2
+ bf 9f ! it hadn't FPU
+ ! Kernel to kernel and FPU was used
+ ! There's the case we don't get FPU now
+ stc $sr, $k2
+ tst $k1, $k2
+ bt 7f
+ ! We need to grab FPU here
+ xor $k1, $k2
+ ldc $k2, $sr ! Grab FPU
+ mov.l __init_task_flags, $k1
+ mov.l @$k1, $k2
+ mov.l __PF_USEDFPU, $k1
+ or $k1, $k2
+ mov.l __init_task_flags, $k1
+ mov.l $k2, @$k1 ! Set init_task.flags |= PF_USEDFPU
+ !
+ ! Restoring FPU...
+ !
+7: fmov.s @$r15+, $fr0
+ fmov.s @$r15+, $fr1
+ fmov.s @$r15+, $fr2
+ fmov.s @$r15+, $fr3
+ fmov.s @$r15+, $fr4
+ fmov.s @$r15+, $fr5
+ fmov.s @$r15+, $fr6
+ fmov.s @$r15+, $fr7
+ fmov.s @$r15+, $fr8
+ fmov.s @$r15+, $fr9
+ fmov.s @$r15+, $fr10
+ fmov.s @$r15+, $fr11
+ fmov.s @$r15+, $fr12
+ fmov.s @$r15+, $fr13
+ fmov.s @$r15+, $fr14
+ fmov.s @$r15+, $fr15
+ lds.l @$r15+, $fpscr
+ lds.l @$r15+, $fpul
+9:
+#endif
+ mov k0,r15
rte
nop
.balign 4
-__n_sys: .long NR_syscalls
-__sct: .long SYMBOL_NAME(sys_call_table)
-__bh_mask: .long SYMBOL_NAME(bh_mask)
-__bh_active: .long SYMBOL_NAME(bh_active)
-__dbh: .long SYMBOL_NAME(do_bottom_half)
__blrb_flags: .long 0x30000000
-__minus8192: .long -8192 ! offset from stackbase to tsk
-__tsk_flags: .long flags-8192 ! offset from stackbase to tsk->flags
-
+#if defined(__SH4__)
+__fpu_prepare_fd:
+ .long SYMBOL_NAME(fpu_prepare_fd)
+__init_task_flags:
+ .long SYMBOL_NAME(init_task_union)+4
+__PF_USEDFPU:
+ .long PF_USEDFPU
+#endif
+1: .long 0x000080f0 ! IMASK+FD
+2: .long 0xffff7f0f ! ~(IMASK+FD)
+3: .long 0x00008000 ! FD=1
! Exception Vector Base
!
@@ -441,43 +529,81 @@ general_exception:
bra handle_exception
mov.l @k2,k2
.balign 4
-2: .long SYMBOL_NAME(ret_from_syscall)
+2: .long SYMBOL_NAME(ret_from_exception)
1: .long EXPEVT
!
!
.balign 1024,0,1024
tlb_miss:
mov.l 1f,k2
- mov.l 3f,k3
+ mov.l 4f,k3
bra handle_exception
mov.l @k2,k2
!
.balign 512,0,512
interrupt:
mov.l 2f,k2
- mov.l 4f,k3
+ mov.l 3f,k3
bra handle_exception
mov.l @k2,k2
.balign 4
1: .long EXPEVT
2: .long INTEVT
-3: .long SYMBOL_NAME(ret_from_syscall)
-4: .long SYMBOL_NAME(ret_from_irq)
+3: .long SYMBOL_NAME(ret_from_irq)
+4: .long SYMBOL_NAME(ret_from_exception)
!
!
handle_exception:
- ! Using k0, k1 for scratch registers (r0_bank1, and r1_bank1),
+ ! Using k0, k1 for scratch registers (r0_bank1, r1_bank),
! save all registers onto stack.
!
stc ssr,k0 ! from kernel space?
shll k0 ! Check MD bit (bit30)
shll k0
- bt/s 1f ! it's from kernel to kernel transition
+#if defined(__SH4__)
+ bf/s 8f ! it's from user to kernel transition
+ mov $r15, $k0 ! save original stack to k0
+ /* Kernel to kernel transition */
+ mov.l 2f, $k1
+ stc $ssr, $k0
+ tst $k1, $k0
+ bf/s 9f ! FPU is not used
+ mov $r15, $k0 ! save original stack to k0
+ ! FPU is used, save FPU
+ ! /* XXX: Need to save another bank of FPU if all FPU feature is used */
+ ! /* Currently it's not the case for GCC (only udivsi3_i4, divsi3_i4) */
+ sts.l $fpul, @-$r15
+ sts.l $fpscr, @-$r15
+ fmov.s $fr15, @-$r15
+ fmov.s $fr14, @-$r15
+ fmov.s $fr13, @-$r15
+ fmov.s $fr12, @-$r15
+ fmov.s $fr11, @-$r15
+ fmov.s $fr10, @-$r15
+ fmov.s $fr9, @-$r15
+ fmov.s $fr8, @-$r15
+ fmov.s $fr7, @-$r15
+ fmov.s $fr6, @-$r15
+ fmov.s $fr5, @-$r15
+ fmov.s $fr4, @-$r15
+ fmov.s $fr3, @-$r15
+ fmov.s $fr2, @-$r15
+ fmov.s $fr1, @-$r15
+ fmov.s $fr0, @-$r15
+ bra 9f
+ mov #0, $k1
+#else
+ bt/s 9f ! it's from kernel to kernel transition
mov r15,k0 ! save original stack to k0 anyway
- mov kernel_sp,r15 ! change to kernel stack
-1: stc.l spc,@-r15
+#endif
+8: /* User space to kernel */
+ mov kernel_sp, $r15 ! change to kernel stack
+#if defined(__SH4__)
+ mov.l 2f, $k1 ! let kernel release FPU
+#endif
+9: stc.l spc,@-r15
sts.l pr,@-r15
!
lds k3,pr ! Set the return address to pr
@@ -487,9 +613,12 @@ handle_exception:
stc.l gbr,@-r15
mov.l r14,@-r15
!
- mov.l 2f,k1
- stc sr,r14 ! back to normal register bank, and
- and k1,r14 ! ..
+ stc sr,r14 ! Back to normal register bank, and
+#if defined(__SH4__)
+ or $k1, $r14 ! may release FPU
+#endif
+ mov.l 3f,k1
+ and k1,r14 ! ...
ldc r14,sr ! ...changed here.
!
mov.l r13,@-r15
@@ -520,7 +649,8 @@ handle_exception:
mov.l @r15,r0 ! recovering r0..
.balign 4
1: .long SYMBOL_NAME(exception_handling_table)
-2: .long 0xdfffffff ! RB=0, BL=1
+2: .long 0x00008000 ! FD=1
+3: .long 0xdfffffff ! RB=0, leave BL=1
none:
rts
@@ -537,7 +667,11 @@ ENTRY(exception_handling_table)
.long tlb_protection_violation_store
.long error ! address_error_load (filled by trap_init)
.long error ! address_error_store (filled by trap_init)
+#if defined(__SH4__)
+ .long SYMBOL_NAME(do_fpu_error)
+#else
.long error ! fpu_exception
+#endif
.long error
.long system_call ! Unconditional Trap
.long error ! reserved_instruction (filled by trap_init)
@@ -628,8 +762,8 @@ ENTRY(interrupt_table)
.long error
.long error
.long error
- .long error ! fpu
- .long error ! fpu
+ .long SYMBOL_NAME(do_fpu_state_restore)
+ .long SYMBOL_NAME(do_fpu_state_restore)
#endif
ENTRY(sys_call_table)
@@ -649,15 +783,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)
@@ -679,13 +813,13 @@ 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_umount) /* recycled never used phys() */
.long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */
.long SYMBOL_NAME(sys_ioctl)
.long SYMBOL_NAME(sys_fcntl) /* 55 */
@@ -703,19 +837,19 @@ 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)
.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_ni_syscall) /* old_select */
+ .long SYMBOL_NAME(sys_getgroups16) /* 80 */
+ .long SYMBOL_NAME(sys_setgroups16)
+ .long SYMBOL_NAME(sys_ni_syscall) /* sys_oldselect */
.long SYMBOL_NAME(sys_symlink)
.long SYMBOL_NAME(sys_lstat)
.long SYMBOL_NAME(sys_readlink) /* 85 */
@@ -723,18 +857,18 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_swapon)
.long SYMBOL_NAME(sys_reboot)
.long SYMBOL_NAME(old_readdir)
- .long SYMBOL_NAME(sys_mmap) /* 90 */
+ .long SYMBOL_NAME(old_mmap) /* 90 */
.long SYMBOL_NAME(sys_munmap)
.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 */
.long SYMBOL_NAME(sys_statfs)
.long SYMBOL_NAME(sys_fstatfs) /* 100 */
- .long SYMBOL_NAME(sys_ni_syscall) /* ioperm */
+ .long SYMBOL_NAME(sys_ni_syscall) /* ioperm */
.long SYMBOL_NAME(sys_socketcall)
.long SYMBOL_NAME(sys_syslog)
.long SYMBOL_NAME(sys_setitimer)
@@ -771,8 +905,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)
@@ -797,14 +931,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_ni_syscall) /* vm86 */
+ .long SYMBOL_NAME(sys_setresuid16)
+ .long SYMBOL_NAME(sys_getresuid16) /* 165 */
+ .long SYMBOL_NAME(sys_ni_syscall) /* 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)
@@ -815,15 +949,42 @@ 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 */
.long SYMBOL_NAME(sys_sigaltstack)
.long SYMBOL_NAME(sys_sendfile)
- .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
- .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
+ .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_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)
+ .long SYMBOL_NAME(sys_pivot_root)
/*
* NOTE!! This doesn't have to be exact - we just have
@@ -831,7 +992,7 @@ 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-190
+ .rept NR_syscalls-217
.long SYMBOL_NAME(sys_ni_syscall)
.endr
diff --git a/arch/sh/kernel/fpu.c b/arch/sh/kernel/fpu.c
new file mode 100644
index 000000000..335902c1d
--- /dev/null
+++ b/arch/sh/kernel/fpu.c
@@ -0,0 +1,266 @@
+/* $Id: fpu.c,v 1.27 2000/03/05 01:48:34 gniibe Exp $
+ *
+ * linux/arch/sh/kernel/fpu.c
+ *
+ * Save/restore floating point context for signal handlers.
+ *
+ * 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
+ * for more details.
+ *
+ * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka
+ *
+ * FIXME! These routines can be optimized in big endian case.
+ */
+
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <asm/processor.h>
+#include <asm/io.h>
+
+void
+save_fpu(struct task_struct *tsk)
+{
+ asm volatile("sts.l $fpul, @-%0\n\t"
+ "sts.l $fpscr, @-%0\n\t"
+ "frchg\n\t"
+ "fmov.s $fr15, @-%0\n\t"
+ "fmov.s $fr14, @-%0\n\t"
+ "fmov.s $fr13, @-%0\n\t"
+ "fmov.s $fr12, @-%0\n\t"
+ "fmov.s $fr11, @-%0\n\t"
+ "fmov.s $fr10, @-%0\n\t"
+ "fmov.s $fr9, @-%0\n\t"
+ "fmov.s $fr8, @-%0\n\t"
+ "fmov.s $fr7, @-%0\n\t"
+ "fmov.s $fr6, @-%0\n\t"
+ "fmov.s $fr5, @-%0\n\t"
+ "fmov.s $fr4, @-%0\n\t"
+ "fmov.s $fr3, @-%0\n\t"
+ "fmov.s $fr2, @-%0\n\t"
+ "fmov.s $fr1, @-%0\n\t"
+ "fmov.s $fr0, @-%0\n\t"
+ "frchg\n\t"
+ "fmov.s $fr15, @-%0\n\t"
+ "fmov.s $fr14, @-%0\n\t"
+ "fmov.s $fr13, @-%0\n\t"
+ "fmov.s $fr12, @-%0\n\t"
+ "fmov.s $fr11, @-%0\n\t"
+ "fmov.s $fr10, @-%0\n\t"
+ "fmov.s $fr9, @-%0\n\t"
+ "fmov.s $fr8, @-%0\n\t"
+ "fmov.s $fr7, @-%0\n\t"
+ "fmov.s $fr6, @-%0\n\t"
+ "fmov.s $fr5, @-%0\n\t"
+ "fmov.s $fr4, @-%0\n\t"
+ "fmov.s $fr3, @-%0\n\t"
+ "fmov.s $fr2, @-%0\n\t"
+ "fmov.s $fr1, @-%0\n\t"
+ "fmov.s $fr0, @-%0"
+ : /* no output */
+ : "r" ((char *)(&tsk->thread.fpu.hard.status))
+ : "memory");
+
+ tsk->flags &= ~PF_USEDFPU;
+ release_fpu();
+}
+
+static void
+restore_fpu(struct task_struct *tsk)
+{
+ asm volatile("fmov.s @%0+, $fr0\n\t"
+ "fmov.s @%0+, $fr1\n\t"
+ "fmov.s @%0+, $fr2\n\t"
+ "fmov.s @%0+, $fr3\n\t"
+ "fmov.s @%0+, $fr4\n\t"
+ "fmov.s @%0+, $fr5\n\t"
+ "fmov.s @%0+, $fr6\n\t"
+ "fmov.s @%0+, $fr7\n\t"
+ "fmov.s @%0+, $fr8\n\t"
+ "fmov.s @%0+, $fr9\n\t"
+ "fmov.s @%0+, $fr10\n\t"
+ "fmov.s @%0+, $fr11\n\t"
+ "fmov.s @%0+, $fr12\n\t"
+ "fmov.s @%0+, $fr13\n\t"
+ "fmov.s @%0+, $fr14\n\t"
+ "fmov.s @%0+, $fr15\n\t"
+ "frchg\n\t"
+ "fmov.s @%0+, $fr0\n\t"
+ "fmov.s @%0+, $fr1\n\t"
+ "fmov.s @%0+, $fr2\n\t"
+ "fmov.s @%0+, $fr3\n\t"
+ "fmov.s @%0+, $fr4\n\t"
+ "fmov.s @%0+, $fr5\n\t"
+ "fmov.s @%0+, $fr6\n\t"
+ "fmov.s @%0+, $fr7\n\t"
+ "fmov.s @%0+, $fr8\n\t"
+ "fmov.s @%0+, $fr9\n\t"
+ "fmov.s @%0+, $fr10\n\t"
+ "fmov.s @%0+, $fr11\n\t"
+ "fmov.s @%0+, $fr12\n\t"
+ "fmov.s @%0+, $fr13\n\t"
+ "fmov.s @%0+, $fr14\n\t"
+ "fmov.s @%0+, $fr15\n\t"
+ "frchg\n\t"
+ "lds.l @%0+, $fpscr\n\t"
+ "lds.l @%0+, $fpul\n\t"
+ : /* no output */
+ : "r" (&tsk->thread.fpu)
+ : "memory");
+}
+
+/*
+ * Load the FPU with signalling NANS. This bit pattern we're using
+ * has the property that no matter wether considered as single or as
+ * double precission represents signaling NANS.
+ */
+/* Double presision, NANS as NANS, rounding to nearest, no exceptions */
+#define FPU_DEFAULT 0x00080000
+
+void fpu_init(void)
+{
+ asm volatile("lds %0, $fpul\n\t"
+ "lds %1, $fpscr\n\t"
+ "fsts $fpul, $fr0\n\t"
+ "fsts $fpul, $fr1\n\t"
+ "fsts $fpul, $fr2\n\t"
+ "fsts $fpul, $fr3\n\t"
+ "fsts $fpul, $fr4\n\t"
+ "fsts $fpul, $fr5\n\t"
+ "fsts $fpul, $fr6\n\t"
+ "fsts $fpul, $fr7\n\t"
+ "fsts $fpul, $fr8\n\t"
+ "fsts $fpul, $fr9\n\t"
+ "fsts $fpul, $fr10\n\t"
+ "fsts $fpul, $fr11\n\t"
+ "fsts $fpul, $fr12\n\t"
+ "fsts $fpul, $fr13\n\t"
+ "fsts $fpul, $fr14\n\t"
+ "fsts $fpul, $fr15\n\t"
+ "frchg\n\t"
+ "fsts $fpul, $fr0\n\t"
+ "fsts $fpul, $fr1\n\t"
+ "fsts $fpul, $fr2\n\t"
+ "fsts $fpul, $fr3\n\t"
+ "fsts $fpul, $fr4\n\t"
+ "fsts $fpul, $fr5\n\t"
+ "fsts $fpul, $fr6\n\t"
+ "fsts $fpul, $fr7\n\t"
+ "fsts $fpul, $fr8\n\t"
+ "fsts $fpul, $fr9\n\t"
+ "fsts $fpul, $fr10\n\t"
+ "fsts $fpul, $fr11\n\t"
+ "fsts $fpul, $fr12\n\t"
+ "fsts $fpul, $fr13\n\t"
+ "fsts $fpul, $fr14\n\t"
+ "fsts $fpul, $fr15\n\t"
+ "frchg"
+ : /* no output */
+ : "r" (0), "r" (FPU_DEFAULT));
+}
+
+asmlinkage void
+do_fpu_error(unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7,
+ struct pt_regs regs)
+{
+ struct task_struct *tsk = current;
+
+ regs.syscall_nr = -1;
+ regs.pc += 2;
+
+ grab_fpu();
+ save_fpu(tsk);
+ tsk->thread.trap_no = 11;
+ tsk->thread.error_code = 0;
+ force_sig(SIGFPE, tsk);
+}
+
+asmlinkage void
+do_fpu_state_restore(unsigned long r4, unsigned long r5, unsigned long r6,
+ unsigned long r7, struct pt_regs regs)
+{
+ struct task_struct *tsk = current;
+
+ regs.syscall_nr = -1;
+
+ if (!user_mode(&regs)) {
+ if (tsk != &init_task) {
+ unlazy_fpu(tsk);
+ }
+ tsk = &init_task;
+ if (tsk->flags & PF_USEDFPU)
+ BUG();
+ }
+
+ grab_fpu();
+ if (tsk->used_math) {
+ /* Using the FPU again. */
+ restore_fpu(tsk);
+ } else {
+ /* First time FPU user. */
+ fpu_init();
+ tsk->used_math = 1;
+ }
+ tsk->flags |= PF_USEDFPU;
+ release_fpu();
+}
+
+/*
+ * Change current FD flag to set FD flag back to exception
+ */
+asmlinkage void
+fpu_prepare_fd(unsigned long sr, unsigned long r5, unsigned long r6,
+ unsigned long r7, struct pt_regs regs)
+{
+ __cli();
+ if (!user_mode(&regs)) {
+ if (init_task.flags & PF_USEDFPU)
+ grab_fpu();
+ else {
+ if (!(sr & SR_FD)) {
+ release_fpu();
+ BUG();
+ }
+ }
+ return;
+ }
+
+ if (sr & SR_FD) { /* Kernel doesn't grab FPU */
+ if (current->flags & PF_USEDFPU)
+ grab_fpu();
+ else {
+ if (init_task.flags & PF_USEDFPU) {
+ init_task.flags &= ~PF_USEDFPU;
+ BUG();
+ }
+ }
+ } else {
+ if (init_task.flags & PF_USEDFPU)
+ save_fpu(&init_task);
+ else {
+ release_fpu();
+ BUG();
+ }
+ }
+}
+
+/* Short cut for the FPU exception */
+asmlinkage void
+enable_fpu_in_danger(void)
+{
+ struct task_struct *tsk = current;
+
+ if (tsk != &init_task)
+ unlazy_fpu(tsk);
+
+ tsk = &init_task;
+ if (tsk->used_math) {
+ /* Using the FPU again. */
+ restore_fpu(tsk);
+ } else {
+ /* First time FPU user. */
+ fpu_init();
+ tsk->used_math = 1;
+ }
+ tsk->flags |= PF_USEDFPU;
+}
diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S
index f6378927e..3f938557a 100644
--- a/arch/sh/kernel/head.S
+++ b/arch/sh/kernel/head.S
@@ -1,8 +1,8 @@
-/* $Id: head.S,v 1.7 1999/10/27 09:41:42 gniibe Exp gniibe $
+/* $Id: head.S,v 1.16 2000/03/02 00:01:15 gniibe Exp $
*
* arch/sh/kernel/head.S
*
- * Copyright (C) 1999 Niibe Yutaka & Kaz Kojima
+ * Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
*
* 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
@@ -34,49 +34,37 @@ ENTRY(empty_zero_page)
* Cache may or may not be initialized.
* Hardware (including on-chip modules) may or may not be initialized.
*
- * The register R4&R5 holds the address of the parameter block, which has
- * command-line data, etc.
- *
*/
ENTRY(_stext)
-#if defined(__SH4__)
- ! Initialize FPSCR
- /* GCC (as of 2.95.1) assumes FPU with double precision mode. */
- mov.l 7f,r0
- lds r0,fpscr
-#endif
! Initialize Status Register
- mov.l 1f,r0 ! MD=1, RB=0, BL=1
- ldc r0,sr
+ mov.l 1f, $r0 ! MD=1, RB=0, BL=1
+ ldc $r0, $sr
!
- mov.l 2f,r0
- mov r0,r15 ! Set initial r15 (stack pointer)
- ldc r0,r4_bank ! and stack base
+ mov.l 2f, $r0
+ mov $r0, $r15 ! Set initial r15 (stack pointer)
+ ldc $r0, $r4_bank ! and stack base
!
! Enable cache
- mov.l 6f,r0
- jsr @r0
+ mov.l 6f, $r0
+ jsr @$r0
nop
! Clear BSS area
- mov.l 3f,r1
- add #4,r1
- mov.l 4f,r2
- mov #0,r0
-9: cmp/hs r2,r1
+ mov.l 3f, $r1
+ add #4, $r1
+ mov.l 4f, $r2
+ mov #0, $r0
+9: cmp/hs $r2, $r1
bf/s 9b ! while (r1 < r2)
- mov.l r0,@-r2
+ mov.l $r0,@-$r2
! Start kernel
- mov.l 5f,r0
- jmp @r0
+ mov.l 5f, $r0
+ jmp @$r0
nop
.balign 4
-1: .long 0x50000000 ! MD=1, RB=0, BL=1
+1: .long 0x50000000 ! MD=1, RB=0, BL=1, FD=0
2: .long SYMBOL_NAME(stack)
3: .long SYMBOL_NAME(__bss_start)
4: .long SYMBOL_NAME(_end)
5: .long SYMBOL_NAME(start_kernel)
6: .long SYMBOL_NAME(cache_init)
-#if defined(__SH4__)
-7: .long 0x00080000
-#endif
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index e87972c73..a15352389 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.4 1999/10/11 13:12:14 gniibe Exp $
+/* $Id: irq.c,v 1.11 2000/02/29 11:03:40 gniibe Exp $
*
* linux/arch/sh/kernel/irq.c
*
@@ -31,7 +31,7 @@
#include <asm/io.h>
#include <asm/bitops.h>
#include <asm/smp.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/delay.h>
#include <asm/irq.h>
#include <linux/irq.h>
@@ -49,7 +49,8 @@ spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
/*
* Controller mappings for all interrupt sources:
*/
-irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { [0 ... NR_IRQS-1] = { 0, &no_irq_type, }};
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned =
+ { [0 ... NR_IRQS-1] = { 0, &no_irq_type, }};
/*
* Special irq handlers.
@@ -112,9 +113,8 @@ int get_irq_list(char *buf)
p += sprintf(p, " %14s", irq_desc[i].handler->typename);
p += sprintf(p, " %s", action->name);
- for (action=action->next; action; action = action->next) {
+ for (action=action->next; action; action = action->next)
p += sprintf(p, ", %s", action->name);
- }
*p++ = '\n';
}
return p - buf;
@@ -248,7 +248,7 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
kstat.irqs[cpu][irq]++;
desc = irq_desc + irq;
spin_lock(&irq_controller_lock);
- irq_desc[irq].handler->ack(irq);
+ desc->handler->ack(irq);
/*
REPLAY is when Linux resends an IRQ that was dropped earlier
WAITING is used by probe to mark irqs that are being tested
@@ -298,21 +298,15 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
spin_unlock(&irq_controller_lock);
}
desc->status &= ~IRQ_INPROGRESS;
- if (!(desc->status & IRQ_DISABLED)){
- irq_desc[irq].handler->end(irq);
- }
+ if (!(desc->status & IRQ_DISABLED))
+ desc->handler->end(irq);
spin_unlock(&irq_controller_lock);
- /*
- * This should be conditional: we should really get
- * a return code from the irq handler to tell us
- * whether the handler wants us to do software bottom
- * half handling or not..
- */
- if (1) {
- if (bh_active & bh_mask)
- do_bottom_half();
- }
+#if 1
+ __sti();
+#endif
+ if (softirq_state[cpu].active&softirq_state[cpu].mask)
+ do_softirq();
return 1;
}
@@ -347,7 +341,7 @@ int request_irq(unsigned int irq,
kfree(action);
return retval;
}
-
+
void free_irq(unsigned int irq, void *dev_id)
{
struct irqaction **p;
@@ -373,10 +367,6 @@ void free_irq(unsigned int irq, void *dev_id)
irq_desc[irq].handler->shutdown(irq);
}
spin_unlock_irqrestore(&irq_controller_lock,flags);
-
- /* Wait to make sure it's not being used on another CPU */
- while (irq_desc[irq].status & IRQ_INPROGRESS)
- barrier();
kfree(action);
return;
}
@@ -398,6 +388,7 @@ unsigned long probe_irq_on(void)
{
unsigned int i;
unsigned long delay;
+ unsigned long val;
/*
* first, enable any unassigned irqs
@@ -421,6 +412,7 @@ unsigned long probe_irq_on(void)
/*
* Now filter out any obviously spurious interrupts
*/
+ val = 0;
spin_lock_irq(&irq_controller_lock);
for (i=0; i<NR_IRQS; i++) {
unsigned int status = irq_desc[i].status;
@@ -433,19 +425,19 @@ unsigned long probe_irq_on(void)
irq_desc[i].status = status & ~IRQ_AUTODETECT;
irq_desc[i].handler->shutdown(i);
}
+
+ if (i < 32)
+ val |= 1 << i;
}
spin_unlock_irq(&irq_controller_lock);
- return 0x12345678;
+ return val;
}
-int probe_irq_off(unsigned long unused)
+int probe_irq_off(unsigned long val)
{
int i, irq_found, nr_irqs;
- if (unused != 0x12345678)
- printk("Bad IRQ probe from %lx\n", (&unused)[-1]);
-
nr_irqs = 0;
irq_found = 0;
spin_lock_irq(&irq_controller_lock);
diff --git a/arch/sh/kernel/irq_imask.c b/arch/sh/kernel/irq_imask.c
new file mode 100644
index 000000000..a3cf78b5f
--- /dev/null
+++ b/arch/sh/kernel/irq_imask.c
@@ -0,0 +1,106 @@
+/* $Id: irq_imask.c,v 1.2 2000/02/11 04:57:40 gniibe Exp $
+ *
+ * linux/arch/sh/kernel/irq_imask.c
+ *
+ * Copyright (C) 1999 Niibe Yutaka
+ *
+ * Simple interrupt handling using IMASK of SR register.
+ *
+ */
+
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+
+#include <linux/spinlock.h>
+#include <linux/cache.h>
+#include <linux/irq.h>
+
+/* Bitmap of IRQ masked */
+static unsigned long imask_mask = 0x7fff;
+static int interrupt_priority = 0;
+
+static void enable_imask_irq(unsigned int irq);
+static void disable_imask_irq(unsigned int irq);
+static void shutdown_imask_irq(unsigned int irq);
+static void mask_and_ack_imask(unsigned int);
+static void end_imask_irq(unsigned int irq);
+
+#define IMASK_PRIORITY 15
+
+static unsigned int startup_imask_irq(unsigned int irq)
+{
+ enable_imask_irq(irq);
+ return 0; /* never anything pending */
+}
+
+static struct hw_interrupt_type imask_irq_type = {
+ "Interrupt using IMASK of SR register",
+ startup_imask_irq,
+ shutdown_imask_irq,
+ enable_imask_irq,
+ disable_imask_irq,
+ mask_and_ack_imask,
+ end_imask_irq
+};
+
+void disable_imask_irq(unsigned int irq)
+{
+ unsigned long __dummy;
+
+ clear_bit(irq, &imask_mask);
+ if (interrupt_priority < IMASK_PRIORITY - irq)
+ interrupt_priority = IMASK_PRIORITY - irq;
+
+ asm volatile("stc sr,%0\n\t"
+ "and %1,%0\n\t"
+ "or %2,%0\n\t"
+ "ldc %0,sr"
+ : "=&r" (__dummy)
+ : "r" (0xffffff0f), "r" (interrupt_priority << 4));
+}
+
+static void enable_imask_irq(unsigned int irq)
+{
+ unsigned long __dummy;
+
+ set_bit(irq, &imask_mask);
+ interrupt_priority = IMASK_PRIORITY - ffz(imask_mask);
+
+ asm volatile("stc sr,%0\n\t"
+ "and %1,%0\n\t"
+ "or %2,%0\n\t"
+ "ldc %0,sr"
+ : "=&r" (__dummy)
+ : "r" (0xffffff0f), "r" (interrupt_priority << 4));
+}
+
+static void mask_and_ack_imask(unsigned int irq)
+{
+ disable_imask_irq(irq);
+}
+
+static void end_imask_irq(unsigned int irq)
+{
+ enable_imask_irq(irq);
+}
+
+static void shutdown_imask_irq(unsigned int irq)
+{
+ disable_imask_irq(irq);
+}
+
+void make_imask_irq(unsigned int irq)
+{
+ disable_irq_nosync(irq);
+ irq_desc[irq].handler = &imask_irq_type;
+ enable_irq(irq);
+}
diff --git a/arch/sh/kernel/irq_onchip.c b/arch/sh/kernel/irq_onchip.c
index cd28d2a59..10c48fd38 100644
--- a/arch/sh/kernel/irq_onchip.c
+++ b/arch/sh/kernel/irq_onchip.c
@@ -1,4 +1,4 @@
-/* $Id: irq_onchip.c,v 1.5 1999/10/28 02:18:33 gniibe Exp $
+/* $Id: irq_onchip.c,v 1.7 2000-01-09 15:55:55+09 gniibe Exp $
*
* linux/arch/sh/kernel/irq_onchip.c
*
@@ -143,7 +143,18 @@ static void end_onChip_irq(unsigned int irq)
*/
#define INTC_IRR0 0xa4000004UL
-#define INTC_IPRC 0xa4000016UL
+#define INTC_IRR1 0xa4000006UL
+#define INTC_IRR2 0xa4000008UL
+
+#define INTC_ICR0 0xfffffee0
+#define INTC_ICR1 0xa4000010
+#define INTC_ICR2 0xa4000012
+#define INTC_INTER 0xa4000014
+#define INTC_IPRA 0xfffffee2
+#define INTC_IPRB 0xfffffee4
+#define INTC_IPRC 0xa4000016
+#define INTC_IPRD 0xa4000018
+#define INTC_IPRE 0xa400001a
#define IRQ0_IRQ 32
#define IRQ1_IRQ 33
@@ -248,6 +259,26 @@ void __init init_IRQ(void)
}
#ifdef CONFIG_CPU_SUBTYPE_SH7709
+
+ /*
+ * Initialize the Interrupt Controller (INTC)
+ * registers to their power on values
+ */
+
+ ctrl_outb(0, INTC_IRR0);
+ ctrl_outb(0, INTC_IRR1);
+ ctrl_outb(0, INTC_IRR2);
+
+ ctrl_outw(0, INTC_ICR0);
+ ctrl_outw(0, INTC_ICR1);
+ ctrl_outw(0, INTC_ICR2);
+ ctrl_outw(0, INTC_INTER);
+ ctrl_outw(0, INTC_IPRA);
+ ctrl_outw(0, INTC_IPRB);
+ ctrl_outw(0, INTC_IPRC);
+ ctrl_outw(0, INTC_IPRD);
+ ctrl_outw(0, INTC_IPRE);
+
for (i = IRQ0_IRQ; i < NR_IRQS; i++) {
irq_desc[i].handler = &onChip2_irq_type;
}
@@ -263,8 +294,5 @@ void __init init_IRQ(void)
set_ipr_data(IRQ3_IRQ, IRQ3_IRP_OFFSET, IRQ3_PRIORITY);
set_ipr_data(IRQ4_IRQ, IRQ4_IRP_OFFSET, IRQ4_PRIORITY);
set_ipr_data(IRQ5_IRQ, IRQ5_IRP_OFFSET, IRQ5_PRIORITY);
-
- ctrl_inb(INTC_IRR0);
- ctrl_outb(0, INTC_IRR0);
#endif /* CONFIG_CPU_SUBTYPE_SH7709 */
}
diff --git a/arch/sh/kernel/pci-sh.c b/arch/sh/kernel/pci-sh.c
new file mode 100644
index 000000000..3613596f7
--- /dev/null
+++ b/arch/sh/kernel/pci-sh.c
@@ -0,0 +1,12 @@
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/errno.h>
+
+unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
+ unsigned long start, unsigned long size)
+{
+ return start;
+}
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 5d2a5696c..2ca91cb40 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -1,10 +1,10 @@
-/* $Id: process.c,v 1.8 1999/10/31 13:19:16 gniibe Exp $
+/* $Id: process.c,v 1.28 2000/03/05 02:16:15 gniibe Exp $
*
* linux/arch/sh/kernel/process.c
*
* Copyright (C) 1995 Linus Torvalds
*
- * SuperH version: Copyright (C) 1999 Niibe Yutaka & Kaz Kojima
+ * SuperH version: Copyright (C) 1999, 2000 Niibe Yutaka & Kaz Kojima
*/
/*
@@ -42,10 +42,6 @@
#include <linux/irq.h>
-#if defined(__SH4__)
-struct task_struct *last_task_used_math = NULL;
-#endif
-
static int hlt_counter=0;
#define HARD_IDLE_TIMEOUT (HZ / 3)
@@ -140,25 +136,25 @@ void free_task_struct(struct task_struct *p)
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{ /* Don't use this in BL=1(cli). Or else, CPU resets! */
- register unsigned long __sc0 __asm__ ("r0") = __NR_clone;
- register unsigned long __sc4 __asm__ ("r4") = (long) flags | CLONE_VM;
- register unsigned long __sc5 __asm__ ("r5") = 0;
- register unsigned long __sc8 __asm__ ("r8") = (long) arg;
- register unsigned long __sc9 __asm__ ("r9") = (long) fn;
- __asm__ __volatile__(
- "trapa #0\n\t" /* Linux/SH system call */
- "tst #0xff,r0\n\t" /* child or parent? */
+ register unsigned long __sc0 __asm__ ("$r0") = __NR_clone;
+ register unsigned long __sc4 __asm__ ("$r4") = (long) flags | CLONE_VM;
+ register unsigned long __sc5 __asm__ ("$r5") = 0;
+ register unsigned long __sc8 __asm__ ("$r8") = (long) arg;
+ register unsigned long __sc9 __asm__ ("$r9") = (long) fn;
+
+ __asm__("trapa #0\n\t" /* Linux/SH system call */
+ "tst #0xff, $r0\n\t" /* child or parent? */
"bf 1f\n\t" /* parent - jump */
- "jsr @r9\n\t" /* call fn */
- " mov r8,r4\n\t" /* push argument */
- "mov r0,r4\n\t" /* return value to arg of exit */
- "mov %2,r0\n\t" /* exit */
+ "jsr @$r9\n\t" /* call fn */
+ " mov $r8, $r4\n\t" /* push argument */
+ "mov $r0, $r4\n\t" /* return value to arg of exit */
+ "mov %2, $r0\n\t" /* exit */
"trapa #0\n"
"1:"
- :"=z" (__sc0)
- :"0" (__sc0), "i" (__NR_exit),
- "r" (__sc4), "r" (__sc5), "r" (__sc8), "r" (__sc9)
- :"memory");
+ : "=z" (__sc0)
+ : "0" (__sc0), "i" (__NR_exit),
+ "r" (__sc4), "r" (__sc5), "r" (__sc8), "r" (__sc9)
+ : "memory");
return __sc0;
}
@@ -167,18 +163,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
*/
void exit_thread(void)
{
-#if defined(__sh3__)
- /* nothing to do ... */
-#elif defined(__SH4__)
-#if 0 /* for the time being... */
- /* Forget lazy fpu state */
- if (last_task_used_math == current) {
- set_status_register (SR_FD, 0);
- write_system_register (fpscr, FPSCR_PR);
- last_task_used_math = NULL;
- }
-#endif
-#endif
+ /* Nothing to do. */
}
void flush_thread(void)
@@ -187,14 +172,11 @@ void flush_thread(void)
/* do nothing */
/* Possibly, set clear debug registers */
#elif defined(__SH4__)
-#if 0 /* for the time being... */
- /* Forget lazy fpu state */
- if (last_task_used_math == current) {
- set_status_register (SR_FD, 0);
- write_system_register (fpscr, FPSCR_PR);
- last_task_used_math = NULL;
- }
-#endif
+ struct task_struct *tsk = current;
+
+ /* Forget lazy FPU state */
+ clear_fpu(tsk);
+ tsk->used_math = 0;
#endif
}
@@ -204,18 +186,22 @@ void release_thread(struct task_struct *dead_task)
}
/* Fill in the fpu structure for a core dump.. */
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r)
+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
{
#if defined(__SH4__)
-#if 0 /* for the time being... */
- /* We store the FPU info in the task->thread area. */
- if (! (regs->sr & SR_FD)) {
- memcpy (r, &current->thread.fpu, sizeof (*r));
- return 1;
- }
-#endif
-#endif
+ int fpvalid;
+ struct task_struct *tsk = current;
+
+ fpvalid = tsk->used_math;
+ if (fpvalid) {
+ unlazy_fpu(tsk);
+ memcpy(fpu, &tsk->thread.fpu.hard, sizeof(*fpu));
+ }
+
+ return fpvalid;
+#else
return 0; /* Task didn't use the fpu at all. */
+#endif
}
asmlinkage void ret_from_fork(void);
@@ -224,21 +210,17 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
struct task_struct *p, struct pt_regs *regs)
{
struct pt_regs *childregs;
+ struct task_struct *tsk = current;
childregs = ((struct pt_regs *)(THREAD_SIZE + (unsigned long) p)) - 1;
- *childregs = *regs;
+ struct_cpy(childregs, regs);
#if defined(__SH4__)
-#if 0 /* for the time being... */
- if (last_task_used_math == current) {
- set_status_register (SR_FD, 0);
- sh4_save_fp (p);
+ if (tsk != &init_task) {
+ unlazy_fpu(tsk);
+ struct_cpy(&p->thread.fpu, &current->thread.fpu);
+ p->used_math = tsk->used_math;
}
- /* New tasks loose permission to use the fpu. This accelerates context
- switching for most programs since they don't use the fpu. */
- p->thread.sr = (read_control_register (sr) &~ SR_MD) | SR_FD;
- childregs->sr |= SR_FD;
-#endif
#endif
if (user_mode(regs)) {
childregs->sp = usp;
@@ -246,6 +228,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
childregs->sp = (unsigned long)p+2*PAGE_SIZE;
}
childregs->regs[0] = 0; /* Set return value for child */
+ childregs->sr |= SR_FD; /* Invalidate FPU flag */
p->thread.sp = (unsigned long) childregs;
p->thread.pc = (unsigned long) ret_from_fork;
@@ -258,7 +241,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
-/* changed the size calculations - should hopefully work better. lbt */
dump->magic = CMAGIC;
dump->start_code = current->mm->start_code;
dump->start_data = current->mm->start_data;
@@ -271,11 +253,7 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
dump->regs = *regs;
-#if 0 /* defined(__SH4__) */
- /* FPU */
- memcpy (&dump->regs[EF_SIZE/4], &current->thread.fpu,
- sizeof (current->thread.fpu));
-#endif
+ dump->u_fpvalid = dump_fpu(regs, &dump->fpu);
}
/*
@@ -284,11 +262,15 @@ void dump_thread(struct pt_regs * regs, struct user * dump)
*/
void __switch_to(struct task_struct *prev, struct task_struct *next)
{
+#if defined(__SH4__)
+ if (prev != &init_task)
+ unlazy_fpu(prev);
+#endif
/*
* Restore the kernel stack onto kernel mode register
* k4 (r4_bank1)
*/
- asm volatile("ldc %0,r4_bank"
+ asm volatile("ldc %0, $r4_bank"
: /* no output */
:"r" ((unsigned long)next+8192));
}
@@ -341,6 +323,7 @@ asmlinkage int sys_execve(char *ufilename, char **uargv,
error = PTR_ERR(filename);
if (IS_ERR(filename))
goto out;
+
error = do_execve(filename, uargv, uenvp, &regs);
if (error == 0)
current->flags &= ~PF_DTRACE;
@@ -349,3 +332,41 @@ out:
unlock_kernel();
return error;
}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched ((unsigned long) scheduling_functions_start_here)
+#define last_sched ((unsigned long) scheduling_functions_end_here)
+
+unsigned long get_wchan(struct task_struct *p)
+{
+ unsigned long schedule_frame;
+ unsigned long pc;
+
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
+ /*
+ * The same comment as on the Alpha applies here, too ...
+ */
+ pc = thread_saved_pc(&p->thread);
+ if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) {
+ schedule_frame = ((unsigned long *)(long)p->thread.sp)[1];
+ return (unsigned long)((unsigned long *)schedule_frame)[1];
+ }
+ return pc;
+}
+
+asmlinkage void print_syscall(int x)
+{
+ unsigned long flags, sr;
+ asm("stc $sr, %0": "=r" (sr));
+ save_and_cli(flags);
+ printk("%c: %c %c, %c: SYSCALL\n", (x&63)+32,
+ (current->flags&PF_USEDFPU)?'C':' ',
+ (init_task.flags&PF_USEDFPU)?'K':' ', (sr&SR_FD)?' ':'F');
+ restore_flags(flags);
+}
diff --git a/arch/sh/kernel/semaphore.c b/arch/sh/kernel/semaphore.c
index b9f565dd8..c958745b5 100644
--- a/arch/sh/kernel/semaphore.c
+++ b/arch/sh/kernel/semaphore.c
@@ -8,6 +8,8 @@
*/
#include <linux/sched.h>
+#include <linux/wait.h>
+#include <asm/semaphore.h>
#include <asm/semaphore-helper.h>
/*
@@ -131,3 +133,162 @@ int __down_trylock(struct semaphore * sem)
{
return waking_non_zero_trylock(sem);
}
+
+/* Called when someone has done an up that transitioned from
+ * negative to non-negative, meaning that the lock has been
+ * granted to whomever owned the bias.
+ */
+struct rw_semaphore *rwsem_wake_readers(struct rw_semaphore *sem)
+{
+ if (xchg(&sem->read_bias_granted, 1))
+ BUG();
+ wake_up(&sem->wait);
+ return sem;
+}
+
+struct rw_semaphore *rwsem_wake_writer(struct rw_semaphore *sem)
+{
+ if (xchg(&sem->write_bias_granted, 1))
+ BUG();
+ wake_up(&sem->write_bias_wait);
+ return sem;
+}
+
+struct rw_semaphore * __rwsem_wake(struct rw_semaphore *sem)
+{
+ if (atomic_read(&sem->count) == 0)
+ return rwsem_wake_writer(sem);
+ else
+ return rwsem_wake_readers(sem);
+}
+
+struct rw_semaphore *down_read_failed_biased(struct rw_semaphore *sem)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ add_wait_queue(&sem->wait, &wait); /* put ourselves at the head of the list */
+
+ for (;;) {
+ if (sem->read_bias_granted && xchg(&sem->read_bias_granted, 0))
+ break;
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ if (!sem->read_bias_granted)
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ return sem;
+}
+
+struct rw_semaphore *down_write_failed_biased(struct rw_semaphore *sem)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ add_wait_queue_exclusive(&sem->write_bias_wait, &wait); /* put ourselves at the end of the list */
+
+ for (;;) {
+ if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0))
+ break;
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE);
+ if (!sem->write_bias_granted)
+ schedule();
+ }
+
+ remove_wait_queue(&sem->write_bias_wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ /* if the lock is currently unbiased, awaken the sleepers
+ * FIXME: this wakes up the readers early in a bit of a
+ * stampede -> bad!
+ */
+ if (atomic_read(&sem->count) >= 0)
+ wake_up(&sem->wait);
+
+ return sem;
+}
+
+/* Wait for the lock to become unbiased. Readers
+ * are non-exclusive. =)
+ */
+struct rw_semaphore *down_read_failed(struct rw_semaphore *sem)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ __up_read(sem); /* this takes care of granting the lock */
+
+ add_wait_queue(&sem->wait, &wait);
+
+ while (atomic_read(&sem->count) < 0) {
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ if (atomic_read(&sem->count) >= 0)
+ break;
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ return sem;
+}
+
+/* Wait for the lock to become unbiased. Since we're
+ * a writer, we'll make ourselves exclusive.
+ */
+struct rw_semaphore *down_write_failed(struct rw_semaphore *sem)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ __up_write(sem); /* this takes care of granting the lock */
+
+ add_wait_queue_exclusive(&sem->wait, &wait);
+
+ while (atomic_read(&sem->count) < 0) {
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE);
+ if (atomic_read(&sem->count) >= 0)
+ break; /* we must attempt to aquire or bias the lock */
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ return sem;
+}
+
+struct rw_semaphore *__down_read(struct rw_semaphore *sem, int carry)
+{
+ if (carry) {
+ int saved, new;
+
+ do {
+ down_read_failed(sem);
+ saved = atomic_read(&sem->count);
+ if ((new = atomic_dec_return(&sem->count)) >= 0)
+ return sem;
+ } while (!(new < 0 && saved >=0));
+ }
+
+ return down_read_failed_biased(sem);
+}
+
+struct rw_semaphore *__down_write(struct rw_semaphore *sem, int carry)
+{
+ if (carry) {
+ int saved, new;
+
+ do {
+ down_write_failed(sem);
+ saved = atomic_read(&sem->count);
+ if ((new = atomic_sub_return(RW_LOCK_BIAS, &sem->count) ) == 0)
+ return sem;
+ } while (!(new < 0 && saved >=0));
+ }
+
+ return down_write_failed_biased(sem);
+}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index f97e66585..154283571 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.7 1999/10/23 01:34:50 gniibe Exp gniibe $
+/* $Id: setup.c,v 1.20 2000/03/05 02:44:41 gniibe Exp $
*
* linux/arch/sh/kernel/setup.c
*
@@ -51,6 +51,7 @@ extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
extern int rd_image_start; /* starting block # of image */
#endif
+extern void fpu_init(void);
extern int root_mountflags;
extern int _text, _etext, _edata, _end;
@@ -196,82 +197,82 @@ void __init setup_arch(char **cmdline_p)
#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
/*
- * partially used pages are not usable - thus
- * we are rounding upwards:
- */
- start_pfn = PFN_UP(__pa(&_end)-__MEMORY_START);
-
- /*
* Find the highest page frame number we have available
*/
- max_pfn = PFN_DOWN(__pa(memory_end)-__MEMORY_START);
+ max_pfn = PFN_DOWN(__pa(memory_end));
/*
* Determine low and high memory ranges:
*/
max_low_pfn = max_pfn;
+ /*
+ * Partially used pages are not usable - thus
+ * we are rounding upwards:
+ */
+ start_pfn = PFN_UP(__pa(&_end));
/*
- * Initialize the boot-time allocator (with low memory only):
- */
- bootmap_size = init_bootmem(start_pfn, max_low_pfn, __MEMORY_START);
-
- /*
- * FIXME: what about high memory?
+ * Find a proper area for the bootmem bitmap. After this
+ * bootstrap step all allocations (until the page allocator
+ * is intact) must be done via bootmem_alloc().
*/
- ram_resources[1].end = PFN_PHYS(max_low_pfn) + __MEMORY_START;
+ bootmap_size = init_bootmem_node(0, start_pfn,
+ __MEMORY_START>>PAGE_SHIFT,
+ max_low_pfn);
/*
* Register fully available low RAM pages with the bootmem allocator.
*/
{
- unsigned long curr_pfn, last_pfn, size;
+ unsigned long curr_pfn, last_pfn, pages;
/*
* We are rounding up the start address of usable memory:
*/
- curr_pfn = PFN_UP(0);
+ curr_pfn = PFN_UP(__MEMORY_START);
/*
* ... and at the end of the usable range downwards:
*/
- last_pfn = PFN_DOWN(memory_end-__MEMORY_START);
+ last_pfn = PFN_DOWN(__pa(memory_end));
if (last_pfn > max_low_pfn)
last_pfn = max_low_pfn;
- size = last_pfn - curr_pfn;
- free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
+ pages = last_pfn - curr_pfn;
+ free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(pages));
}
+
/*
* Reserve the kernel text and
- * Reserve the bootmem bitmap itself as well. We do this in two
- * steps (first step was init_bootmem()) because this catches
- * the (very unlikely) case of us accidentally initializing the
- * bootmem allocator with an invalid RAM area.
+ * Reserve the bootmem bitmap.We do this in two steps (first step
+ * was init_bootmem()), because this catches the (definitely buggy)
+ * case of us accidentally initializing the bootmem allocator with
+ * an invalid RAM area.
*/
- reserve_bootmem(PAGE_SIZE, PFN_PHYS(start_pfn) + bootmap_size);
+ reserve_bootmem(__MEMORY_START+PAGE_SIZE, (PFN_PHYS(start_pfn) +
+ bootmap_size + PAGE_SIZE-1) - __MEMORY_START);
/*
* reserve physical page 0 - it's a special BIOS page on many boxes,
* enabling clean reboots, SMP operation, laptop functions.
*/
- reserve_bootmem(0, PAGE_SIZE);
+ reserve_bootmem(__MEMORY_START, PAGE_SIZE);
#ifdef CONFIG_BLK_DEV_INITRD
- if (LOADER_TYPE) {
+ if (LOADER_TYPE && INITRD_START) {
if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
- reserve_bootmem(INITRD_START, INITRD_SIZE);
- initrd_start =
- INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
- initrd_end = initrd_start+INITRD_SIZE;
+ reserve_bootmem(INITRD_START+__MEMORY_START, INITRD_SIZE);
+ initrd_start =
+ INITRD_START ? INITRD_START + PAGE_OFFSET + __MEMORY_START : 0;
+ initrd_end = initrd_start + INITRD_SIZE;
} else {
- printk("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- INITRD_START + INITRD_SIZE,
- max_low_pfn << PAGE_SHIFT);
- initrd_start = 0;
- }
- }
+ printk("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ INITRD_START + INITRD_SIZE,
+ max_low_pfn << PAGE_SHIFT);
+ initrd_start = 0;
+ }
+ }
#endif
#if 0
@@ -298,6 +299,14 @@ void __init setup_arch(char **cmdline_p)
conswitchp = &dummy_con;
#endif
#endif
+
+#if defined(__SH4__)
+ init_task.used_math = 1;
+ init_task.flags |= PF_USEDFPU;
+ grab_fpu();
+ fpu_init();
+#endif
+ paging_init();
}
/*
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 7c9fbbf00..0c24acf73 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.10 1999/09/27 23:25:44 gniibe Exp $
+/* $Id: signal.c,v 1.16 2000/01/29 11:31:31 gniibe Exp gniibe $
*
* linux/arch/sh/kernel/signal.c
*
@@ -54,7 +54,7 @@ sys_sigsuspend(old_sigset_t mask,
while (1) {
current->state = TASK_INTERRUPTIBLE;
schedule();
- if (do_signal(&regs,&saveset))
+ if (do_signal(&regs, &saveset))
return -EINTR;
}
}
@@ -73,7 +73,6 @@ sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize,
if (copy_from_user(&newset, unewset, sizeof(newset)))
return -EFAULT;
sigdelsetmask(&newset, ~_BLOCKABLE);
-
spin_lock_irq(&current->sigmask_lock);
saveset = current->blocked;
current->blocked = newset;
@@ -188,6 +187,7 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
+
if (__get_user(set.sig[0], &frame->sc.oldmask)
|| (_NSIG_WORDS > 1
&& __copy_from_user(&set.sig[1], &frame->extramask,
@@ -195,6 +195,7 @@ asmlinkage int sys_sigreturn(unsigned long r4, unsigned long r5,
goto badframe;
sigdelsetmask(&set, ~_BLOCKABLE);
+
spin_lock_irq(&current->sigmask_lock);
current->blocked = set;
recalc_sigpending(current);
@@ -220,6 +221,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
+
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
goto badframe;
@@ -228,7 +230,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long r4, unsigned long r5,
current->blocked = set;
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
-
+
if (restore_sigcontext(&regs, &frame->uc.uc_mcontext, &r0))
goto badframe;
@@ -317,7 +319,7 @@ static void setup_frame(int sig, struct k_sigaction *ka,
if (ka->sa.sa_flags & SA_RESTORER) {
regs->pr = (unsigned long) ka->sa.sa_restorer;
} else {
- /* This is ; mov #__NR_sigreturn,r0 ; trapa #0 */
+ /* This is : mov #__NR_sigreturn,r0 ; trapa #0 */
#ifdef __LITTLE_ENDIAN__
unsigned long code = 0xc300e000 | (__NR_sigreturn);
#else
@@ -390,11 +392,11 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
if (ka->sa.sa_flags & SA_RESTORER) {
regs->pr = (unsigned long) ka->sa.sa_restorer;
} else {
- /* This is ; mov #__NR_sigreturn,r0 ; trapa #0 */
+ /* This is : mov #__NR_rt_sigreturn,r0 ; trapa #0 */
#ifdef __LITTLE_ENDIAN__
- unsigned long code = 0xc300e000 | (__NR_sigreturn);
+ unsigned long code = 0xc300e000 | (__NR_rt_sigreturn);
#else
- unsigned long code = 0xe000c300 | (__NR_sigreturn << 16);
+ unsigned long code = 0xe000c300 | (__NR_rt_sigreturn << 16);
#endif
regs->pr = (unsigned long) frame->retcode;
@@ -485,6 +487,15 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
siginfo_t info;
struct k_sigaction *ka;
+ /*
+ * We want the common case to go fast, which
+ * is why we may in certain cases get here from
+ * kernel mode. Just return without doing anything
+ * if so.
+ */
+ if (!user_mode(regs))
+ return 1;
+
if (!oldset)
oldset = &current->blocked;
@@ -580,6 +591,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
/* NOTREACHED */
}
}
+
/* Whee! Actually deliver the signal. */
handle_signal(signr, ka, &info, oldset, regs);
return 1;
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index 1b708e5a9..0b3d5fc2e 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -28,7 +28,9 @@
* sys_pipe() is the normal C calling standard for creating
* a pipe. It's not the way Unix traditionally does this, though.
*/
-asmlinkage int sys_pipe(unsigned long * fildes)
+asmlinkage int sys_pipe(unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7,
+ struct pt_regs regs)
{
int fd[2];
int error;
@@ -37,46 +39,62 @@ asmlinkage int sys_pipe(unsigned long * fildes)
error = do_pipe(fd);
unlock_kernel();
if (!error) {
- if (copy_to_user(fildes, fd, 2*sizeof(int)))
- error = -EFAULT;
+ regs.regs[1] = fd[1];
+ return fd[0];
}
return error;
}
-asmlinkage unsigned long
-sys_mmap(unsigned long addr, unsigned long len, unsigned long prot,
- unsigned long flags, int fd, unsigned long off)
+static inline long
+do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+ unsigned long flags, int fd, unsigned long pgoff)
{
- int error = -EFAULT;
+ int error = -EBADF;
struct file *file = NULL;
- down(&current->mm->mmap_sem);
- lock_kernel();
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
if (!(flags & MAP_ANONYMOUS)) {
- error = -EBADF;
file = fget(fd);
if (!file)
goto out;
}
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- error = do_mmap(file, addr, len, prot, flags, off);
- if (file)
- fput(file);
-out:
+ down(&current->mm->mmap_sem);
+ lock_kernel();
+
+ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
unlock_kernel();
up(&current->mm->mmap_sem);
+ if (file)
+ fput(file);
+out:
return error;
}
+asmlinkage int old_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ int fd, unsigned long off)
+{
+ if (off & ~PAGE_MASK)
+ return -EINVAL;
+ return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT);
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
/*
* sys_ipc() is the de-multiplexer for the SysV IPC calls..
*
* This is really horribly ugly.
*/
-asmlinkage int sys_ipc (uint call, int first, int second,
- int third, void *ptr, long fifth)
+asmlinkage int sys_ipc(uint call, int first, int second,
+ int third, void *ptr, long fifth)
{
int version, ret;
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index 49a765f83..fad3a8145 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.7 1999/11/06 02:00:37 gniibe Exp $
+/* $Id: time.c,v 1.20 2000/02/28 12:42:51 gniibe Exp $
*
* linux/arch/sh/kernel/time.c
*
@@ -8,8 +8,6 @@
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
*/
-#include <linux/config.h>
-
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -43,10 +41,10 @@
#define TMU0_TCNT 0xfffffe98 /* Long access */
#define TMU0_TCR 0xfffffe9c /* Word access */
-#define INTERVAL 37500 /* (1000000*CLOCK_MHZ/HZ/2) ??? for CqREEK */
-#if 0 /* Takeshi's board */
-#define INTERVAL 83333
-#endif
+#define FRQCR 0xffffff80
+
+#define RTC_IRQ 22
+#define RTC_IPR_OFFSET 0
/* SH-3 RTC */
#define R64CNT 0xfffffec0
@@ -74,7 +72,10 @@
#define TMU0_TCNT 0xffd8000c /* Long access */
#define TMU0_TCR 0xffd80010 /* Word access */
-#define INTERVAL 83333
+#define FRQCR 0xffc00000
+
+#define RTC_IRQ 22
+#define RTC_IPR_OFFSET 0
/* SH-4 RTC */
#define R64CNT 0xffc80000
@@ -145,11 +146,10 @@ void do_settimeofday(struct timeval *tv)
static int set_rtc_time(unsigned long nowtime)
{
-#ifdef CONFIG_SH_CPU_RTC
int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
- ctrl_outb(2, RCR2); /* reset pre-scaler & stop RTC */
+ ctrl_outb(0x02, RCR2); /* reset pre-scaler & stop RTC */
cmos_minutes = ctrl_inb(RMINCNT);
BCD_TO_BIN(cmos_minutes);
@@ -178,13 +178,9 @@ static int set_rtc_time(unsigned long nowtime)
retval = -1;
}
- ctrl_outb(2, RCR2); /* start RTC */
+ ctrl_outb(0x01, RCR2); /* start RTC */
return retval;
-#else
- /* XXX should support other clock devices? */
- return -1;
-#endif
}
/* last time the RTC clock got updated */
@@ -197,7 +193,6 @@ static long last_rtc_update = 0;
static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
do_timer(regs);
-
#ifdef TAKESHI
{
unsigned long what_is_this=0xa4000124;
@@ -248,9 +243,7 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* locally disabled. -arca
*/
write_lock(&xtime_lock);
-
do_timer_interrupt(irq, NULL, regs);
-
write_unlock(&xtime_lock);
}
@@ -287,11 +280,10 @@ static inline unsigned long mktime(unsigned int year, unsigned int mon,
static unsigned long get_rtc_time(void)
{
-#ifdef CONFIG_SH_CPU_RTC
unsigned int sec, min, hr, wk, day, mon, yr, yr100;
again:
- ctrl_outb(1, RCR1); /* clear CF bit */
+ ctrl_outb(0x01, RCR1); /* clear CF bit */
do {
sec = ctrl_inb(RSECCNT);
min = ctrl_inb(RMINCNT);
@@ -321,7 +313,7 @@ static unsigned long get_rtc_time(void)
hr > 23 || min > 59 || sec > 59) {
printk(KERN_ERR
"SH RTC: invalid value, resetting to 1 Jan 2000\n");
- ctrl_outb(2, RCR2); /* reset, stop */
+ ctrl_outb(0x02, RCR2); /* reset, stop */
ctrl_outb(0, RSECCNT);
ctrl_outb(0, RMINCNT);
ctrl_outb(0, RHRCNT);
@@ -333,36 +325,114 @@ static unsigned long get_rtc_time(void)
#else
ctrl_outb(0, RYRCNT);
#endif
- ctrl_outb(1, RCR2); /* start */
+ ctrl_outb(0x01, RCR2); /* start */
goto again;
}
return mktime(yr100 * 100 + yr, mon, day, hr, min, sec);
+}
+
+static __init unsigned int get_cpu_mhz(void)
+{
+ unsigned int count;
+ unsigned long __dummy;
+
+ sti();
+ do {} while (ctrl_inb(R64CNT) != 0);
+ ctrl_outb(0x11, RCR1);
+ asm volatile(
+ "1:\t"
+ "tst %1,%1\n\t"
+ "bt/s 1b\n\t"
+ " add #1,%0"
+ : "=&r"(count), "=&z" (__dummy)
+ : "0" (0), "1" (0));
+ cli();
+ /*
+ * SH-3:
+ * CPU clock = 4 stages * loop
+ * tst rm,rm if id ex
+ * bt/s 1b if id ex
+ * add #1,rd if id ex
+ * (if) pipe line stole
+ * tst rm,rm if id ex
+ * ....
+ *
+ *
+ * SH-4:
+ * CPU clock = 6 stages * loop
+ * I don't know why.
+ * ....
+ */
+#if defined(__SH4__)
+ return count*6;
#else
- /* XXX should support other clock devices? */
- return 0;
+ return count*4;
#endif
}
+static void rtc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ ctrl_outb(0x01, RCR1);
+ regs->regs[0] = 1;
+}
+
static struct irqaction irq0 = { timer_interrupt, SA_INTERRUPT, 0, "timer", NULL, NULL};
+static struct irqaction irq1 = { rtc_interrupt, SA_INTERRUPT, 0, "rtc", NULL, NULL};
void __init time_init(void)
{
+ unsigned int cpu_clock, master_clock, module_clock;
+ unsigned short ifc, pfc;
+ unsigned long interval;
+#if defined(__sh3__)
+ static int ifc_table[] = { 1, 2, 4, 1, 3, 1, 1, 1 };
+ static int pfc_table[] = { 1, 2, 4, 1, 3, 6, 1, 1 };
+#elif defined(__SH4__)
+ static int ifc_table[] = { 1, 2, 3, 4, 6, 8, 1, 1 };
+ static int pfc_table[] = { 2, 3, 4, 6, 8, 2, 2, 2 };
+#endif
+
xtime.tv_sec = get_rtc_time();
xtime.tv_usec = 0;
- set_ipr_data(TIMER_IRQ, TIMER_IRP_OFFSET, TIMER_PRIORITY);
+ set_ipr_data(TIMER_IRQ, TIMER_IPR_OFFSET, TIMER_PRIORITY);
setup_irq(TIMER_IRQ, &irq0);
+ set_ipr_data(RTC_IRQ, RTC_IPR_OFFSET, TIMER_PRIORITY);
+ setup_irq(RTC_IRQ, &irq1);
- /* Start TMU0 */
- ctrl_outb(TMU_TOCR_INIT,TMU_TOCR);
- ctrl_outw(TMU0_TCR_INIT,TMU0_TCR);
- ctrl_outl(INTERVAL,TMU0_TCOR);
- ctrl_outl(INTERVAL,TMU0_TCNT);
- ctrl_outb(TMU_TSTR_INIT,TMU_TSTR);
+ /* Check how fast it is.. */
+ cpu_clock = get_cpu_mhz();
+ disable_irq(RTC_IRQ);
-#if 0
- /* Start RTC */
- asm volatile("");
+ printk("CPU clock: %d.%02dMHz\n",
+ (cpu_clock / 1000000), (cpu_clock % 1000000)/10000);
+#if defined(__sh3__)
+ {
+ unsigned short tmp;
+ tmp = (ctrl_inw(FRQCR) & 0x000c) >> 2;
+ tmp |= (ctrl_inw(FRQCR) & 0x4000) >> 12;
+ ifc = ifc_table[tmp & 0x0007];
+ tmp = ctrl_inw(FRQCR) & 0x0003;
+ tmp |= (ctrl_inw(FRQCR) & 0x2000) >> 11;
+ pfc = pfc_table[ctrl_inw(FRQCR) & 0x0007];
+ }
+#elif defined(__SH4__)
+ ifc = ifc_table[(ctrl_inw(FRQCR)>> 6) & 0x0007];
+ pfc = pfc_table[ctrl_inw(FRQCR) & 0x0007];
#endif
+ master_clock = cpu_clock * ifc;
+ module_clock = master_clock/pfc;
+ printk("Module clock: %d.%02dMHz\n",
+ (module_clock/1000000), (module_clock % 1000000)/10000);
+ interval = (module_clock/400);
+
+ printk("Interval = %ld\n", interval);
+
+ /* Start TMU0 */
+ ctrl_outb(TMU_TOCR_INIT, TMU_TOCR);
+ ctrl_outw(TMU0_TCR_INIT, TMU0_TCR);
+ ctrl_outl(interval, TMU0_TCOR);
+ ctrl_outl(interval, TMU0_TCNT);
+ ctrl_outb(TMU_TSTR_INIT, TMU_TSTR);
}
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index 8a9b3e1f9..98431cb36 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.3 1999/09/21 14:37:19 gniibe Exp $
+/* $Id: traps.c,v 1.5 2000/02/27 08:27:55 gniibe Exp $
*
* linux/arch/sh/traps.c
*
@@ -26,6 +26,7 @@
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/atomic.h>
+#include <asm/processor.h>
static inline void console_verbose(void)
{
@@ -40,7 +41,7 @@ asmlinkage void do_##name(unsigned long r4, unsigned long r5, \
{ \
unsigned long error_code; \
\
- asm volatile("stc r2_bank,%0": "=r" (error_code)); \
+ asm volatile("stc $r2_bank, %0": "=r" (error_code)); \
sti(); \
regs.syscall_nr = -1; \
tsk->thread.error_code = error_code; \
@@ -99,7 +100,7 @@ asmlinkage void do_exception_error (unsigned long r4, unsigned long r5,
struct pt_regs regs)
{
long ex;
- asm volatile("stc r2_bank,%0" : "=r" (ex));
+ asm volatile("stc $r2_bank, %0" : "=r" (ex));
die_if_kernel("exception", &regs, ex);
}
@@ -117,8 +118,22 @@ void __init trap_init(void)
(or P2, virtural "fixed" address space).
It's definitely should not in physical address. */
- asm volatile("ldc %0,vbr"
+ asm volatile("ldc %0, $vbr"
: /* no output */
: "r" (&vbr_base)
: "memory");
}
+
+void dump_stack(void)
+{
+ unsigned long *start;
+ unsigned long *end;
+ unsigned long *p;
+
+ asm("mov $r15, %0" : "=r" (start));
+ asm("stc $r4_bank, %0" : "=r" (end));
+
+ printk("%08lx:%08lx\n", (unsigned long)start, (unsigned long)end);
+ for (p=start; p < end; p++)
+ printk("%08lx\n", *p);
+}
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index d15c62385..f5c5200be 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -1,4 +1,4 @@
-/* $Id: cache.c,v 1.7 1999/09/23 11:43:07 gniibe Exp $
+/* $Id: cache.c,v 1.9 2000/02/14 12:45:26 gniibe Exp $
*
* linux/arch/sh/mm/cache.c
*
@@ -283,7 +283,30 @@ void __init cache_init(void)
}
#if defined(__SH4__)
-/* Write back data caches, and invalidates instructiin caches */
+void flush_icache_page(struct vm_area_struct *vma, struct page *pg)
+{
+ unsigned long flags, __dummy;
+ unsigned long addr, data, v;
+
+ save_and_cli(flags);
+ jump_to_p2(__dummy);
+
+ v = page_address(pg);
+
+ /* Write back O Cache */
+ asm volatile("ocbwb %0"
+ : /* no output */
+ : "m" (__m(v)));
+ /* Invalidate I Cache */
+ addr = CACHE_IC_ADDRESS_ARRAY |
+ (v&CACHE_IC_ENTRY_MASK) | 0x8 /* A-bit */;
+ data = (v&0xfffffc00); /* Valid=0 */
+ ctrl_outl(data,addr);
+
+ back_to_p1(__dummy);
+ restore_flags(flags);
+}
+
void flush_icache_range(unsigned long start, unsigned long end)
{
unsigned long flags, __dummy;
@@ -358,7 +381,7 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
flush_cache_range(vma->vm_mm, addr, addr+PAGE_SIZE);
}
-void flush_page_to_ram(unsigned long page)
+void __flush_page_to_ram(unsigned long page)
{ /* Page is in physical address */
/* XXX: for the time being... */
flush_cache_all();
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 7f3610a3b..3b8e86e36 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.5 1999/10/31 13:17:31 gniibe Exp $
+/* $Id: fault.c,v 1.12 2000/03/01 11:15:27 gniibe Exp $
*
* linux/arch/sh/mm/fault.c
* Copyright (C) 1999 Niibe Yutaka
@@ -23,7 +23,7 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/uaccess.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/hardirq.h>
#include <asm/mmu_context.h>
@@ -211,10 +211,12 @@ no_context:
printk(KERN_ALERT "Unable to handle kernel paging request");
printk(" at virtual address %08lx\n",address);
printk(KERN_ALERT "pc = %08lx\n", regs->pc);
- page = (unsigned long)mm->pgd;
- page = ((unsigned long *) __va(page))[address >> 22];
+ asm volatile("mov.l %1,%0"
+ : "=r" (page)
+ : "m" (__m(MMU_TTB)));
+ page = ((unsigned long *) page)[address >> 22];
printk(KERN_ALERT "*pde = %08lx\n", page);
- if (page & 1) {
+ if (page & _PAGE_PRESENT) {
page &= PAGE_MASK;
address &= 0x003ff000;
page = ((unsigned long *) __va(page))[address >> PAGE_SHIFT];
@@ -256,6 +258,7 @@ void update_mmu_cache(struct vm_area_struct * vma,
{
unsigned long flags;
unsigned long pteval;
+ unsigned long pteaddr;
save_and_cli(flags);
/*
@@ -267,6 +270,9 @@ void update_mmu_cache(struct vm_area_struct * vma,
pteval |= _PAGE_FLAGS_HARDWARE_DEFAULT; /* add default flags */
/* Set PTEL register */
ctrl_outl(pteval, MMU_PTEL);
+ /* Set PTEH register */
+ pteaddr = (address & MMU_VPN_MASK) | (vma->vm_mm->context & MMU_CONTEXT_ASID_MASK);
+ ctrl_outl(pteaddr, MMU_PTEH);
/* Load the TLB */
asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
@@ -277,6 +283,9 @@ static void __flush_tlb_page(struct mm_struct *mm, unsigned long page)
{
unsigned long addr, data, asid;
unsigned long saved_asid = MMU_NO_ASID;
+#if defined(__SH4__)
+ int i;
+#endif
if (mm->context == NO_CONTEXT)
return;
@@ -296,8 +305,6 @@ static void __flush_tlb_page(struct mm_struct *mm, unsigned long page)
data = (page & 0xfffe0000) | asid; /* VALID bit is off */
ctrl_outl(data, addr);
#elif defined(__SH4__)
- int i;
-
addr = MMU_UTLB_ADDRESS_ARRAY | MMU_PAGE_ASSOC_BIT;
data = page | asid; /* VALID bit is off */
ctrl_outl(data, addr);
@@ -305,7 +312,7 @@ static void __flush_tlb_page(struct mm_struct *mm, unsigned long page)
for (i=0; i<4; i++) {
addr = MMU_ITLB_ADDRESS_ARRAY | (i<<8);
data = ctrl_inl(addr);
- data &= ~0x30;
+ data &= ~0x300;
if (data == (page | asid)) {
ctrl_outl(data, addr);
break;
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 458685f4a..776389cac 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.4 1999/10/23 01:37:02 gniibe Exp gniibe $
+/* $Id: init.c,v 1.16 2000/02/14 15:19:05 gniibe Exp $
*
* linux/arch/sh/mm/init.c
*
@@ -24,12 +24,14 @@
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
#endif
+#include <linux/highmem.h>
#include <linux/bootmem.h>
#include <asm/processor.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
@@ -77,13 +79,13 @@ static pte_t * get_bad_pte_table(void)
void __handle_bad_pmd(pmd_t *pmd)
{
pmd_ERROR(*pmd);
- pmd_val(*pmd) = _PAGE_TABLE + __pa(get_bad_pte_table());
+ set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(get_bad_pte_table())));
}
void __handle_bad_pmd_kernel(pmd_t *pmd)
{
pmd_ERROR(*pmd);
- pmd_val(*pmd) = _KERNPG_TABLE + __pa(get_bad_pte_table());
+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(get_bad_pte_table())));
}
pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
@@ -94,10 +96,10 @@ pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
if (pmd_none(*pmd)) {
if (pte) {
clear_page(pte);
- pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte);
+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
return pte + offset;
}
- pmd_val(*pmd) = _KERNPG_TABLE + __pa(get_bad_pte_table());
+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(get_bad_pte_table())));
return NULL;
}
free_page((unsigned long)pte);
@@ -116,10 +118,10 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
if (pmd_none(*pmd)) {
if (pte) {
clear_page((void *)pte);
- pmd_val(*pmd) = _PAGE_TABLE + __pa(pte);
+ set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)));
return (pte_t *)pte + offset;
}
- pmd_val(*pmd) = _PAGE_TABLE + __pa(get_bad_pte_table());
+ set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(get_bad_pte_table())));
return NULL;
}
free_page(pte);
@@ -133,15 +135,15 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
int do_check_pgt_cache(int low, int high)
{
int freed = 0;
- if(pgtable_cache_size > high) {
+ if (pgtable_cache_size > high) {
do {
- if(pgd_quicklist)
+ if (pgd_quicklist)
free_pgd_slow(get_pgd_fast()), freed++;
- if(pmd_quicklist)
+ if (pmd_quicklist)
free_pmd_slow(get_pmd_fast()), freed++;
- if(pte_quicklist)
+ if (pte_quicklist)
free_pte_slow(get_pte_fast()), freed++;
- } while(pgtable_cache_size > low);
+ } while (pgtable_cache_size > low);
}
return freed;
}
@@ -181,6 +183,10 @@ extern char __init_begin, __init_end;
pgd_t swapper_pg_dir[1024];
+/* It'd be good if these lines were in the standard header file. */
+#define START_PFN (NODE_DATA(0)->bdata->node_boot_start >> PAGE_SHIFT)
+#define MAX_LOW_PFN (NODE_DATA(0)->bdata->node_low_pfn)
+
/*
* paging_init() sets up the page tables
*
@@ -204,32 +210,55 @@ void __init paging_init(void)
mmu_context_cache = MMU_CONTEXT_FIRST_VERSION;
set_asid(mmu_context_cache & MMU_CONTEXT_ASID_MASK);
- free_area_init(max_low_pfn);
+ {
+ unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned long max_dma, low, start_pfn;
+
+ start_pfn = START_PFN;
+ max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ low = MAX_LOW_PFN;
+
+ if (low < max_dma)
+ zones_size[ZONE_DMA] = low - start_pfn;
+ else {
+ zones_size[ZONE_DMA] = max_dma - start_pfn;
+ zones_size[ZONE_NORMAL] = low - max_dma;
+ }
+ free_area_init_node(0, 0, zones_size, __MEMORY_START);
+ }
}
void __init mem_init(void)
{
- int codepages = 0;
- int reservedpages = 0;
- int datapages = 0;
- int initpages = 0;
+ int codesize, reservedpages, datasize, initsize;
+ int tmp;
- max_mapnr = num_physpages = max_low_pfn;
- high_memory = (void *) ((unsigned long)__va(max_low_pfn * PAGE_SIZE)+__MEMORY_START);
+ max_mapnr = num_physpages = MAX_LOW_PFN - START_PFN;
+ high_memory = (void *)__va(MAX_LOW_PFN * PAGE_SIZE);
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
/* this will put all low memory onto the freelists */
totalram_pages += free_all_bootmem();
+ reservedpages = 0;
+ for (tmp = 0; tmp < num_physpages; tmp++)
+ /*
+ * Only count reserved RAM pages
+ */
+ if (PageReserved(mem_map+tmp))
+ reservedpages++;
+ codesize = (unsigned long) &_etext - (unsigned long) &_text;
+ datasize = (unsigned long) &_edata - (unsigned long) &_etext;
+ initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init)\n",
- (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
+ (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
max_mapnr << (PAGE_SHIFT-10),
- codepages << (PAGE_SHIFT-10),
+ codesize >> 10,
reservedpages << (PAGE_SHIFT-10),
- datapages << (PAGE_SHIFT-10),
- initpages << (PAGE_SHIFT-10));
+ datasize >> 10,
+ initsize >> 10);
}
void free_initmem(void)
@@ -246,14 +275,28 @@ void free_initmem(void)
printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
}
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ unsigned long p;
+ for (p = start; p < end; p += PAGE_SIZE) {
+ ClearPageReserved(mem_map + MAP_NR(p));
+ set_page_count(mem_map+MAP_NR(p), 1);
+ free_page(p);
+ totalram_pages++;
+ }
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
void si_meminfo(struct sysinfo *val)
{
val->totalram = totalram_pages;
val->sharedram = 0;
- val->freeram = nr_free_pages;
+ val->freeram = nr_free_pages();
val->bufferram = atomic_read(&buffermem_pages);
val->totalhigh = totalhigh_pages;
- val->freehigh = nr_free_highpages;
+ val->freehigh = nr_free_highpages();
val->mem_unit = PAGE_SIZE;
return;
}
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c
index c12b97d18..2dd1e6ec2 100644
--- a/arch/sh/mm/ioremap.c
+++ b/arch/sh/mm/ioremap.c
@@ -1,4 +1,4 @@
-/* $Id: ioremap.c,v 1.1 1999/09/18 16:57:48 gniibe Exp $
+/* $Id: ioremap.c,v 1.2 1999/11/25 14:00:28 gniibe Exp $
*
* arch/sh/mm/ioremap.c
*
@@ -11,6 +11,7 @@
#include <linux/vmalloc.h>
#include <asm/io.h>
+#include <asm/pgalloc.h>
static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
unsigned long phys_addr, unsigned long flags)
diff --git a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S
index 688c4c9c4..53a7fff56 100644
--- a/arch/sh/vmlinux.lds.S
+++ b/arch/sh/vmlinux.lds.S
@@ -1,4 +1,4 @@
-/* $Id: vmlinux.lds.S,v 1.3 1999/10/05 12:33:48 gniibe Exp $
+/* $Id: vmlinux.lds.S,v 1.4 1999/12/23 11:37:45 gniibe Exp $
* ld script to make SuperH Linux kernel
* Written by Niibe Yutaka
*/
@@ -13,8 +13,8 @@ ENTRY(_start)
SECTIONS
{
. = 0x80000000 + CONFIG_MEMORY_START + 0x1000;
- __text = .; /* Text and read-only data */
_text = .; /* Text and read-only data */
+ text = .; /* Text and read-only data */
.text : {
*(.empty_zero_page)
*(.text)
@@ -26,41 +26,41 @@ SECTIONS
.kstrtab : { *(.kstrtab) }
. = ALIGN(16); /* Exception table */
- ___start___ex_table = .;
- ___ex_table : { *(__ex_table) }
- ___stop___ex_table = .;
+ __start___ex_table = .;
+ __ex_table : { *(__ex_table) }
+ __stop___ex_table = .;
- ___start___ksymtab = .; /* Kernel symbol table */
- ___ksymtab : { *(__ksymtab) }
- ___stop___ksymtab = .;
+ __start___ksymtab = .; /* Kernel symbol table */
+ __ksymtab : { *(__ksymtab) }
+ __stop___ksymtab = .;
- __etext = .; /* End of text section */
+ _etext = .; /* End of text section */
.data : { /* Data */
*(.data)
CONSTRUCTORS
}
- __edata = .; /* End of data section */
+ _edata = .; /* End of data section */
. = ALIGN(8192); /* init_task */
.data.init_task : { *(.data.init_task) }
/* stack */
- .stack : { _stack = .; __stack = .; }
+ .stack : { stack = .; _stack = .; }
. = ALIGN(4096); /* Init code and data */
- ___init_begin = .;
+ __init_begin = .;
.text.init : { *(.text.init) }
.data.init : { *(.data.init) }
. = ALIGN(16);
- ___setup_start = .;
+ __setup_start = .;
.setup.init : { *(.setup.init) }
- ___setup_end = .;
- ___initcall_start = .;
+ __setup_end = .;
+ __initcall_start = .;
.initcall.init : { *(.initcall.init) }
- ___initcall_end = .;
+ __initcall_end = .;
. = ALIGN(4096);
- ___init_end = .;
+ __init_end = .;
. = ALIGN(4096);
.data.page_aligned : { *(.data.idt) }
@@ -69,12 +69,12 @@ SECTIONS
.data.cacheline_aligned : { *(.data.cacheline_aligned) }
. = ALIGN(4);
- ___bss_start = .; /* BSS */
+ __bss_start = .; /* BSS */
.bss : {
*(.bss)
}
. = ALIGN(4);
- __end = . ;
+ _end = . ;
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
diff --git a/arch/sparc/kernel/sys_sunos.c b/arch/sparc/kernel/sys_sunos.c
index 82b5ac653..54c701768 100644
--- a/arch/sparc/kernel/sys_sunos.c
+++ b/arch/sparc/kernel/sys_sunos.c
@@ -432,12 +432,10 @@ static int sunos_filldir(void * __buf, const char * name, int namlen,
asmlinkage int sunos_getdents(unsigned int fd, void * dirent, int cnt)
{
struct file * file;
- struct inode * inode;
struct sunos_dirent * lastdirent;
struct sunos_dirent_callback buf;
int error = -EBADF;
- lock_kernel();
if (fd >= SUNOS_NR_OPEN)
goto out;
@@ -445,10 +443,7 @@ asmlinkage int sunos_getdents(unsigned int fd, void * dirent, int cnt)
if (!file)
goto out;
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out_putf;
-
+ lock_kernel();
error = -EINVAL;
if (cnt < (sizeof(struct sunos_dirent) + 255))
goto out_putf;
@@ -458,10 +453,7 @@ asmlinkage int sunos_getdents(unsigned int fd, void * dirent, int cnt)
buf.count = cnt;
buf.error = 0;
- inode = file->f_dentry->d_inode;
- down(&inode->i_sem);
- error = file->f_op->readdir(file, &buf, sunos_filldir);
- up(&inode->i_sem);
+ error = vfs_readdir(file, sunos_filldir, &buf);
if (error < 0)
goto out_putf;
@@ -473,9 +465,9 @@ asmlinkage int sunos_getdents(unsigned int fd, void * dirent, int cnt)
}
out_putf:
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
@@ -521,12 +513,10 @@ static int sunos_filldirentry(void * __buf, const char * name, int namlen,
asmlinkage int sunos_getdirentries(unsigned int fd, void * dirent, int cnt, unsigned int *basep)
{
struct file * file;
- struct inode * inode;
struct sunos_direntry * lastdirent;
struct sunos_direntry_callback buf;
int error = -EBADF;
- lock_kernel();
if (fd >= SUNOS_NR_OPEN)
goto out;
@@ -534,10 +524,7 @@ asmlinkage int sunos_getdirentries(unsigned int fd, void * dirent, int cnt, unsi
if (!file)
goto out;
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out_putf;
-
+ lock_kernel();
error = -EINVAL;
if(cnt < (sizeof(struct sunos_direntry) + 255))
goto out_putf;
@@ -547,10 +534,7 @@ asmlinkage int sunos_getdirentries(unsigned int fd, void * dirent, int cnt, unsi
buf.count = cnt;
buf.error = 0;
- inode = file->f_dentry->d_inode;
- down(&inode->i_sem);
- error = file->f_op->readdir(file, &buf, sunos_filldirentry);
- up(&inode->i_sem);
+ error = vfs_readdir(file, sunos_filldirentry, &buf);
if (error < 0)
goto out_putf;
@@ -562,9 +546,9 @@ asmlinkage int sunos_getdirentries(unsigned int fd, void * dirent, int cnt, unsi
}
out_putf:
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index df636ec6f..2ab8b70d4 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.112 2000/01/14 07:12:31 davem Exp $
+/* $Id: entry.S,v 1.113 2000/03/06 22:33:42 davem Exp $
* arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points.
*
* Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -927,7 +927,17 @@ ret_from_syscall:
nop
ldx [%g6 + AOFF_task_thread + AOFF_thread_pcr_reg], %o7
wr %g0, %o7, %pcr
- wr %g0, %g0, %pic
+
+ /* Blackbird errata workaround. See commentary in
+ * smp.c:smp_percpu_timer_interrupt() for more
+ * information.
+ */
+ ba,pt %xcc, 99f
+ nop
+ .align 64
+99: wr %g0, %g0, %pic
+ rd %pic, %g0
+
1: b,pt %xcc, ret_sys_call
ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0], %o0
sparc_exit: rdpr %otherwin, %g1
diff --git a/arch/sparc64/kernel/head.S b/arch/sparc64/kernel/head.S
index 47a170f54..7eefa9f65 100644
--- a/arch/sparc64/kernel/head.S
+++ b/arch/sparc64/kernel/head.S
@@ -1,4 +1,4 @@
-/* $Id: head.S,v 1.63 1999/11/19 05:52:49 davem Exp $
+/* $Id: head.S,v 1.64 2000/03/06 22:33:42 davem Exp $
* head.S: Initial boot code for the Sparc64 port of Linux.
*
* Copyright (C) 1996,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -262,7 +262,16 @@ sun4u_init:
/* Setup "Linux Current Register", thanks Sun 8-) */
wr %g0, 0x1, %pcr
- wr %g6, 0x0, %pic
+
+ /* Blackbird errata workaround. See commentary in
+ * smp.c:smp_percpu_timer_interrupt() for more
+ * information.
+ */
+ ba,pt %xcc, 99f
+ nop
+ .align 64
+99: wr %g6, %g0, %pic
+ rd %pic, %g0
#endif
wr %g0, ASI_P, %asi
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index ed2e8bd81..0d1b968fa 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.51 2000/02/26 04:24:32 davem Exp $
+/* $Id: setup.c,v 1.52 2000/03/03 23:48:41 davem Exp $
* linux/arch/sparc64/kernel/setup.c
*
* Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
@@ -164,9 +164,17 @@ int prom_callback(long *args)
}
if ((va >= KERNBASE) && (va < (KERNBASE + (4 * 1024 * 1024)))) {
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
/*
* Locked down tlb entry 63.
*/
+
tte = spitfire_get_dtlb_data(63);
res = PROM_TRUE;
goto done;
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index 175372877..96360b010 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -312,6 +312,13 @@ static inline void xcall_deliver(u64 data0, u64 data1, u64 data2, u64 pstate, un
smp_processor_id(), data0, data1, data2, target);
#endif
again:
+ /* Ok, this is the real Spitfire Errata #54.
+ * One must read back from a UDB internal register
+ * after writes to the UDB interrupt dispatch, but
+ * before the membar Sync for that write.
+ * So we use the high UDB control register (ASI 0x7f,
+ * ADDR 0x20) for the dummy read. -DaveM
+ */
tmp = 0x40;
__asm__ __volatile__("
wrpr %1, %2, %%pstate
@@ -321,10 +328,13 @@ again:
stxa %6, [%0+%8] %3
membar #Sync
stxa %%g0, [%7] %3
+ mov 0x20, %%g1
+ ldxa [%%g1] 0x7f, %%g0
membar #Sync"
: "=r" (tmp)
: "r" (pstate), "i" (PSTATE_IE), "i" (ASI_UDB_INTR_W),
- "r" (data0), "r" (data1), "r" (data2), "r" (target), "r" (0x10), "0" (tmp));
+ "r" (data0), "r" (data1), "r" (data2), "r" (target), "r" (0x10), "0" (tmp)
+ : "g1");
/* NOTE: PSTATE_IE is still clear. */
stuck = 100000;
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 6e2d566b2..d3f02ae54 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1257,10 +1257,8 @@ asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent,
{
int error = -EBADF;
struct file * file;
- struct inode * inode;
struct readdir_callback32 buf;
- lock_kernel();
file = fget(fd);
if (!file)
goto out;
@@ -1268,22 +1266,16 @@ asmlinkage int old32_readdir(unsigned int fd, struct old_linux_dirent32 *dirent,
buf.count = 0;
buf.dirent = dirent;
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out_putf;
-
- inode = file->f_dentry->d_inode;
- down(&inode->i_sem);
- error = file->f_op->readdir(file, &buf, fillonedir);
- up(&inode->i_sem);
+ lock_kernel();
+ error = vfs_readdir(file, fillonedir, &buf);
if (error < 0)
goto out_putf;
error = buf.count;
out_putf:
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
@@ -1328,12 +1320,10 @@ static int filldir(void * __buf, const char * name, int namlen, off_t offset, in
asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, unsigned int count)
{
struct file * file;
- struct inode * inode;
struct linux_dirent32 * lastdirent;
struct getdents_callback32 buf;
int error = -EBADF;
- lock_kernel();
file = fget(fd);
if (!file)
goto out;
@@ -1343,14 +1333,8 @@ asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, un
buf.count = count;
buf.error = 0;
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out_putf;
-
- inode = file->f_dentry->d_inode;
- down(&inode->i_sem);
- error = file->f_op->readdir(file, &buf, filldir);
- up(&inode->i_sem);
+ lock_kernel();
+ error = vfs_readdir(file, filldir, &buf);
if (error < 0)
goto out_putf;
lastdirent = buf.previous;
@@ -1360,9 +1344,9 @@ asmlinkage int sys32_getdents(unsigned int fd, struct linux_dirent32 *dirent, un
error = count - buf.count;
}
out_putf:
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c
index c5101248a..d977c7952 100644
--- a/arch/sparc64/kernel/sys_sunos32.c
+++ b/arch/sparc64/kernel/sys_sunos32.c
@@ -388,13 +388,11 @@ static int sunos_filldir(void * __buf, const char * name, int namlen,
asmlinkage int sunos_getdents(unsigned int fd, u32 u_dirent, int cnt)
{
struct file * file;
- struct inode * inode;
struct sunos_dirent * lastdirent;
struct sunos_dirent_callback buf;
int error = -EBADF;
void *dirent = (void *)A(u_dirent);
- lock_kernel();
if(fd >= SUNOS_NR_OPEN)
goto out;
@@ -402,9 +400,7 @@ asmlinkage int sunos_getdents(unsigned int fd, u32 u_dirent, int cnt)
if(!file)
goto out;
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out_putf;
+ lock_kernel();
error = -EINVAL;
if(cnt < (sizeof(struct sunos_dirent) + 255))
@@ -415,10 +411,7 @@ asmlinkage int sunos_getdents(unsigned int fd, u32 u_dirent, int cnt)
buf.count = cnt;
buf.error = 0;
- inode = file->f_dentry->d_inode;
- down(&inode->i_sem);
- error = file->f_op->readdir(file, &buf, sunos_filldir);
- up(&inode->i_sem);
+ error = vfs_readdir(file, sunos_filldir, &buf);
if (error < 0)
goto out_putf;
@@ -430,9 +423,9 @@ asmlinkage int sunos_getdents(unsigned int fd, u32 u_dirent, int cnt)
}
out_putf:
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
@@ -481,12 +474,10 @@ asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent,
void *dirent = (void *) A(u_dirent);
unsigned int *basep = (unsigned int *)A(u_basep);
struct file * file;
- struct inode * inode;
struct sunos_direntry * lastdirent;
int error = -EBADF;
struct sunos_direntry_callback buf;
- lock_kernel();
if(fd >= SUNOS_NR_OPEN)
goto out;
@@ -494,9 +485,7 @@ asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent,
if(!file)
goto out;
- error = -ENOTDIR;
- if (!file->f_op || !file->f_op->readdir)
- goto out_putf;
+ lock_kernel();
error = -EINVAL;
if(cnt < (sizeof(struct sunos_direntry) + 255))
@@ -507,10 +496,7 @@ asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent,
buf.count = cnt;
buf.error = 0;
- inode = file->f_dentry->d_inode;
- down(&inode->i_sem);
- error = file->f_op->readdir(file, &buf, sunos_filldirentry);
- up(&inode->i_sem);
+ error = vfs_readdir(file, sunos_filldirentry, &buf);
if (error < 0)
goto out_putf;
@@ -522,9 +508,9 @@ asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent,
}
out_putf:
+ unlock_kernel();
fput(file);
out:
- unlock_kernel();
return error;
}
diff --git a/arch/sparc64/lib/blockops.S b/arch/sparc64/lib/blockops.S
index 1aa48643c..1cdbf09da 100644
--- a/arch/sparc64/lib/blockops.S
+++ b/arch/sparc64/lib/blockops.S
@@ -1,4 +1,4 @@
-/* $Id: blockops.S,v 1.19 1999/11/19 05:52:45 davem Exp $
+/* $Id: blockops.S,v 1.20 2000/03/03 23:48:38 davem Exp $
* blockops.S: UltraSparc block zero optimized routines.
*
* Copyright (C) 1996,1998 David S. Miller (davem@caip.rutgers.edu)
@@ -46,13 +46,37 @@ copy_page: /* %o0=dest, %o1=src */
sethi %hi(TLBTEMP_ENT1), %o3
rdpr %pstate, %g3
wrpr %g3, PSTATE_IE, %pstate
+
+ /* Spitfire Errata #32 workaround */
+ mov 0x8, %o4
+ stxa %g0, [%o4] ASI_DMMU
+ flush %g6
+
ldxa [%o3] ASI_DTLB_TAG_READ, %o4
+
+ /* Spitfire Errata #32 workaround */
+ mov 0x8, %o5
+ stxa %g0, [%o5] ASI_DMMU
+ flush %g6
+
ldxa [%o3] ASI_DTLB_DATA_ACCESS, %o5
stxa %o0, [%o2] ASI_DMMU
stxa %g1, [%o3] ASI_DTLB_DATA_ACCESS
membar #Sync
add %o3, (TLBTEMP_ENTSZ), %o3
+
+ /* Spitfire Errata #32 workaround */
+ mov 0x8, %g5
+ stxa %g0, [%g5] ASI_DMMU
+ flush %g6
+
ldxa [%o3] ASI_DTLB_TAG_READ, %g5
+
+ /* Spitfire Errata #32 workaround */
+ mov 0x8, %g7
+ stxa %g0, [%g7] ASI_DMMU
+ flush %g6
+
ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g7
stxa %o1, [%o2] ASI_DMMU
stxa %g2, [%o3] ASI_DTLB_DATA_ACCESS
@@ -120,7 +144,19 @@ clear_page: /* %o0=dest */
sethi %hi(TLBTEMP_ENT2), %o3
rdpr %pstate, %g3
wrpr %g3, PSTATE_IE, %pstate
+
+ /* Spitfire Errata #32 workaround */
+ mov 0x8, %g5
+ stxa %g0, [%g5] ASI_DMMU
+ flush %g6
+
ldxa [%o3] ASI_DTLB_TAG_READ, %g5
+
+ /* Spitfire Errata #32 workaround */
+ mov 0x8, %g7
+ stxa %g0, [%g7] ASI_DMMU
+ flush %g6
+
ldxa [%o3] ASI_DTLB_DATA_ACCESS, %g7
stxa %o0, [%o2] ASI_DMMU
stxa %g1, [%o3] ASI_DTLB_DATA_ACCESS
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 58dc224f9..68147d4d4 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.146 2000/02/09 21:11:09 davem Exp $
+/* $Id: init.c,v 1.147 2000/03/03 23:48:44 davem Exp $
* arch/sparc64/mm/init.c
*
* Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -230,6 +230,14 @@ static void inherit_prom_mappings(void)
/* Now fixup OBP's idea about where we really are mapped. */
prom_printf("Remapping the kernel... ");
+
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
phys_page = spitfire_get_dtlb_data(63) & _PAGE_PADDR;
phys_page += ((unsigned long)&prom_boot_page -
(unsigned long)&empty_zero_page);
@@ -252,11 +260,27 @@ static void inherit_prom_mappings(void)
: "memory");
tte_vaddr = (unsigned long) &empty_zero_page;
+
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
kern_locked_tte_data = tte_data = spitfire_get_dtlb_data(63);
remap_func = (void *) ((unsigned long) &prom_remap -
(unsigned long) &prom_boot_page);
+
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
remap_func(spitfire_get_dtlb_data(63) & _PAGE_PADDR,
(unsigned long) &empty_zero_page,
prom_get_mmu_ihandle());
@@ -319,8 +343,16 @@ static void __flush_nucleus_vptes(void)
/* Only DTLB must be checked for VPTE entries. */
for(i = 0; i < 63; i++) {
- unsigned long tag = spitfire_get_dtlb_tag(i);
+ unsigned long tag;
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
+ tag = spitfire_get_dtlb_tag(i);
if(((tag & ~(PAGE_MASK)) == 0) &&
((tag & (PAGE_MASK)) >= prom_reserved_base)) {
__asm__ __volatile__("stxa %%g0, [%0] %1"
@@ -436,10 +468,26 @@ void inherit_locked_prom_mappings(int save_p)
for(i = 0; i < 63; i++) {
unsigned long data;
+
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
data = spitfire_get_dtlb_data(i);
if((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {
- unsigned long tag = spitfire_get_dtlb_tag(i);
+ unsigned long tag;
+
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+ tag = spitfire_get_dtlb_tag(i);
if(save_p) {
prom_dtlb[dtlb_seen].tlb_ent = i;
prom_dtlb[dtlb_seen].tlb_tag = tag;
@@ -459,10 +507,25 @@ void inherit_locked_prom_mappings(int save_p)
for(i = 0; i < 63; i++) {
unsigned long data;
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
data = spitfire_get_itlb_data(i);
if((data & (_PAGE_L|_PAGE_VALID)) == (_PAGE_L|_PAGE_VALID)) {
- unsigned long tag = spitfire_get_itlb_tag(i);
+ unsigned long tag;
+
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+ tag = spitfire_get_itlb_tag(i);
if(save_p) {
prom_itlb[itlb_seen].tlb_ent = i;
prom_itlb[itlb_seen].tlb_tag = tag;
@@ -544,6 +607,13 @@ void __flush_tlb_all(void)
: "=r" (pstate)
: "i" (PSTATE_IE));
for(i = 0; i < 64; i++) {
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
if(!(spitfire_get_dtlb_data(i) & _PAGE_L)) {
__asm__ __volatile__("stxa %%g0, [%0] %1"
: /* no outputs */
@@ -552,6 +622,14 @@ void __flush_tlb_all(void)
spitfire_put_dtlb_data(i, 0x0UL);
membar("#Sync");
}
+
+ /* Spitfire Errata #32 workaround */
+ __asm__ __volatile__("stxa %0, [%1] %2\n\t"
+ "flush %%g6"
+ : /* No outputs */
+ : "r" (0),
+ "r" (PRIMARY_CONTEXT), "i" (ASI_DMMU));
+
if(!(spitfire_get_itlb_data(i) & _PAGE_L)) {
__asm__ __volatile__("stxa %%g0, [%0] %1"
: /* no outputs */
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S
index 0825b0585..210db79e6 100644
--- a/arch/sparc64/mm/ultra.S
+++ b/arch/sparc64/mm/ultra.S
@@ -1,4 +1,4 @@
-/* $Id: ultra.S,v 1.37 2000/02/14 02:52:04 davem Exp $
+/* $Id: ultra.S,v 1.38 2000/03/03 23:48:44 davem Exp $
* ultra.S: Don't expand these all over the place...
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -35,7 +35,7 @@ __flush_tlb_mm: /* %o0=(ctx & 0x3ff), %o1=SECONDARY_CONTEXT */
__flush_tlb_range: /* %o0=(ctx&0x3ff), %o1=start&PAGE_MASK, %o2=SECONDARY_CONTEXT,
* %o3=end&PAGE_MASK, %o4=PAGE_SIZE, %o5=(end - start)
*/
-#define TLB_MAGIC 206 /* Students, do you know how I calculated this? -DaveM */
+#define TLB_MAGIC 207 /* Students, do you know how I calculated this? -DaveM */
/*IC3*/ cmp %o5, %o4
be,pt %xcc, __flush_tlb_page
srlx %o5, 13, %g5
@@ -58,6 +58,12 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
wrpr %g1, PSTATE_IE, %pstate
mov TLB_TAG_ACCESS, %g3
mov (62 << 3), %g2
+
+ /* Spitfire Errata #32 workaround. */
+ mov 0x8, %o4
+ stxa %g0, [%o4] ASI_DMMU
+ flush %g6
+
1: ldxa [%g2] ASI_ITLB_TAG_READ, %o4
and %o4, 0x3ff, %o5
cmp %o5, %o0
@@ -83,12 +89,27 @@ __flush_tlb_range_constant_time: /* %o0=ctx, %o1=start, %o3=end */
wrpr %g1, 0x0, %pstate
4: stxa %g0, [%g3] ASI_IMMU
stxa %g0, [%g2] ASI_ITLB_DATA_ACCESS
+ flush %g6
+
+ /* Spitfire Errata #32 workaround. */
+ mov 0x8, %o4
+ stxa %g0, [%o4] ASI_DMMU
+ flush %g6
+
ba,pt %xcc, 2b
- flush %g6
+ nop
+
5: stxa %g0, [%g3] ASI_DMMU
/*IC9*/ stxa %g0, [%g2] ASI_DTLB_DATA_ACCESS
+ flush %g6
+
+ /* Spitfire Errata #32 workaround. */
+ mov 0x8, %o4
+ stxa %g0, [%o4] ASI_DMMU
+ flush %g6
+
ba,pt %xcc, 3b
- flush %g6
+ nop
.align 32
__flush_tlb_mm_slow:
@@ -293,28 +314,51 @@ xcall_receive_signal:
clr %l6
99: retry
+ .data
+
+errata32_hwbug:
+ .xword 0
+
+ .text
+
/* These two are not performance critical... */
.globl xcall_flush_tlb_all
xcall_flush_tlb_all:
+
+ /* Spitfire Errata #32 workaround. */
+ sethi %hi(errata32_hwbug), %g4
+ stx %g0, [%g4 + %lo(errata32_hwbug)]
+
clr %g2
clr %g3
1: ldxa [%g3] ASI_DTLB_DATA_ACCESS, %g4
and %g4, _PAGE_L, %g5
brnz,pn %g5, 2f
mov TLB_TAG_ACCESS, %g7
+
stxa %g0, [%g7] ASI_DMMU
membar #Sync
-
stxa %g0, [%g3] ASI_DTLB_DATA_ACCESS
membar #Sync
+
+ /* Spitfire Errata #32 workaround. */
+ sethi %hi(errata32_hwbug), %g4
+ stx %g0, [%g4 + %lo(errata32_hwbug)]
+
2: ldxa [%g3] ASI_ITLB_DATA_ACCESS, %g4
and %g4, _PAGE_L, %g5
brnz,pn %g5, 2f
mov TLB_TAG_ACCESS, %g7
+
stxa %g0, [%g7] ASI_IMMU
membar #Sync
-
stxa %g0, [%g3] ASI_ITLB_DATA_ACCESS
+ membar #Sync
+
+ /* Spitfire Errata #32 workaround. */
+ sethi %hi(errata32_hwbug), %g4
+ stx %g0, [%g4 + %lo(errata32_hwbug)]
+
2: add %g2, 1, %g2
cmp %g2, 63
ble,pt %icc, 1b