summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/config.in7
-rw-r--r--arch/alpha/defconfig2
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c2
-rw-r--r--arch/alpha/kernel/process.c32
-rw-r--r--arch/arm/Makefile38
-rw-r--r--arch/arm/boot/compressed/Makefile2
-rw-r--r--arch/arm/boot/compressed/head.S31
-rw-r--r--arch/arm/config.in22
-rw-r--r--arch/arm/defconfig2
-rw-r--r--arch/arm/kernel/armksyms.c10
-rw-r--r--arch/arm/kernel/bios32.c437
-rw-r--r--arch/arm/kernel/dec21285.c161
-rw-r--r--arch/arm/kernel/ecard.c12
-rw-r--r--arch/arm/kernel/process.c28
-rw-r--r--arch/arm/kernel/setup.c301
-rw-r--r--arch/arm/kernel/sys_arm.c2
-rw-r--r--arch/arm/kernel/traps.c41
-rw-r--r--arch/arm/mm/fault-armv.c12
-rw-r--r--arch/arm/mm/fault-common.c18
-rw-r--r--arch/arm/mm/init.c292
-rw-r--r--arch/arm/mm/map.h12
-rw-r--r--arch/arm/mm/mm-armo.c116
-rw-r--r--arch/arm/mm/mm-armv.c249
-rw-r--r--arch/arm/mm/mm-ebsa110.c10
-rw-r--r--arch/arm/mm/mm-footbridge.c10
-rw-r--r--arch/arm/mm/mm-nexuspci.c10
-rw-r--r--arch/arm/mm/mm-rpc.c22
-rw-r--r--arch/arm/mm/mm-tbox.c10
-rw-r--r--arch/arm/mm/proc-arm2,3.S2
-rw-r--r--arch/arm/mm/proc-arm6,7.S2
-rw-r--r--arch/arm/mm/proc-sa110.S4
-rw-r--r--arch/arm/mm/small_page.c314
-rw-r--r--arch/arm/vmlinux-armo.lds.in22
-rw-r--r--arch/i386/boot/compressed/misc.c1
-rw-r--r--arch/i386/config.in6
-rw-r--r--arch/i386/defconfig15
-rw-r--r--arch/i386/kernel/Makefile3
-rw-r--r--arch/i386/kernel/apm.c494
-rw-r--r--arch/i386/kernel/entry.S5
-rw-r--r--arch/i386/kernel/head.S1
-rw-r--r--arch/i386/kernel/i386_ksyms.c2
-rw-r--r--arch/i386/kernel/irq.c13
-rw-r--r--arch/i386/kernel/mca.c280
-rw-r--r--arch/i386/kernel/mtrr.c4
-rw-r--r--arch/i386/kernel/process.c47
-rw-r--r--arch/i386/kernel/setup.c21
-rw-r--r--arch/i386/kernel/smpboot.c6
-rw-r--r--arch/i386/kernel/sys_i386.c131
-rw-r--r--arch/i386/lib/mmx.c12
-rw-r--r--arch/i386/math-emu/README11
-rw-r--r--arch/i386/math-emu/fpu_trig.c35
-rw-r--r--arch/i386/math-emu/poly.h25
-rw-r--r--arch/i386/math-emu/poly_sin.c22
-rw-r--r--arch/i386/math-emu/poly_tan.c16
-rw-r--r--arch/i386/math-emu/reg_round.S2
-rw-r--r--arch/i386/math-emu/version.h6
-rw-r--r--arch/i386/mm/init.c124
-rw-r--r--arch/m68k/config.in5
-rw-r--r--arch/m68k/defconfig2
-rw-r--r--arch/m68k/kernel/m68k_ksyms.c2
-rw-r--r--arch/m68k/kernel/process.c35
-rw-r--r--arch/m68k/mac/iop.c23
-rw-r--r--arch/m68k/math-emu/fp_emu.h8
-rw-r--r--arch/mips/config.in5
-rw-r--r--arch/mips/defconfig33
-rw-r--r--arch/mips/kernel/ipc.c129
-rw-r--r--arch/mips/kernel/irixelf.c12
-rw-r--r--arch/mips/kernel/mips_ksyms.c3
-rw-r--r--arch/mips/kernel/process.c36
-rw-r--r--arch/mips/kernel/scall_o32.S3
-rw-r--r--arch/mips/kernel/syscalls.h5
-rw-r--r--arch/mips/mm/init.c18
-rw-r--r--arch/mips/mm/umap.c2
-rw-r--r--arch/mips64/Makefile3
-rw-r--r--arch/mips64/config.in6
-rw-r--r--arch/mips64/defconfig1
-rw-r--r--arch/mips64/defconfig-ip229
-rw-r--r--arch/mips64/defconfig-ip271
-rw-r--r--arch/mips64/kernel/mips64_ksyms.c4
-rw-r--r--arch/mips64/kernel/process.c36
-rw-r--r--arch/mips64/kernel/r4k_tlb_debug.c5
-rw-r--r--arch/mips64/kernel/scall_o32.S5
-rw-r--r--arch/mips64/kernel/syscall.c133
-rw-r--r--arch/mips64/mm/init.c19
-rw-r--r--arch/mips64/mm/umap.c4
-rw-r--r--arch/ppc/amiga/Makefile3
-rw-r--r--arch/ppc/amiga/amiints.c50
-rw-r--r--arch/ppc/amiga/cia.c236
-rw-r--r--arch/ppc/amiga/config.c5
-rw-r--r--arch/ppc/common_defconfig165
-rw-r--r--arch/ppc/config.in24
-rw-r--r--arch/ppc/defconfig313
-rw-r--r--arch/ppc/kernel/Makefile8
-rw-r--r--arch/ppc/kernel/apus_setup.c244
-rw-r--r--arch/ppc/kernel/chrp_setup.c26
-rw-r--r--arch/ppc/kernel/entry.S2
-rw-r--r--arch/ppc/kernel/head.S157
-rw-r--r--arch/ppc/kernel/irq.c38
-rw-r--r--arch/ppc/kernel/mk_defs.c3
-rw-r--r--arch/ppc/kernel/pmac_setup.c6
-rw-r--r--arch/ppc/kernel/pmac_support.c4
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c3
-rw-r--r--arch/ppc/kernel/prep_setup.c2
-rw-r--r--arch/ppc/kernel/process.c117
-rw-r--r--arch/ppc/kernel/setup.c7
-rw-r--r--arch/ppc/kernel/traps.c36
-rw-r--r--arch/ppc/lib/checksum.S4
-rw-r--r--arch/ppc/mm/extable.c7
-rw-r--r--arch/ppc/mm/init.c6
-rw-r--r--arch/sh/Makefile2
-rw-r--r--arch/sh/config.in29
-rw-r--r--arch/sh/defconfig19
-rw-r--r--arch/sh/kernel/entry.S60
-rw-r--r--arch/sh/kernel/head.S7
-rw-r--r--arch/sh/kernel/irq.c2
-rw-r--r--arch/sh/kernel/irq_onchip.c128
-rw-r--r--arch/sh/kernel/process.c4
-rw-r--r--arch/sh/kernel/setup.c24
-rw-r--r--arch/sh/kernel/signal.c2
-rw-r--r--arch/sh/kernel/sys_sh.c5
-rw-r--r--arch/sh/kernel/time.c14
-rw-r--r--arch/sh/kernel/traps.c2
-rw-r--r--arch/sh/lib/checksum.S4
-rw-r--r--arch/sh/lib/memcpy.S2
-rw-r--r--arch/sh/lib/memmove.S2
-rw-r--r--arch/sh/lib/memset.S2
-rw-r--r--arch/sh/mm/cache.c2
-rw-r--r--arch/sh/mm/extable.c2
-rw-r--r--arch/sh/mm/fault.c104
-rw-r--r--arch/sh/mm/init.c7
-rw-r--r--arch/sh/mm/ioremap.c2
-rw-r--r--arch/sh/vmlinux.lds.S2
-rw-r--r--arch/sparc/config.in208
-rw-r--r--arch/sparc/defconfig2
-rw-r--r--arch/sparc/kernel/process.c34
-rw-r--r--arch/sparc/kernel/signal.c2
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c2
-rw-r--r--arch/sparc64/config.in251
-rw-r--r--arch/sparc64/defconfig2
-rw-r--r--arch/sparc64/kernel/process.c32
-rw-r--r--arch/sparc64/kernel/signal.c2
-rw-r--r--arch/sparc64/kernel/signal32.c2
-rw-r--r--arch/sparc64/kernel/sparc64_ksyms.c2
143 files changed, 3857 insertions, 2639 deletions
diff --git a/arch/alpha/config.in b/arch/alpha/config.in
index 7cb20bee3..f6dc93f61 100644
--- a/arch/alpha/config.in
+++ b/arch/alpha/config.in
@@ -172,6 +172,11 @@ bool 'Networking support' CONFIG_NET
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 a.out (ECOFF) binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
@@ -263,7 +268,7 @@ comment 'Kernel hacking'
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Kernel FP software completion' CONFIG_MATHEMU
else
- define_bool CONFIG_MATHEMU y
+ define_tristate CONFIG_MATHEMU y
fi
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig
index 186505eda..54a05ea5a 100644
--- a/arch/alpha/defconfig
+++ b/arch/alpha/defconfig
@@ -47,6 +47,8 @@ CONFIG_PCI=y
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
CONFIG_SYSCTL=y
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index f280e4541..ffd93ca9d 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -206,3 +206,5 @@ EXPORT_SYMBOL_NOVERS(__remq);
EXPORT_SYMBOL_NOVERS(__remqu);
EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(memset);
+
+EXPORT_SYMBOL(get_wchan);
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 354597ba2..0390e3138 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -406,3 +406,35 @@ 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;
+ /*
+ * This one depends on the frame size of schedule(). Do a
+ * "disass schedule" in gdb to find the frame size. Also, the
+ * code assumes that sleep_on() follows immediately after
+ * interruptible_sleep_on() and that add_timer() follows
+ * immediately after interruptible_sleep(). Ugly, isn't it?
+ * Maybe adding a wchan field to task_struct would be better,
+ * after all...
+ */
+
+ pc = thread_saved_pc(&p->thread);
+ if (pc >= first_sched && pc < last_sched) {
+ schedule_frame = ((unsigned long *)p->thread.ksp)[6];
+ return ((unsigned long *)schedule_frame)[12];
+ }
+ return pc;
+}
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 0895fc0ba..f8c91aca3 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -16,10 +16,10 @@ LD := $(CROSS_COMPILE)ld
OBJCOPY := $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
CPP := $(CC) -E
PERL := perl
-LINKFLAGS := -X -T arch/arm/vmlinux.lds
+LINKFLAGS := -p -X -T arch/arm/vmlinux.lds
ARCHCC := $(word 1,$(CC))
-
+AFLAGS += -mno-fpu
CFLAGS_PIPE := -pipe
CFLAGS := $(CFLAGS) $(CFLAGS_PIPE)
@@ -31,6 +31,15 @@ ifdef CONFIG_DEBUG_INFO
CFLAGS += -g
endif
+# Ensure this is ld "2.9.4" or later
+NEW_LINKER := $(shell if $(LD) --gc-sections --version >/dev/null 2>&1; then echo y; else echo n; fi)
+
+ifneq ($(NEW_LINKER),y)
+dummy:; @echo '*** 2.3 kernels no longer build correctly with old versions of binutils.'
+ @echo '*** Please upgrade your binutils to 2.9.5.'
+ @false
+endif
+
# GCC 2.7 uses different options to later compilers; sort out which we have
NEW_GCC := $(shell if $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; then echo n; else echo y; fi)
@@ -55,21 +64,6 @@ CFLAGS_ARM7 := -m6
CFLAGS_SA110 := -m6
endif
-# See if this is ld "2.9.4" or later
-NEW_LINKER := $(shell if $(LD) --gc-sections --version >/dev/null 2>&1; then echo y; else echo n; fi)
-
-ifeq ($(NEW_LINKER),y)
-AFLAGS += -mno-fpu
-AFLAGS_PROC_CPU_26 := -mapcs-26
-AFLAGS_PROC_CPU_32v3 := -mapcs-32 -marmv3m
-AFLAGS_PROC_CPU_32v4 := -mapcs-32 -marmv4t
-LINKFLAGS := -p $(LINKFLAGS)
-else
-AFLAGS_PROC_CPU_26 := -m3
-AFLAGS_PROC_CPU_32v3 := -m6
-AFLAGS_PROC_CPU_32v4 := -m6
-endif
-
#
# Select CPU dependent flags
#
@@ -77,7 +71,7 @@ ifeq ($(CONFIG_CPU_26),y)
PROCESSOR = armo
TEXTADDR = 0x02080000
CFLAGS += $(CFLAGS_PROC_CPU_26)
- AFLAGS += $(AFLAGS_PROC_CPU_26)
+ AFLAGS += -mapcs-26
endif
ifeq ($(CONFIG_CPU_32),y)
@@ -85,10 +79,10 @@ ifeq ($(CONFIG_CPU_32),y)
TEXTADDR = 0xC0008000
ifeq ($(CONFIG_CPU_32v4),y)
CFLAGS += $(CFLAGS_PROC_CPU_32v4)
- AFLAGS += $(AFLAGS_PROC_CPU_32v4)
+ AFLAGS += -mapcs-32 -marmv4
else
CFLAGS += $(CFLAGS_PROC_CPU_32v3)
- AFLAGS += $(AFLAGS_PROC_CPU_32v3)
+ AFLAGS += -mapcs-32 -marmv3m
endif
#
# Exactly one of the following must be selected
@@ -156,7 +150,7 @@ LIBS := arch/arm/lib/lib.a $(LIBS) $(GCCLIB)
DRIVERS += arch/arm/special/special.a
ifeq ($(CONFIG_NWFPE),y)
-CORE_FILES += arch/arm/nwfpe/math-emu.o
+LIBS := arch/arm/nwfpe/math-emu.o $(LIBS)
endif
ifeq ($(CONFIG_ARCH_ACORN),y)
@@ -173,7 +167,7 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
# to date before starting compilation
CONSTANTS := constants
-constants: dummy
+constants: $(TOPDIR)/include/asm-arm/proc-fns.h dummy
@$(MAKE) -C arch/arm/lib constants.h
symlinks: archsymlinks
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 3c0478ab3..a9d71cb7b 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -8,7 +8,7 @@ OBJS = misc.o
SYSTEM = $(TOPDIR)/vmlinux
CFLAGS = -O2 -DSTDC_HEADERS $(CFLAGS_PROC)
FONTC = $(TOPDIR)/drivers/video/font_acorn_8x8.c
-ZLDFLAGS = -X -T vmlinux.lds
+ZLDFLAGS = -p -X -T vmlinux.lds
#
# Architecture dependencies
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 721967e4b..e87c0a72e 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -96,6 +96,8 @@ start:
*/
reloc_start: add r8, r5, r0
#if 0
+ mov r0, #'\n'
+ bl putc
mov r0, r6
mov r1, #8
bl phex
@@ -139,8 +141,8 @@ reloc_start: add r8, r5, r0
bl phex
mov r0, #'\n'
bl putc
- mov r0, r4
- bl memdump
+ mov r0, r4
+ bl memdump
#endif
eor r0, r6, #0x44 << 24 @ SA-110?
eor r0, r0, #0x01 << 16
@@ -155,6 +157,25 @@ call_kernel: mov r0, #0
phexbuf: .space 12
+#if 0
+ .macro loadsp, rb
+ mov \rb, #0x7c000000
+ .endm
+
+ .macro writeb, rb
+ strb \rb, [r3, #0x3f8]
+ .endm
+#else
+ .macro loadsp, rb
+ mov \rb, #0x03000000
+ orr \rb, \rb, #0x00010000
+ .endm
+
+ .macro writeb, rb
+ strb \rb, [r3, #0x3f8 << 2]
+ .endm
+#endif
+
phex: adr r3, phexbuf
mov r2, #0
strb r2, [r3, r1]
@@ -169,11 +190,11 @@ phex: adr r3, phexbuf
strb r2, [r3, r1]
b 1b
-puts: mov r3, #0x7c000000
+puts: loadsp r3
1: ldrb r2, [r0], #1
teq r2, #0
moveq pc, lr
-2: strb r2, [r3, #0x3f8]
+2: writeb r2
mov r1, #0x00020000
3: subs r1, r1, #1
bne 3b
@@ -186,7 +207,7 @@ puts: mov r3, #0x7c000000
putc:
mov r2, r0
mov r0, #0
- mov r3, #0x7c000000
+ loadsp r3
b 2b
memdump: mov r12, r0
diff --git a/arch/arm/config.in b/arch/arm/config.in
index 3e0bcd0f3..249759e1a 100644
--- a/arch/arm/config.in
+++ b/arch/arm/config.in
@@ -21,6 +21,7 @@ choice 'ARM system type' \
EBSA-110 CONFIG_ARCH_EBSA110 \
FootBridge-based CONFIG_FOOTBRIDGE" RiscPC
# SA1100-based CONFIG_ARCH_SA1100
+
if [ "$CONFIG_FOOTBRIDGE" = "y" ]; then
bool 'FootBridge in HOST mode' CONFIG_HOST_FOOTBRIDGE
if [ "$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then
@@ -45,13 +46,13 @@ fi
if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
define_bool CONFIG_CPU_SA1100 y
choice 'SA1100 implementation' \
- "Brutus CONFIG_SA1100_BRUTUS \
- empeg CONFIG_SA1100_EMPEG \
- Itsy CONFIG_SA1100_ITSY \
- LART CONFIG_SA1100_LART \
- PLEB CONFIG_SA1100_PLEB \
- Victor CONFIG_SA1100_VICTOR \
- Tifon CONFIG_SA1100_TIFON" Brutus
+ "Brutus CONFIG_SA1100_BRUTUS \
+ Empeg CONFIG_SA1100_EMPEG \
+ Itsy CONFIG_SA1100_ITSY \
+ LART CONFIG_SA1100_LART \
+ PLEB CONFIG_SA1100_PLEB \
+ Victor CONFIG_SA1100_VICTOR \
+ Tifon CONFIG_SA1100_TIFON" Brutus
fi
#
@@ -121,8 +122,6 @@ else
define_bool CONFIG_ISA_DMA n
fi
-endmenu
-
if [ "$CONFIG_CPU_32" = "y" -a "$CONFIG_ARCH_EBSA110" != "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'Enable kernel-mode alignment trap handler (EXPERIMENTAL)' CONFIG_ALIGNMENT_TRAP
fi
@@ -145,6 +144,11 @@ bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
bool 'Sysctl support' CONFIG_SYSCTL
tristate 'Math emulation' CONFIG_NWFPE
+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 a.out binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
diff --git a/arch/arm/defconfig b/arch/arm/defconfig
index d289870ea..ef7d1e315 100644
--- a/arch/arm/defconfig
+++ b/arch/arm/defconfig
@@ -49,6 +49,8 @@ CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
CONFIG_NWFPE=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index ebb2f150d..43cc0574f 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -12,6 +12,7 @@
#include <asm/byteorder.h>
#include <asm/elf.h>
#include <asm/io.h>
+#include <asm/irq.h>
#include <asm/dma.h>
#include <asm/pgtable.h>
#include <asm/proc-fns.h>
@@ -98,7 +99,8 @@ EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(system_rev);
EXPORT_SYMBOL(system_serial_low);
EXPORT_SYMBOL(system_serial_high);
-
+EXPORT_SYMBOL(__bug);
+EXPORT_SYMBOL(__readwrite_bug);
EXPORT_SYMBOL(enable_irq);
EXPORT_SYMBOL(disable_irq);
@@ -152,8 +154,8 @@ EXPORT_SYMBOL(__bus_to_virt);
#ifndef CONFIG_NO_PGT_CACHE
EXPORT_SYMBOL(quicklists);
#endif
-EXPORT_SYMBOL(__bad_pmd);
-EXPORT_SYMBOL(__bad_pmd_kernel);
+EXPORT_SYMBOL(__handle_bad_pmd);
+EXPORT_SYMBOL(__handle_bad_pmd_kernel);
/* string / mem functions */
EXPORT_SYMBOL_NOVERS(strcpy);
@@ -235,3 +237,5 @@ EXPORT_SYMBOL_NOVERS(__down_failed);
EXPORT_SYMBOL_NOVERS(__down_interruptible_failed);
EXPORT_SYMBOL_NOVERS(__down_trylock_failed);
EXPORT_SYMBOL_NOVERS(__up_wakeup);
+
+EXPORT_SYMBOL(get_wchan);
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 3bd7a7358..28c12d3e8 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -13,16 +13,14 @@
#include <asm/irq.h>
#include <asm/system.h>
-int have_isa_bridge;
+#include "bios32.h"
-int (*pci_irq_fixup)(struct pci_dev *dev);
+static int debug_pci;
+int have_isa_bridge;
-extern struct pci_ops *dc21285_init(int pass);
-extern void pcibios_fixup_ebsa285(struct pci_dev *dev);
extern void hw_init(void);
-void
-pcibios_report_device_errors(void)
+void pcibios_report_device_errors(void)
{
struct pci_dev *dev;
@@ -31,16 +29,17 @@ pcibios_report_device_errors(void)
pci_read_config_word(dev, PCI_STATUS, &status);
- if (status & 0xf900) {
- pci_write_config_word(dev, PCI_STATUS, status & 0xf900);
- printk(KERN_DEBUG "PCI: %02x:%02x status = %X\n",
- dev->bus->number, dev->devfn, status);
- }
+ if ((status & 0xf900) == 0)
+ continue;
+
+ pci_write_config_word(dev, PCI_STATUS, status & 0xf900);
+ printk(KERN_DEBUG "PCI: status %04X on %s\n",
+ status, dev->name);
}
}
/*
- * We don't use this to fix the device, but more our initialisation.
+ * We don't use this to fix the device, but initialisation of it.
* It's not the correct use for this, but it works. The actions we
* take are:
* - enable only IO
@@ -68,196 +67,108 @@ static void __init pci_fixup_83c553(struct pci_dev *dev)
pci_write_config_byte(dev, 0x81, 0x01);
}
-struct pci_fixup pcibios_fixups[] = {
- { PCI_FIXUP_HEADER, PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, pci_fixup_83c553 },
- { 0 }
-};
-
-/*
- * Assign new address to PCI resource. We hope our resource information
- * is complete. On the PC, we don't re-assign resources unless we are
- * forced to do so.
- *
- * Expects start=0, end=size-1, flags=resource type.
- */
-
-int __init pcibios_assign_resource(struct pci_dev *dev, int i)
+static void __init pci_fixup_unassign(struct pci_dev *dev)
{
- struct resource *r = &dev->resource[i];
- struct resource *pr = pci_find_parent_resource(dev, r);
- unsigned long size = r->end + 1;
- unsigned long flags = 0;
-
- if (!pr)
- return -EINVAL;
- if (r->flags & IORESOURCE_IO) {
- if (size > 0x100)
- return -EFBIG;
- if (allocate_resource(pr, r, size, 0x9000, ~0, 1024))
- return -EBUSY;
- flags = PCI_BASE_ADDRESS_SPACE_IO;
- } else {
- if (allocate_resource(pr, r, size, 0x00100000, 0x7fffffff, size))
- return -EBUSY;
- }
- if (i < 6)
- pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + 4*i, r->start | flags);
- return 0;
+ dev->resource[0].end -= dev->resource[0].start;
+ dev->resource[0].start = 0;
}
/*
- * Assign an address to an I/O range.
+ * PCI IDE controllers use non-standard I/O port
+ * decoding, respect it.
*/
-static void __init pcibios_fixup_io_addr(struct pci_dev *dev, struct resource *r, int idx)
+static void __init pci_fixup_ide_bases(struct pci_dev *dev)
{
- unsigned int reg = PCI_BASE_ADDRESS_0 + (idx << 2);
- unsigned int size = r->end - r->start + 1;
- u32 try;
+ struct resource *r;
+ int i;
- /*
- * We need to avoid collisions with `mirrored' VGA ports and other strange
- * ISA hardware, so we always want the addresses kilobyte aligned.
- */
- if (!size || size > 256) {
- printk(KERN_ERR "PCI: Cannot assign I/O space to %s, "
- "%d bytes are too much.\n", dev->name, size);
+ if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE)
return;
- }
-
- if (allocate_resource(&ioport_resource, r, size, 0x9000, ~0, 1024)) {
- printk(KERN_ERR "PCI: Unable to find free %d bytes of I/O "
- "space for %s.\n", size, dev->name);
- return;
- }
- printk("PCI: Assigning I/O space %04lx-%04lx to %s\n",
- r->start, r->end, dev->name);
-
- pci_write_config_dword(dev, reg, r->start | PCI_BASE_ADDRESS_SPACE_IO);
- pci_read_config_dword(dev, reg, &try);
-
- if ((try & PCI_BASE_ADDRESS_IO_MASK) != r->start) {
- r->start = 0;
- pci_write_config_dword(dev, reg, 0);
- printk(KERN_ERR "PCI: I/O address setup failed, got %04x\n", try);
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ r = dev->resource + i;
+ if ((r->start & ~0x80) == 0x374) {
+ r->start |= 2;
+ r->end = r->start;
+ }
}
}
+struct pci_fixup pcibios_fixups[] = {
+ {
+ PCI_FIXUP_HEADER,
+ PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553,
+ pci_fixup_83c553
+ }, {
+ PCI_FIXUP_HEADER,
+ PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940F,
+ pci_fixup_unassign
+ }, {
+ PCI_FIXUP_HEADER,
+ PCI_ANY_ID, PCI_ANY_ID,
+ pci_fixup_ide_bases
+ }, { 0 }
+};
+
/*
- * Assign an address to an memory range.
+ * Allocate resources for all PCI devices that have been enabled.
+ * We need to do that before we try to fix up anything.
*/
-static void __init pcibios_fixup_mem_addr(struct pci_dev *dev, struct resource *r, int idx)
+static void __init pcibios_claim_resources(void)
{
- unsigned int reg = PCI_BASE_ADDRESS_0 + (idx << 2);
- unsigned int size = r->end - r->start + 1;
- u32 try;
-
- if (!size) {
- printk(KERN_ERR "PCI: Cannot assign memory space to %s, "
- "%d bytes are too much.\n", dev->name, size);
- return;
- }
-
- if (allocate_resource(&iomem_resource, r, size,
- 0x00100000, 0x0fffffff, 1024)) {
- printk(KERN_ERR "PCI: Unable to find free %d bytes of memory "
- "space for %s.\n", size, dev->name);
- return;
- }
-
- printk("PCI: Assigning memory space %08lx-%08lx to %s\n",
- r->start, r->end, dev->name);
-
- pci_write_config_dword(dev, reg, r->start);
- pci_read_config_dword(dev, reg, &try);
+ struct pci_dev *dev;
+ int idx;
- if (try != r->start) {
- r->start = 0;
- pci_write_config_dword(dev, reg, 0);
- printk(KERN_ERR "PCI: memory address setup failed, "
- "got %08x\n", try);
- }
+ for (dev = pci_devices; dev; dev = dev->next)
+ for (idx = 0; idx < PCI_NUM_RESOURCES; idx++)
+ if (dev->resource[idx].flags &&
+ dev->resource[idx].start)
+ pci_claim_resource(dev, idx);
}
-#define _PCI_REGION_IO 1
-#define _PCI_REGION_MEM 2
-
-/*
- * Fix up one PCI devices regions, enables and interrupt lines
- */
-static void __init pcibios_fixup_device(struct pci_dev *dev, u16 *cmd)
+void __init
+pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+ struct resource *res, int resource)
{
- int i, has_regions = 0;
-
- /*
- * Fix up the regions. Any regions which aren't allocated
- * are given a free region.
- */
- for (i = 0; i < 6; i++) {
- struct resource *r = dev->resource + i;
+ unsigned long where, size;
+ u32 reg;
- if (r->flags & IORESOURCE_IO) {
- has_regions |= _PCI_REGION_IO;
+ if (debug_pci)
+ printk("PCI: Assigning %3s %08lx to %s\n",
+ res->flags & IORESOURCE_IO ? "IO" : "MEM",
+ res->start, dev->name);
- if (!r->start || r->end == 0xffffffff)
- pcibios_fixup_io_addr(dev, r, i);
- } else if (r->end) {
- has_regions |= _PCI_REGION_MEM;
+ where = PCI_BASE_ADDRESS_0 + resource * 4;
+ size = res->end - res->start;
- if (!r->start)
- pcibios_fixup_mem_addr(dev, r, i);
- }
- }
-
- switch (dev->class >> 8) {
- case PCI_CLASS_BRIDGE_ISA:
- case PCI_CLASS_BRIDGE_EISA:
- /*
- * If this device is an ISA bridge, set the have_isa_bridge
- * flag. We will then go looking for things like keyboard,
- * etc
- */
- have_isa_bridge = !0;
- /* FALL THROUGH */
-
- default:
- /*
- * Don't enable VGA-compatible cards since they have
- * fixed I/O and memory space.
- *
- * Don't enabled disabled IDE interfaces either because
- * some BIOSes may reallocate the same address when they
- * find that no devices are attached.
- */
- if (has_regions & _PCI_REGION_IO &&
- !((*cmd) & PCI_COMMAND_IO)) {
- printk("PCI: Enabling I/O for %s\n", dev->name);
- *cmd |= PCI_COMMAND_IO;
- }
+ pci_read_config_dword(dev, where, &reg);
+ reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
+ pci_write_config_dword(dev, where, reg);
+}
- if (has_regions & _PCI_REGION_MEM &&
- !((*cmd) & PCI_COMMAND_MEMORY)) {
- printk("PCI: Enabling memory for %s\n", dev->name);
- *cmd |= PCI_COMMAND_MEMORY;
- }
- }
+void __init pcibios_update_irq(struct pci_dev *dev, int irq)
+{
+ if (debug_pci)
+ printk("PCI: Assigning IRQ %02d to %s\n", irq, dev->name);
+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
}
/*
- * Fix base addresses, I/O and memory enables and IRQ's
+ * Called after each bus is probed, but before its children
+ * are examined.
*/
-static void __init pcibios_fixup_devices(void)
+void __init pcibios_fixup_bus(struct pci_bus *bus)
{
struct pci_dev *dev;
- for (dev = pci_devices; dev; dev = dev->next) {
+ for (dev = bus->devices; dev; dev = dev->sibling) {
u16 cmd;
/*
- * architecture specific hacks.
- * I don't really want this here,
- * but I don't see any other place
- * for it to live.
+ * architecture specific hacks. I don't really want
+ * this here, but I don't see any other place for it
+ * to live. Shame the device doesn't support
+ * capabilities
*/
if (machine_is_netwinder() &&
dev->vendor == PCI_VENDOR_ID_DEC &&
@@ -266,119 +177,165 @@ static void __init pcibios_fixup_devices(void)
pci_write_config_dword(dev, 0x40, 0x80000000);
/*
+ * If this device is an ISA bridge, set the have_isa_bridge
+ * flag. We will then go looking for things like keyboard,
+ * etc
+ */
+ if (dev->class >> 8 == PCI_CLASS_BRIDGE_ISA ||
+ dev->class >> 8 == PCI_CLASS_BRIDGE_EISA)
+ have_isa_bridge = !0;
+
+ /*
* Set latency timer to 32, and a cache line size to 32 bytes.
* Also, set system error enable, parity error enable, and
* fast back to back transaction enable. Disable ROM.
*/
pci_write_config_byte(dev, PCI_LATENCY_TIMER, 32);
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 8);
- pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
pci_read_config_word(dev, PCI_COMMAND, &cmd);
cmd |= PCI_COMMAND_FAST_BACK | PCI_COMMAND_SERR |
PCI_COMMAND_PARITY;
- pcibios_fixup_device(dev, &cmd);
-
pci_write_config_word(dev, PCI_COMMAND, cmd);
pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ pci_write_config_dword(dev, PCI_ROM_ADDRESS, 0);
+ }
+}
- /*
- * now fixup the IRQs, if required
- */
- if (pci_irq_fixup)
- dev->irq = pci_irq_fixup(dev);
+static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
+{
+ return 0;
+}
- /*
- * If any remaining IRQs are weird, fix it now.
- */
- if (dev->irq >= NR_IRQS)
- dev->irq = 0;
+/* ebsa285 host-specific stuff */
+static int irqmap_ebsa285[] __initdata = { IRQ_IN1, IRQ_IN0, IRQ_PCI, IRQ_IN3 };
- /*
- * catch any drivers still reading this from the
- * device itself. This can be removed once
- * all drivers are fixed. (are there any?)
- */
- pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
- }
+static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin)
+{
+ return PCI_SLOT(dev->devfn);
}
-/*
- * Allocate resources for all PCI devices that have been enabled.
- * We need to do that before we try to fix up anything.
- */
-static void __init pcibios_claim_resources(void)
+static int __init ebsa285_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
- struct pci_dev *dev;
- int idx;
+ return irqmap_ebsa285[(slot + pin) & 3];
+}
- for (dev = pci_devices; dev; dev = dev->next)
- for (idx = 0; idx < PCI_NUM_RESOURCES; idx++) {
- struct resource *a, *r = &dev->resource[idx];
-
- /*
- * Ignore regions that start at 0 or
- * end at 0xffffffff
- */
- if (!r->start || r->end == 0xffffffff)
- continue;
-
- if (r->flags & IORESOURCE_IO)
- a = &ioport_resource;
- else
- a = &iomem_resource;
-
- if (request_resource(a, r) < 0)
- printk(KERN_ERR "PCI: Address space collision "
- "on region %d of %s\n",
- idx, dev->name);
- /* We probably should disable the region,
- * shouldn't we?
- */
- }
+static struct hw_pci ebsa285_pci __initdata = {
+ dc21285_init,
+ 0x9000,
+ 0x00100000,
+ ebsa285_swizzle,
+ ebsa285_map_irq
+};
+
+/* cats host-specific stuff */
+static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
+
+static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (dev->irq >= 128)
+ return 16 + (dev->irq & 0x1f);
+
+ if (dev->irq >= 1 && dev->irq <= 4)
+ return irqmap_cats[dev->irq - 1];
+
+ if (dev->irq != 0)
+ printk("PCI: device %02x:%02x has unknown irq line %x\n",
+ dev->bus->number, dev->devfn, dev->irq);
+
+ return -1;
}
-/*
- * Called after each bus is probed, but before its children
- * are examined.
- *
- * No fixup of bus required
- */
-void __init pcibios_fixup_bus(struct pci_bus *bus)
+static struct hw_pci cats_pci __initdata = {
+ dc21285_init,
+ 0x9000,
+ 0x00100000,
+ no_swizzle,
+ cats_map_irq
+};
+
+/* netwinder host-specific stuff */
+static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
+#define DEV(v,d) ((v)<<16|(d))
+ switch (DEV(dev->vendor, dev->device)) {
+ case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142):
+ return IRQ_NETWINDER_ETHER100;
+
+ case DEV(PCI_VENDOR_ID_WINBOND2, 0x5a5a):
+ return IRQ_NETWINDER_ETHER10;
+
+ case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553):
+ return 0;
+
+ case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105):
+ return IRQ_ISA_HARDDISK1;
+
+ case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000):
+ return IRQ_NETWINDER_VGA;
+
+ default:
+ printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n",
+ dev->bus->number, dev->devfn,
+ dev->vendor, dev->device);
+ return 0;
+ }
}
+static struct hw_pci netwinder_pci __initdata = {
+ dc21285_init,
+ 0x9000,
+ 0x00100000,
+ no_swizzle,
+ netwinder_map_irq
+};
+
void __init pcibios_init(void)
{
- struct pci_ops *ops;
+ struct hw_pci *hw_pci = NULL;
+
+ if (machine_is_ebsa285())
+ hw_pci = &ebsa285_pci;
+ else if (machine_is_cats())
+ hw_pci = &cats_pci;
+ else if (machine_is_netwinder())
+ hw_pci = &netwinder_pci;
+
+ if (hw_pci == NULL)
+ return;
/*
- * Pre-initialisation. Set up the host bridge.
+ * Set up the host bridge, and scan the bus.
*/
- ops = dc21285_init(0);
+ hw_pci->init();
- printk("PCI: Probing PCI hardware\n");
-
- pci_scan_bus(0, ops, NULL);
+ /*
+ * Other architectures don't seem to do this... should we?
+ */
pcibios_claim_resources();
- pcibios_fixup_devices();
/*
- * Now clear down any PCI error IRQs and
- * register the error handler
+ * Assign any unassigned resources. Note that we really ought to
+ * have min/max stuff here - max mem address is 0x0fffffff
*/
- dc21285_init(1);
+ pci_assign_unassigned_resources(hw_pci->io_start, hw_pci->mem_start);
+ pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq);
+ pci_set_bus_ranges();
/*
- * Initialise any other hardware after we've
- * got the PCI bus initialised. We may need
- * the PCI bus to talk to this other hardware.
+ * Initialise any other hardware after we've got the PCI bus
+ * initialised. We may need the PCI bus to talk to this other
+ * hardware.
*/
hw_init();
}
char * __init pcibios_setup(char *str)
{
+ if (!strcmp(str, "debug")) {
+ debug_pci = 1;
+ return NULL;
+ }
return str;
}
diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c
index 42a9a616f..2622dec25 100644
--- a/arch/arm/kernel/dec21285.c
+++ b/arch/arm/kernel/dec21285.c
@@ -18,11 +18,12 @@
#include <asm/irq.h>
#include <asm/system.h>
+#include "bios32.h"
+
#define MAX_SLOTS 21
extern int setup_arm_irq(int, struct irqaction *);
extern void pcibios_report_device_errors(void);
-extern int (*pci_irq_fixup)(struct pci_dev *dev);
static unsigned long
dc21285_base_address(struct pci_dev *dev, int where)
@@ -202,129 +203,53 @@ static struct irqaction dc21285_error_action = {
dc21285_error, SA_INTERRUPT, 0, "PCI error", NULL, NULL
};
-static int irqmap_ebsa[] __initdata = { IRQ_IN1, IRQ_IN0, IRQ_PCI, IRQ_IN3 };
-
-static int __init ebsa_irqval(struct pci_dev *dev)
-{
- u8 pin;
-
- pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
-
- return irqmap_ebsa[(PCI_SLOT(dev->devfn) + pin) & 3];
-}
-
-static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
-
-static int __init cats_irqval(struct pci_dev *dev)
-{
- if (dev->irq >= 128)
- return 16 + (dev->irq & 0x1f);
-
- switch (dev->irq) {
- case 1 ... 4:
- return irqmap_cats[dev->irq - 1];
-
- default:
- printk("PCI: device %02x:%02x has unknown irq line %x\n",
- dev->bus->number, dev->devfn, dev->irq);
- case 0:
- break;
- }
- return 0;
-}
-
-static int __init netwinder_irqval(struct pci_dev *dev)
-{
-#define DEV(v,d) ((v)<<16|(d))
- switch (DEV(dev->vendor, dev->device)) {
- case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142):
- return IRQ_NETWINDER_ETHER100;
-
- case DEV(PCI_VENDOR_ID_WINBOND2, 0x5a5a):
- return IRQ_NETWINDER_ETHER10;
-
- case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553):
- return 0;
-
- case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105):
- return IRQ_ISA_HARDDISK1;
-
- case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000):
- return IRQ_NETWINDER_VGA;
-
- default:
- printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n",
- dev->bus->number, dev->devfn,
- dev->vendor, dev->device);
- return 0;
- }
-}
-
-struct pci_ops * __init dc21285_init(int pass)
+void __init dc21285_init(void)
{
unsigned int mem_size;
unsigned long cntl;
- if (pass == 0) {
- mem_size = (unsigned int)high_memory - PAGE_OFFSET;
- *CSR_SDRAMBASEMASK = (mem_size - 1) & 0x0ffc0000;
- *CSR_SDRAMBASEOFFSET = 0;
- *CSR_ROMBASEMASK = 0x80000000;
- *CSR_CSRBASEMASK = 0;
- *CSR_CSRBASEOFFSET = 0;
- *CSR_PCIADDR_EXTN = 0;
+ mem_size = (unsigned int)high_memory - PAGE_OFFSET;
+ *CSR_SDRAMBASEMASK = (mem_size - 1) & 0x0ffc0000;
+ *CSR_SDRAMBASEOFFSET = 0;
+ *CSR_ROMBASEMASK = 0x80000000;
+ *CSR_CSRBASEMASK = 0;
+ *CSR_CSRBASEOFFSET = 0;
+ *CSR_PCIADDR_EXTN = 0;
#ifdef CONFIG_HOST_FOOTBRIDGE
- /*
- * Map our SDRAM at a known address in PCI space, just in case
- * the firmware had other ideas. Using a nonzero base is
- * necessary, since some VGA cards forcefully use PCI addresses
- * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
- */
- *CSR_PCICACHELINESIZE = 0x00002008;
- *CSR_PCICSRBASE = 0;
- *CSR_PCICSRIOBASE = 0;
- *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET);
- *CSR_PCIROMBASE = 0;
- *CSR_PCICMD = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
- PCI_COMMAND_MASTER | PCI_COMMAND_FAST_BACK |
- PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY |
- (1 << 31) | (1 << 29) | (1 << 28) | (1 << 24);
+ /*
+ * Map our SDRAM at a known address in PCI space, just in case
+ * the firmware had other ideas. Using a nonzero base is
+ * necessary, since some VGA cards forcefully use PCI addresses
+ * in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
+ */
+ *CSR_PCICACHELINESIZE = 0x00002008;
+ *CSR_PCICSRBASE = 0;
+ *CSR_PCICSRIOBASE = 0;
+ *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET);
+ *CSR_PCIROMBASE = 0;
+ *CSR_PCICMD = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_FAST_BACK |
+ PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY |
+ (1 << 31) | (1 << 29) | (1 << 28) | (1 << 24);
#endif
- printk(KERN_DEBUG"PCI: DC21285 footbridge, revision %02lX\n",
- *CSR_CLASSREV & 0xff);
-
- switch (machine_arch_type) {
- case MACH_TYPE_EBSA285:
- pci_irq_fixup = ebsa_irqval;
- break;
-
- case MACH_TYPE_CATS:
- pci_irq_fixup = cats_irqval;
- break;
-
- case MACH_TYPE_NETWINDER:
- pci_irq_fixup = netwinder_irqval;
- break;
- }
-
- return &dc21285_ops;
- } else {
- /*
- * Clear any existing errors - we aren't
- * interested in historical data...
- */
- cntl = *CSR_SA110_CNTL & 0xffffde07;
- *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR;
- cntl = *CSR_PCICMD & 0x0000ffff;
- *CSR_PCICMD = cntl | 1 << 31 | 1 << 29 | 1 << 28 | 1 << 24;
-
- /*
- * Initialise PCI error IRQ after we've finished probing
- */
- setup_arm_irq(IRQ_PCI_ERR, &dc21285_error_action);
-
- return NULL;
- }
+ printk(KERN_DEBUG"PCI: DC21285 footbridge, revision %02lX\n",
+ *CSR_CLASSREV & 0xff);
+
+ pci_scan_bus(0, &dc21285_ops, NULL);
+
+ /*
+ * Clear any existing errors - we aren't
+ * interested in historical data...
+ */
+ cntl = *CSR_SA110_CNTL & 0xffffde07;
+ *CSR_SA110_CNTL = cntl | SA110_CNTL_RXSERR;
+ cntl = *CSR_PCICMD & 0x0000ffff;
+ *CSR_PCICMD = cntl | 1 << 31 | 1 << 29 | 1 << 28 | 1 << 24;
+
+ /*
+ * Initialise PCI error IRQ after we've finished probing
+ */
+ setup_arm_irq(IRQ_PCI_ERR, &dc21285_error_action);
}
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index 99b2b2b1d..c777db993 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -888,19 +888,13 @@ int get_ecard_dev_info(char *buf, char **start, off_t pos, int count, int wr)
return (count > cnt) ? cnt : count;
}
-static struct proc_dir_entry proc_ecard_devices = {
- PROC_BUS_ECARD_DEVICES, 7, "devices",
- S_IFREG | S_IRUGO, 1, 0, 0,
- 0, &proc_array_inode_operations,
- get_ecard_dev_info
-};
-
-static struct proc_dir_entry *proc_bus_ecard_dir;
+static struct proc_dir_entry *proc_bus_ecard_dir = NULL;
static void ecard_proc_init(void)
{
proc_bus_ecard_dir = create_proc_entry("ecard", S_IFDIR, proc_bus);
- proc_register(proc_bus_ecard_dir, &proc_ecard_devices);
+ create_proc_info_entry("devices", 0, proc_bus_ecard_dir,
+ get_ecard_dev_info);
}
/*
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index ab92aae52..3c82ee68c 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -337,3 +337,31 @@ pid_t kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
return __ret;
}
+/*
+ * 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 fp, lr;
+ unsigned long stack_page;
+ int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
+ stack_page = 4096 + (unsigned long)p;
+ fp = get_css_fp(&p->thread);
+ do {
+ if (fp < stack_page || fp > 4092+stack_page)
+ return 0;
+ lr = pc_pointer (((unsigned long *)fp)[-1]);
+ if (lr < first_sched || lr > last_sched)
+ return lr;
+ fp = *(unsigned long *) (fp - 12);
+ } while (count ++ < 16);
+ return 0;
+}
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index b09b3798b..340700dbe 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -20,6 +20,7 @@
#include <linux/blk.h>
#include <linux/console.h>
#include <linux/init.h>
+#include <linux/bootmem.h>
#include <asm/elf.h>
#include <asm/hardware.h>
@@ -42,50 +43,74 @@
extern void reboot_setup(char *str, int *ints);
extern void disable_hlt(void);
-
-struct drive_info_struct { char dummy[32]; } drive_info;
-struct screen_info screen_info = {
- orig_video_lines: 30,
- orig_video_cols: 80,
- orig_video_mode: 0,
- orig_video_ega_bx: 0,
- orig_video_isVGA: 1,
- orig_video_points: 8
-};
-
extern int root_mountflags;
-extern int _text, _etext, _edata, _end;
-
-unsigned char aux_device_present;
- char elf_platform[ELF_PLATFORM_SIZE];
-unsigned int elf_hwcap;
+extern int _stext, _text, _etext, _edata, _end;
-/*
- * From head-armv.S
- */
unsigned int processor_id;
unsigned int __machine_arch_type;
unsigned int vram_size;
unsigned int system_rev;
unsigned int system_serial_low;
unsigned int system_serial_high;
-#ifdef MULTI_CPU
-struct processor processor;
-#endif
+unsigned int elf_hwcap;
+
#ifdef CONFIG_ARCH_ACORN
unsigned int memc_ctrl_reg;
unsigned int number_mfm_drives;
#endif
+struct meminfo meminfo;
+
+#ifdef MULTI_CPU
+struct processor processor;
+#endif
+
+struct drive_info_struct { char dummy[32]; } drive_info;
+
+struct screen_info screen_info = {
+ orig_video_lines: 30,
+ orig_video_cols: 80,
+ orig_video_mode: 0,
+ orig_video_ega_bx: 0,
+ orig_video_isVGA: 1,
+ orig_video_points: 8
+};
+
+unsigned char aux_device_present;
+char elf_platform[ELF_PLATFORM_SIZE];
+char saved_command_line[COMMAND_LINE_SIZE];
+
static struct proc_info_item proc_info;
+static char command_line[COMMAND_LINE_SIZE] = { 0, };
+
+static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
#define ENDIANNESS ((char)endian_test.l)
-/*-------------------------------------------------------------------------
- * Early initialisation routines for various configurable items in the
- * kernel. Each one either supplies a setup_ function, or defines this
- * symbol to be empty if not configured.
+/*
+ * Standard memory resources
*/
+static struct resource mem_res[] = {
+ { "System RAM", 0, 0, IORESOURCE_MEM | IORESOURCE_BUSY },
+ { "Video RAM", 0, 0, IORESOURCE_MEM },
+ { "Kernel code", 0, 0, IORESOURCE_MEM },
+ { "Kernel data", 0, 0, IORESOURCE_MEM }
+};
+
+#define system_ram mem_res[0]
+#define video_ram mem_res[1]
+#define kernel_code mem_res[2]
+#define kernel_data mem_res[3]
+
+static struct resource io_res[] = {
+ { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY },
+ { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY },
+ { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY }
+};
+
+#define lp0 io_res[0]
+#define lp1 io_res[1]
+#define lp2 io_res[2]
static void __init setup_processor(void)
{
@@ -124,55 +149,69 @@ static void __init setup_processor(void)
cpu_proc_init();
}
-static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
-static char command_line[COMMAND_LINE_SIZE] = { 0, };
- char saved_command_line[COMMAND_LINE_SIZE];
+static unsigned long __init memparse(char *ptr, char **retptr)
+{
+ unsigned long ret = simple_strtoul(ptr, retptr, 0);
+
+ switch (**retptr) {
+ case 'M':
+ case 'm':
+ ret <<= 10;
+ case 'K':
+ case 'k':
+ ret <<= 10;
+ (*retptr)++;
+ default:
+ break;
+ }
+ return ret;
+}
+/*
+ * Initial parsing of the command line. We need to pick out the
+ * memory size. We look for mem=size@start, where start and size
+ * are "size[KkMm]"
+ */
static void __init
-setup_mem(char *cmd_line, unsigned long *mem_sz)
+parse_cmdline(char **cmdline_p, char *from)
{
char c = ' ', *to = command_line;
- int len = 0;
-
- if (!*mem_sz)
- *mem_sz = MEM_SIZE;
+ int usermem = 0, len = 0;
for (;;) {
- if (c == ' ') {
- if (cmd_line[0] == 'm' &&
- cmd_line[1] == 'e' &&
- cmd_line[2] == 'm' &&
- cmd_line[3] == '=') {
- *mem_sz = simple_strtoul(cmd_line+4, &cmd_line, 0);
- switch(*cmd_line) {
- case 'M':
- case 'm':
- *mem_sz <<= 10;
- case 'K':
- case 'k':
- *mem_sz <<= 10;
- cmd_line++;
- }
- }
- /* if there are two spaces, remove one */
- if (*cmd_line == ' ') {
- cmd_line++;
- continue;
+ if (c == ' ' && !memcmp(from, "mem=", 4)) {
+ unsigned long size, start;
+
+ if (to != command_line)
+ to -= 1;
+
+ /* If the user specifies memory size, we
+ * blow away any automatically generated
+ * size.
+ */
+ if (usermem == 0) {
+ usermem = 1;
+ meminfo.nr_banks = 0;
}
+
+ start = 0;
+ size = memparse(from + 4, &from);
+ if (*from == '@')
+ start = memparse(from + 1, &from);
+
+ meminfo.bank[meminfo.nr_banks].start = start;
+ meminfo.bank[meminfo.nr_banks].size = size;
+ meminfo.nr_banks += 1;
}
- c = *cmd_line++;
+ c = *from++;
if (!c)
break;
if (COMMAND_LINE_SIZE <= ++len)
break;
*to++ = c;
}
-
*to = '\0';
-
- /* remove trailing spaces */
- while (*--to == ' ' && to != command_line)
- *to = '\0';
+ *cmdline_p = command_line;
}
static void __init
@@ -199,51 +238,90 @@ setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
static void __init setup_initrd(unsigned int start, unsigned int size)
{
#ifdef CONFIG_BLK_DEV_INITRD
- if (start) {
- initrd_start = start;
- initrd_end = start + size;
- } else {
- initrd_start = 0;
- initrd_end = 0;
- }
+ if (start == 0)
+ size = 0;
+ initrd_start = start;
+ initrd_end = start + size;
#endif
}
-static void __init check_initrd(unsigned long mem_end)
+/*
+ * Work out our memory regions. Note that "pfn" is the physical page number
+ * relative to the first physical page, not the physical address itself.
+ */
+static void __init setup_bootmem(void)
{
+ unsigned int end_pfn, bootmem_end;
+ int bank;
+
+ /*
+ * Calculate the end of memory.
+ */
+ for (bank = 0; bank < meminfo.nr_banks; bank++) {
+ if (meminfo.bank[bank].size) {
+ unsigned long end;
+
+ end = meminfo.bank[bank].start +
+ meminfo.bank[bank].size;
+ if (meminfo.end < end)
+ meminfo.end = end;
+ }
+ }
+
+ bootmem_end = __pa(PAGE_ALIGN((unsigned long)&_end));
+ end_pfn = meminfo.end >> PAGE_SHIFT;
+
+ /*
+ * Initialise the boot-time allocator
+ */
+ bootmem_end += init_bootmem(bootmem_end >> PAGE_SHIFT, end_pfn);
+
+ /*
+ * Register all available RAM with the bootmem allocator.
+ * The address is relative to the start of physical memory.
+ */
+ for (bank = 0; bank < meminfo.nr_banks; bank ++)
+ free_bootmem(meminfo.bank[bank].start, meminfo.bank[bank].size);
+
+ /*
+ * reserve the following regions:
+ * physical page 0 - it contains the exception vectors
+ * kernel and the bootmem structure
+ * swapper page directory (if any)
+ * initrd (if any)
+ */
+ reserve_bootmem(0, PAGE_SIZE);
+#ifdef CONFIG_CPU_32
+ reserve_bootmem(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(void *));
+#endif
+ reserve_bootmem(__pa(&_stext), bootmem_end - __pa(&_stext));
#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_end > mem_end) {
+ if (__pa(initrd_end) > (end_pfn << PAGE_SHIFT)) {
printk ("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx) - disabling initrd\n",
- initrd_end, mem_end);
+ "(0x%08lx > 0x%08x) - disabling initrd\n",
+ __pa(initrd_end), end_pfn << PAGE_SHIFT);
initrd_start = 0;
}
+
+ if (initrd_start)
+ reserve_bootmem(__pa(initrd_start),
+ initrd_end - initrd_start);
#endif
}
-/*
- * Standard memory resources
- */
-static struct resource system_ram = { "System RAM", 0, 0, IORESOURCE_MEM | IORESOURCE_BUSY };
-static struct resource video_ram = { "Video RAM", 0, 0, IORESOURCE_MEM };
-static struct resource kernel_code = { "Kernel code", 0, 0, IORESOURCE_MEM };
-static struct resource kernel_data = { "Kernel data", 0, 0, IORESOURCE_MEM };
-static struct resource lpt1 = { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY };
-static struct resource lpt2 = { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY };
-static struct resource lpt3 = { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY };
-
-static void __init request_standard_resources(unsigned long end)
+static void __init request_standard_resources(void)
{
kernel_code.start = __virt_to_bus((unsigned long) &_text);
kernel_code.end = __virt_to_bus((unsigned long) &_etext - 1);
kernel_data.start = __virt_to_bus((unsigned long) &_etext);
kernel_data.end = __virt_to_bus((unsigned long) &_edata - 1);
system_ram.start = __virt_to_bus(PAGE_OFFSET);
- system_ram.end = __virt_to_bus(end - 1);
+ system_ram.end = __virt_to_bus(meminfo.end + PAGE_OFFSET - 1);
request_resource(&iomem_resource, &system_ram);
request_resource(&system_ram, &kernel_code);
request_resource(&system_ram, &kernel_data);
+
if (video_ram.start != video_ram.end)
request_resource(&iomem_resource, &video_ram);
@@ -253,17 +331,16 @@ static void __init request_standard_resources(unsigned long end)
*/
if (machine_is_ebsa110() || machine_is_riscpc() ||
machine_is_netwinder())
- request_resource(&ioport_resource, &lpt1);
+ request_resource(&ioport_resource, &lp0);
if (machine_is_riscpc())
- request_resource(&ioport_resource, &lpt2);
+ request_resource(&ioport_resource, &lp1);
if (machine_is_ebsa110() || machine_is_netwinder())
- request_resource(&ioport_resource, &lpt3);
+ request_resource(&ioport_resource, &lp2);
}
-void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p)
+void __init setup_arch(char **cmdline_p)
{
struct param_struct *params = (struct param_struct *)PARAMS_BASE;
- unsigned long memory_end = 0;
char *from = default_command_line;
#if defined(CONFIG_ARCH_ARC)
@@ -296,10 +373,6 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne
case MACH_TYPE_RISCPC:
/* RiscPC can't handle half-word loads and stores */
elf_hwcap &= ~HWCAP_HALF;
- {
- extern void init_dram_banks(struct param_struct *);
- init_dram_banks(params);
- }
switch (params->u1.s.pages_in_vram) {
case 512:
@@ -309,6 +382,17 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne
default:
break;
}
+ {
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ meminfo.bank[i].start = i << 26;
+ meminfo.bank[i].size =
+ params->u1.s.pages_in_bank[i] *
+ params->u1.s.page_size;
+ }
+ meminfo.nr_banks = 4;
+ }
#endif
case MACH_TYPE_ARCHIMEDES:
case MACH_TYPE_A5K:
@@ -347,7 +431,7 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne
*/
reboot_setup("s", NULL);
params = NULL;
- ORIG_VIDEO_LINES = 25;
+ ORIG_VIDEO_LINES = 25;
ORIG_VIDEO_POINTS = 16;
ORIG_Y = 24;
video_ram.start = 0x0a0000;
@@ -393,7 +477,11 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne
}
if (params) {
- memory_end = PAGE_SIZE * params->u1.s.nr_pages;
+ if (meminfo.nr_banks == 0) {
+ meminfo.nr_banks = 1;
+ meminfo.bank[0].start = 0;
+ meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT;
+ }
ROOT_DEV = to_kdev_t(params->u1.s.rootdev);
system_rev = params->u1.s.system_rev;
system_serial_low = params->u1.s.system_serial_low;
@@ -413,24 +501,23 @@ void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigne
from = params->commandline;
}
- /* Save unparsed command line copy for /proc/cmdline */
- memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
- saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
-
- setup_mem(from, &memory_end);
-
- memory_end += PAGE_OFFSET;
+ if (meminfo.nr_banks == 0) {
+ meminfo.nr_banks = 1;
+ meminfo.bank[0].start = 0;
+ meminfo.bank[0].size = MEM_SIZE;
+ }
- *cmdline_p = command_line;
init_mm.start_code = (unsigned long) &_text;
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
- *memory_start_p = (unsigned long) &_end;
- *memory_end_p = memory_end;
- request_standard_resources(memory_end);
- check_initrd(memory_end);
+ /* Save unparsed command line copy for /proc/cmdline */
+ memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
+ saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
+ parse_cmdline(cmdline_p, from);
+ setup_bootmem();
+ request_standard_resources();
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 3d39c8d39..f25544c14 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -29,8 +29,6 @@
/*
* Constant strings used in inlined functions in header files
*/
-/* proc/system.h */
-const char xchg_str[] = "xchg";
/*
* sys_pipe() is the normal C calling standard for creating
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index da0d464f6..038946e9c 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -34,7 +34,10 @@ char *processor_modes[]=
"UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
};
-static char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
+/* proc/system.h */
+const char xchg_str[] = "xchg";
+
+static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
static inline void console_verbose(void)
{
@@ -335,10 +338,11 @@ asmlinkage void deferred(int n, struct pt_regs *regs)
}
#ifdef CONFIG_DEBUG_USER
- printk(KERN_ERR "[%d] %s: old system call.\n", current->pid,
- current->comm);
+ printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", current->pid,
+ current->comm, n);
#endif
force_sig(SIGILL, current);
+ die_if_kernel("Oops", regs, n);
}
asmlinkage void arm_malalignedptr(const char *str, void *pc, volatile void *ptr)
@@ -385,8 +389,37 @@ asmlinkage void baddataabort(int code, unsigned long instr, struct pt_regs *regs
}
#endif
+void __bug(const char *file, int line, void *data)
+{
+ printk(KERN_CRIT"kernel BUG at %s:%d!\n", file, line);
+ if (data)
+ printk(KERN_CRIT"extra data = %p\n", data);
+ *(int *)0 = 0;
+}
+
+void __readwrite_bug(const char *fn)
+{
+ printk("%s called, but not implemented", fn);
+ *(int *)0 = 0;
+}
+
+void __pte_error(const char *file, int line, unsigned long val)
+{
+ printk("%s:%d: bad pte %08lx.\n", file, line, val);
+}
+
+void __pmd_error(const char *file, int line, unsigned long val)
+{
+ printk("%s:%d: bad pmd %08lx.\n", file, line, val);
+}
+
+void __pgd_error(const char *file, int line, unsigned long val)
+{
+ printk("%s:%d: bad pgd %08lx.\n", file, line, val);
+}
+
asmlinkage void __div0(void)
{
- printk("Awooga, division by zero in kernel.\n");
+ printk("Division by zero in kernel.\n");
__backtrace();
}
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index 8c2df7f5e..8715ea271 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -90,6 +90,7 @@ static unsigned long ai_half;
static unsigned long ai_word;
static unsigned long ai_multi;
+#ifdef CONFIG_SYSCTL
static int proc_alignment_read(char *page, char **start, off_t off,
int count, int *eof, void *data)
{
@@ -113,23 +114,18 @@ static int proc_alignment_read(char *page, char **start, off_t off,
return len;
}
-#ifdef CONFIG_SYSCTL
/*
* This needs to be done after sysctl_init, otherwise sys/
* will be overwritten.
*/
void __init alignment_init(void)
{
- struct proc_dir_entry *e;
-
- e = create_proc_entry("sys/debug/alignment", S_IFREG | S_IRUGO, NULL);
-
- if (e)
- e->read_proc = proc_alignment_read;
+ create_proc_read_entry("sys/debug/alignment", 0, NULL,
+ proc_alignment_read);
}
__initcall(alignment_init);
-#endif
+#endif /* CONFIG_SYSCTL */
static int
do_alignment_exception(struct pt_regs *regs)
diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c
index c87fa760e..e516261ed 100644
--- a/arch/arm/mm/fault-common.c
+++ b/arch/arm/mm/fault-common.c
@@ -8,24 +8,6 @@
extern void die(char *msg, struct pt_regs *regs, unsigned int err);
-void __bad_pmd(pmd_t *pmd)
-{
- printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
-#ifdef CONFIG_DEBUG_ERRORS
- __backtrace();
-#endif
- set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE));
-}
-
-void __bad_pmd_kernel(pmd_t *pmd)
-{
- printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd));
-#ifdef CONFIG_DEBUG_ERRORS
- __backtrace();
-#endif
- set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE));
-}
-
/*
* This is useful to dump out the page tables associated with
* 'addr' in mm 'mm'.
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 115cec885..229b4dcd7 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -1,7 +1,7 @@
/*
* linux/arch/arm/mm/init.c
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-1999 Russell King
*/
#include <linux/config.h>
@@ -18,6 +18,7 @@
#include <linux/swapctl.h>
#include <linux/smp.h>
#include <linux/init.h>
+#include <linux/bootmem.h>
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
#endif
@@ -27,73 +28,94 @@
#include <asm/pgtable.h>
#include <asm/dma.h>
#include <asm/hardware.h>
+#include <asm/setup.h>
#include "map.h"
+static unsigned long totalram_pages;
pgd_t swapper_pg_dir[PTRS_PER_PGD];
-#ifndef CONFIG_NO_PGT_CACHE
-struct pgtable_cache_struct quicklists;
-#endif
-extern unsigned long free_area_init(unsigned long, unsigned long);
extern void show_net_buffers(void);
-extern char _etext, _text, _edata, __bss_start, _end;
-extern char __init_begin, __init_end;
-
-int do_check_pgt_cache(int low, int high)
-{
- int freed = 0;
-#ifndef CONFIG_NO_PGT_CACHE
- if(pgtable_cache_size > high) {
- do {
- if(pgd_quicklist)
- free_pgd_slow(get_pgd_fast()), freed++;
- if(pmd_quicklist)
- free_pmd_slow(get_pmd_fast()), freed++;
- if(pte_quicklist)
- free_pte_slow(get_pte_fast()), freed++;
- } while(pgtable_cache_size > low);
- }
-#endif
- return freed;
-}
-
/*
- * BAD_PAGE is the page that is used for page faults when linux
- * is out-of-memory. Older versions of linux just did a
+ * empty_bad_page is the page that is used for page faults when
+ * linux is out-of-memory. Older versions of linux just did a
* do_exit(), but using this instead means there is less risk
* for a process dying in kernel mode, possibly leaving a inode
* unused etc..
*
- * BAD_PAGETABLE is the accompanying page-table: it is initialized
- * to point to BAD_PAGE entries.
+ * empty_bad_pte_table is the accompanying page-table: it is
+ * initialized to point to BAD_PAGE entries.
*
- * ZERO_PAGE is a special page that is used for zero-initialized
- * data and COW.
+ * empty_zero_page is a special page that is used for
+ * zero-initialized data and COW.
*/
-pte_t *empty_bad_page_table;
+struct page *empty_zero_page;
+struct page *empty_bad_page;
+pte_t *empty_bad_pte_table;
-pte_t *__bad_pagetable(void)
+pte_t *get_bad_pte_table(void)
{
- pte_t bad_page;
+ pte_t v;
int i;
- bad_page = BAD_PAGE;
+ v = pte_mkdirty(mk_pte(empty_bad_page, PAGE_SHARED));
+
for (i = 0; i < PTRS_PER_PTE; i++)
- set_pte(empty_bad_page_table + i, bad_page);
+ set_pte(empty_bad_pte_table + i, v);
+
+ return empty_bad_pte_table;
+}
+
+void __handle_bad_pmd(pmd_t *pmd)
+{
+ pmd_ERROR(*pmd);
+#ifdef CONFIG_DEBUG_ERRORS
+ __backtrace();
+#endif
+ set_pmd(pmd, mk_user_pmd(get_bad_pte_table()));
+}
- return empty_bad_page_table;
+void __handle_bad_pmd_kernel(pmd_t *pmd)
+{
+ pmd_ERROR(*pmd);
+#ifdef CONFIG_DEBUG_ERRORS
+ __backtrace();
+#endif
+ set_pmd(pmd, mk_kernel_pmd(get_bad_pte_table()));
}
-unsigned long *empty_zero_page;
-unsigned long *empty_bad_page;
+#ifndef CONFIG_NO_PGT_CACHE
+struct pgtable_cache_struct quicklists;
+
+int do_check_pgt_cache(int low, int high)
+{
+ int freed = 0;
-pte_t __bad_page(void)
+ if(pgtable_cache_size > high) {
+ do {
+ if(pgd_quicklist) {
+ free_pgd_slow(get_pgd_fast());
+ freed++;
+ }
+ if(pmd_quicklist) {
+ free_pmd_slow(get_pmd_fast());
+ freed++;
+ }
+ if(pte_quicklist) {
+ free_pte_slow(get_pte_fast());
+ freed++;
+ }
+ } while(pgtable_cache_size > low);
+ }
+ return freed;
+}
+#else
+int do_check_pgt_cache(int low, int high)
{
- memzero (empty_bad_page, PAGE_SIZE);
- return pte_nocache(pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED)));
+ return 0;
}
+#endif
void show_mem(void)
{
@@ -104,23 +126,28 @@ void show_mem(void)
printk("Mem-info:\n");
show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
- for (page = mem_map, end = mem_map + max_mapnr;
- page < end; page++) {
+
+ page = mem_map;
+ end = mem_map + max_mapnr;
+
+ do {
if (PageSkip(page)) {
- if (page->next_hash < page)
- break;
page = page->next_hash;
+ if (page == NULL)
+ break;
}
total++;
if (PageReserved(page))
reserved++;
else if (PageSwapCache(page))
cached++;
- else if (!atomic_read(&page->count))
+ else if (!page_count(page))
free++;
else
shared += atomic_read(&page->count) - 1;
- }
+ page++;
+ } while (page < end);
+
printk("%d pages of RAM\n", total);
printk("%d free pages\n", free);
printk("%d reserved pages\n", reserved);
@@ -138,31 +165,42 @@ void show_mem(void)
/*
* paging_init() sets up the page tables...
*/
-unsigned long __init paging_init(unsigned long start_mem, unsigned long end_mem)
+void __init paging_init(void)
{
- start_mem = PAGE_ALIGN(start_mem);
-
- empty_zero_page = (unsigned long *)start_mem;
- memzero(empty_zero_page, PAGE_SIZE);
- start_mem += PAGE_SIZE;
-
- empty_bad_page = (unsigned long *)start_mem;
- start_mem += PAGE_SIZE;
+ void *zero_page, *bad_page, *bad_table;
#ifdef CONFIG_CPU_32
- start_mem += PTRS_PER_PTE * BYTES_PER_PTR;
+#define TABLE_OFFSET (PTRS_PER_PTE)
+#else
+#define TABLE_OFFSET 0
#endif
- empty_bad_page_table = (pte_t *)start_mem;
- start_mem += PTRS_PER_PTE * BYTES_PER_PTR;
-
- start_mem = setup_page_tables(start_mem, end_mem);
-
+#define TABLE_SIZE ((TABLE_OFFSET + PTRS_PER_PTE) * sizeof(void *))
+
+ /*
+ * allocate what we need for the bad pages
+ */
+ zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
+ bad_page = alloc_bootmem_low_pages(PAGE_SIZE);
+ bad_table = alloc_bootmem_low_pages(TABLE_SIZE);
+
+ /*
+ * initialise the page tables
+ */
+ pagetable_init();
flush_tlb_all();
- end_mem &= PAGE_MASK;
- high_memory = (void *)end_mem;
+ free_area_init(max_low_pfn);
+
+ /*
+ * finish off the bad pages once
+ * the mem_map is initialised
+ */
+ memzero(zero_page, PAGE_SIZE);
+ memzero(bad_page, PAGE_SIZE);
- return free_area_init(start_mem, end_mem);
+ empty_zero_page = mem_map + MAP_NR(zero_page);
+ empty_bad_page = mem_map + MAP_NR(bad_page);
+ empty_bad_pte_table = ((pte_t *)bad_table) + TABLE_OFFSET;
}
static inline void free_unused_mem_map(void)
@@ -184,7 +222,7 @@ static inline void free_unused_mem_map(void)
high = ((unsigned long)page->next_hash) & PAGE_MASK;
while (low < high) {
- clear_bit(PG_reserved, &mem_map[MAP_NR(low)].flags);
+ ClearPageReserved(mem_map + MAP_NR(low));
low += PAGE_SIZE;
}
}
@@ -195,67 +233,35 @@ static inline void free_unused_mem_map(void)
* memory is free. This is done after various parts of the system have
* claimed their memory after the kernel image.
*/
-void __init mem_init(unsigned long start_mem, unsigned long end_mem)
+void __init mem_init(void)
{
int codepages = 0;
int reservedpages = 0;
int datapages = 0;
int initpages = 0, i, min_nr;
- unsigned long tmp;
- end_mem &= PAGE_MASK;
- high_memory = (void *)end_mem;
- max_mapnr = MAP_NR(end_mem);
- num_physpages = 0;
-
- /* setup address validity bitmap */
- start_mem = create_mem_holes(start_mem, end_mem);
-
- start_mem = PAGE_ALIGN(start_mem);
-
- /* mark usable pages in the mem_map[] */
- mark_usable_memory_areas(start_mem, end_mem);
-
- /* free unused mem_map[] entries */
- free_unused_mem_map();
+ max_mapnr = max_low_pfn;
+ high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
-#define BETWEEN(w,min,max) ((w) >= (unsigned long)(min) && \
- (w) < (unsigned long)(max))
-
- for (tmp = PAGE_OFFSET; tmp < end_mem ; tmp += PAGE_SIZE) {
- if (PageSkip(mem_map+MAP_NR(tmp))) {
- unsigned long next;
-
- next = mem_map[MAP_NR(tmp)].next_hash - mem_map;
-
- next = (next << PAGE_SHIFT) + PAGE_OFFSET;
-
- if (next < tmp || next >= end_mem)
- break;
- tmp = next;
- }
- num_physpages++;
- if (PageReserved(mem_map+MAP_NR(tmp))) {
- if (BETWEEN(tmp, &__init_begin, &__init_end))
- initpages++;
- else if (BETWEEN(tmp, &_text, &_etext))
- codepages++;
- else if (BETWEEN(tmp, &_etext, &_edata))
- datapages++;
- else if (BETWEEN(tmp, &__bss_start, start_mem))
- datapages++;
- else
- reservedpages++;
- continue;
- }
- atomic_set(&mem_map[MAP_NR(tmp)].count, 1);
-#ifdef CONFIG_BLK_DEV_INITRD
- if (!initrd_start || !BETWEEN(tmp, initrd_start, initrd_end))
+#ifdef CONFIG_CPU_32
+ /*
+ * We may have non-contiguous memory. Setup the PageSkip stuff,
+ * and mark the areas of mem_map which can be freed
+ */
+ if (meminfo.nr_banks != 1)
+ create_memmap_holes();
#endif
- free_page(tmp);
- }
-#undef BETWEEN
+ /* this will put all unused low memory onto the freelists */
+ totalram_pages += free_all_bootmem();
+
+ /*
+ * Since our memory may not be contiguous, calculate the
+ * real number of pages we have in this system
+ */
+ num_physpages = 0;
+ for (i = 0; i < meminfo.nr_banks; i++)
+ num_physpages += meminfo.bank[i].size >> PAGE_SHIFT;
printk ("Memory: %luk/%luM available (%dk code, %dk reserved, %dk data, %dk init)\n",
(unsigned long) nr_free_pages << (PAGE_SHIFT-10),
@@ -265,6 +271,9 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
datapages << (PAGE_SHIFT-10),
initpages << (PAGE_SHIFT-10));
+ /*
+ * Correct freepages watermarks
+ */
i = nr_free_pages >> 7;
if (PAGE_SIZE < 32768)
min_nr = 10;
@@ -288,22 +297,26 @@ void __init mem_init(unsigned long start_mem, unsigned long end_mem)
#endif
}
-static void free_area(unsigned long addr, unsigned long end, char *s)
+static inline void free_area(unsigned long addr, unsigned long end, char *s)
{
unsigned int size = (end - addr) >> 10;
+ struct page *page = mem_map + MAP_NR(addr);
- for (; addr < end; addr += PAGE_SIZE) {
- mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
- atomic_set(&mem_map[MAP_NR(addr)].count, 1);
+ for (; addr < end; addr += PAGE_SIZE, page ++) {
+ ClearPageReserved(page);
+ set_page_count(page, 1);
free_page(addr);
+ totalram_pages++;
}
if (size)
printk(" %dk %s", size, s);
}
-void free_initmem (void)
+void free_initmem(void)
{
+ extern char __init_begin, __init_end;
+
printk("Freeing unused kernel memory:");
free_area((unsigned long)(&__init_begin),
@@ -333,28 +346,11 @@ void free_initmem (void)
void si_meminfo(struct sysinfo *val)
{
- struct page *page, *end;
-
- val->totalram = 0;
+ val->totalram = totalram_pages;
val->sharedram = 0;
- val->freeram = nr_free_pages << PAGE_SHIFT;
- val->bufferram = atomic_read(&buffermem);
- for (page = mem_map, end = mem_map + max_mapnr;
- page < end; page++) {
- if (PageSkip(page)) {
- if (page->next_hash < page)
- break;
- page = page->next_hash;
- }
- if (PageReserved(page))
- continue;
- val->totalram++;
- if (!atomic_read(&page->count))
- continue;
- val->sharedram += atomic_read(&page->count) - 1;
- }
- val->totalram <<= PAGE_SHIFT;
- val->sharedram <<= PAGE_SHIFT;
- val->totalbig = 0;
- val->freebig = 0;
+ val->freeram = nr_free_pages;
+ val->bufferram = atomic_read(&buffermem_pages);
+ val->totalhigh = 0;
+ val->freehigh = 0;
+ val->mem_unit = PAGE_SIZE;
}
diff --git a/arch/arm/mm/map.h b/arch/arm/mm/map.h
index a1fc92b2c..0a3ee8b4d 100644
--- a/arch/arm/mm/map.h
+++ b/arch/arm/mm/map.h
@@ -16,17 +16,9 @@ struct map_desc {
bufferable:1;
};
-struct mem_desc {
- unsigned long virt_start;
- unsigned long virt_end;
-};
-
extern struct map_desc io_desc[];
extern unsigned int io_desc_size;
-extern struct mem_desc mem_desc[];
-extern unsigned int mem_desc_size;
-extern void mark_usable_memory_areas(unsigned long start, unsigned long end);
-extern unsigned long create_mem_holes(unsigned long start, unsigned long end);
-extern unsigned long setup_page_tables(unsigned long start, unsigned long end);
+extern void create_memmap_holes(void);
+extern void pagetable_init(void);
diff --git a/arch/arm/mm/mm-armo.c b/arch/arm/mm/mm-armo.c
index 55245f4e8..5ee95ea45 100644
--- a/arch/arm/mm/mm-armo.c
+++ b/arch/arm/mm/mm-armo.c
@@ -8,6 +8,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/init.h>
+#include <linux/bootmem.h>
#include <asm/pgtable.h>
#include <asm/page.h>
@@ -18,40 +19,54 @@
#define MEMC_TABLE_SIZE (256*sizeof(unsigned long))
#define PGD_TABLE_SIZE (PTRS_PER_PGD * BYTES_PER_PTR)
-/*
- * FIXME: the following over-allocates by 6400%
- */
-static inline void *alloc_table(int size, int prio)
-{
- if (size != 128)
- printk("invalid table size\n");
- return (void *)get_page_8k(prio);
-}
+int page_nr;
+
+extern unsigned long get_page_2k(int prio);
+extern void free_page_2k(unsigned long);
+extern pte_t *get_bad_pte_table(void);
/*
* Allocate a page table. Note that we place the MEMC
* table before the page directory. This means we can
* easily get to both tightly-associated data structures
- * with a single pointer. This function is slightly
- * better - it over-allocates by only 711%
+ * with a single pointer.
+ *
+ * We actually only need 1152 bytes, 896 bytes is wasted.
+ * We could try to fit 7 PTEs into that slot somehow.
*/
static inline void *alloc_pgd_table(int priority)
{
- unsigned long pg8k;
+ unsigned long pg2k;
- pg8k = get_page_8k(priority);
- if (pg8k)
- pg8k += MEMC_TABLE_SIZE;
+ pg2k = get_page_2k(priority);
+ if (pg2k)
+ pg2k += MEMC_TABLE_SIZE;
- return (void *)pg8k;
+ return (void *)pg2k;
}
-void free_table(void *table)
+void free_pgd_slow(pgd_t *pgd)
{
- unsigned long tbl = (unsigned long)table;
+ unsigned long tbl = (unsigned long)pgd;
+
+ tbl -= MEMC_TABLE_SIZE;
+ free_page_2k(tbl);
+}
- tbl &= ~8191;
- free_page_8k(tbl);
+/*
+ * FIXME: the following over-allocates by 1600%
+ */
+static inline void *alloc_pte_table(int size, int prio)
+{
+ if (size != 128)
+ printk("invalid table size\n");
+ return (void *)get_page_2k(prio);
+}
+
+void free_pte_slow(pte_t *pte)
+{
+ unsigned long tbl = (unsigned long)pte;
+ free_page_2k(tbl);
}
pgd_t *get_pgd_slow(void)
@@ -62,9 +77,9 @@ pgd_t *get_pgd_slow(void)
if (pgd) {
pgd_t *init = pgd_offset(&init_mm, 0);
- memzero(pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
+ memzero(pgd, USER_PTRS_PER_PGD * sizeof(pgd_t));
memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR);
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
/*
* On ARM, first page must always be allocated
@@ -92,7 +107,7 @@ pgd_t *get_pgd_slow(void)
nomem_pmd:
pmd_free(new_pmd);
nomem:
- free_table(pgd);
+ free_pgd_slow(pgd);
return NULL;
}
@@ -100,19 +115,19 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
{
pte_t *pte;
- pte = (pte_t *)alloc_table(PTRS_PER_PTE * BYTES_PER_PTR, GFP_KERNEL);
+ pte = (pte_t *)alloc_pte_table(PTRS_PER_PTE * sizeof(pte_t), GFP_KERNEL);
if (pmd_none(*pmd)) {
if (pte) {
- memzero(pte, PTRS_PER_PTE * BYTES_PER_PTR);
- set_pmd(pmd, mk_pmd(pte));
+ memzero(pte, PTRS_PER_PTE * sizeof(pte_t));
+ set_pmd(pmd, mk_user_pmd(pte));
return pte + offset;
}
- set_pmd(pmd, mk_pmd(BAD_PAGETABLE));
+ set_pmd(pmd, mk_user_pmd(get_bad_pte_table()));
return NULL;
}
- free_table((void *)pte);
+ free_pte_slow(pte);
if (pmd_bad(*pmd)) {
- __bad_pmd(pmd);
+ __handle_bad_pmd(pmd);
return NULL;
}
return (pte_t *) pmd_page(*pmd) + offset;
@@ -124,47 +139,22 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
* some more work to get it to fit into our separate processor and
* architecture structure.
*/
-int page_nr;
-
-#define PTE_SIZE (PTRS_PER_PTE * BYTES_PER_PTR)
-
-static inline void setup_swapper_dir (int index, pte_t *ptep)
+void __init pagetable_init(void)
{
- set_pmd (pmd_offset (swapper_pg_dir + index, 0), mk_pmd (ptep));
-}
-
-unsigned long __init
-setup_page_tables(unsigned long start_mem, unsigned long end_mem)
-{
- unsigned int i;
- union { unsigned long l; pte_t *pte; } u;
+ pte_t *pte;
+ int i;
- page_nr = MAP_NR(end_mem);
+ page_nr = max_low_pfn;
- /* map in pages for (0x0000 - 0x8000) */
- u.l = ((start_mem + (PTE_SIZE-1)) & ~(PTE_SIZE-1));
- start_mem = u.l + PTE_SIZE;
- memzero (u.pte, PTE_SIZE);
- u.pte[0] = mk_pte(PAGE_OFFSET + 491520, PAGE_READONLY);
- setup_swapper_dir (0, u.pte);
+ pte = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t));
+ memzero(pte, PTRS_PER_PTE * sizeof(pte_t));
+ pte[0] = mk_pte_phys(PAGE_OFFSET + 491520, PAGE_READONLY);
+ set_pmd(pmd_offset(swapper_pg_dir, 0), mk_kernel_pmd(pte));
for (i = 1; i < PTRS_PER_PGD; i++)
pgd_val(swapper_pg_dir[i]) = 0;
-
- return start_mem;
}
-unsigned long __init
-create_mem_holes(unsigned long start, unsigned long end)
+void __init create_memmap_holes(void)
{
- return start;
-}
-
-void __init
-mark_usable_memory_areas(unsigned long start_mem, unsigned long end_mem)
-{
- while (start_mem < end_mem) {
- clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
- start_mem += PAGE_SIZE;
- }
}
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index d52c21cc4..3df6c13b5 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -1,22 +1,28 @@
/*
- * arch/arm/mm/mm-armv.c
+ * linux/arch/arm/mm/mm-armv.c
*
- * Page table sludge for ARM v3 and v4 processor architectures.
+ * Page table sludge for ARM v3 and v4 processor architectures.
*
- * Copyright (C) 1998-1999 Russell King
+ * Copyright (C) 1998-1999 Russell King
*/
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/init.h>
+#include <linux/bootmem.h>
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/io.h>
+#include <asm/setup.h>
#include "map.h"
unsigned long *valid_addr_bitmap;
+extern unsigned long get_page_2k(int priority);
+extern void free_page_2k(unsigned long page);
+extern pte_t *get_bad_pte_table(void);
+
/*
* need to get a 16k page for level 1
*/
@@ -26,12 +32,12 @@ pgd_t *get_pgd_slow(void)
pmd_t *new_pmd;
if (pgd) {
- pgd_t *init = pgd_offset(&init_mm, 0);
+ pgd_t *init = pgd_offset_k(0);
- memzero(pgd, USER_PTRS_PER_PGD * BYTES_PER_PTR);
+ memzero(pgd, USER_PTRS_PER_PGD * sizeof(pgd_t));
memcpy(pgd + USER_PTRS_PER_PGD, init + USER_PTRS_PER_PGD,
- (PTRS_PER_PGD - USER_PTRS_PER_PGD) * BYTES_PER_PTR);
- clean_cache_area(pgd, PTRS_PER_PGD * BYTES_PER_PTR);
+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t));
+ clean_cache_area(pgd, PTRS_PER_PGD * sizeof(pgd_t));
/*
* On ARM, first page must always be allocated
@@ -48,7 +54,7 @@ pgd_t *get_pgd_slow(void)
pte_t *new_pte = pte_offset(new_pmd, 0);
pte_t *old_pte = pte_offset(old_pmd, 0);
- set_pte (new_pte, *old_pte);
+ set_pte(new_pte, *old_pte);
}
}
}
@@ -61,6 +67,31 @@ nomem:
return NULL;
}
+void free_pgd_slow(pgd_t *pgd)
+{
+ if (pgd) { /* can pgd be NULL? */
+ pmd_t *pmd;
+ pte_t *pte;
+
+ /* pgd is always present and good */
+ pmd = (pmd_t *)pgd;
+ if (pmd_none(*pmd))
+ goto free;
+ if (pmd_bad(*pmd)) {
+ pmd_ERROR(*pmd);
+ pmd_clear(pmd);
+ goto free;
+ }
+
+ pte = pte_offset(pmd, 0);
+ pmd_clear(pmd);
+ pte_free(pte);
+ pmd_free(pmd);
+ }
+free:
+ free_pages((unsigned long) pgd, 2);
+}
+
pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
{
pte_t *pte;
@@ -68,18 +99,18 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
pte = (pte_t *)get_page_2k(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (pte) {
- memzero(pte, 2 * PTRS_PER_PTE * BYTES_PER_PTR);
- clean_cache_area(pte, PTRS_PER_PTE * BYTES_PER_PTR);
+ memzero(pte, 2 * PTRS_PER_PTE * sizeof(pte_t));
+ clean_cache_area(pte, PTRS_PER_PTE * sizeof(pte_t));
pte += PTRS_PER_PTE;
set_pmd(pmd, mk_user_pmd(pte));
return pte + offset;
}
- set_pmd(pmd, mk_user_pmd(BAD_PAGETABLE));
+ set_pmd(pmd, mk_user_pmd(get_bad_pte_table()));
return NULL;
}
free_page_2k((unsigned long)pte);
if (pmd_bad(*pmd)) {
- __bad_pmd(pmd);
+ __handle_bad_pmd(pmd);
return NULL;
}
return (pte_t *) pmd_page(*pmd) + offset;
@@ -92,23 +123,28 @@ pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
pte = (pte_t *)get_page_2k(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (pte) {
- memzero(pte, 2 * PTRS_PER_PTE * BYTES_PER_PTR);
- clean_cache_area(pte, PTRS_PER_PTE * BYTES_PER_PTR);
+ memzero(pte, 2 * PTRS_PER_PTE * sizeof(pte_t));
+ clean_cache_area(pte, PTRS_PER_PTE * sizeof(pte_t));
pte += PTRS_PER_PTE;
set_pmd(pmd, mk_kernel_pmd(pte));
return pte + offset;
}
- set_pmd(pmd, mk_kernel_pmd(BAD_PAGETABLE));
+ set_pmd(pmd, mk_kernel_pmd(get_bad_pte_table()));
return NULL;
}
free_page_2k((unsigned long)pte);
if (pmd_bad(*pmd)) {
- __bad_pmd_kernel(pmd);
+ __handle_bad_pmd_kernel(pmd);
return NULL;
}
return (pte_t *) pmd_page(*pmd) + offset;
}
+void free_pte_slow(pte_t *pte)
+{
+ free_page_2k((unsigned long)(pte - PTRS_PER_PTE));
+}
+
/*
* Create a SECTION PGD between VIRT and PHYS in domain
* DOMAIN with protection PROT
@@ -131,34 +167,22 @@ alloc_init_section(unsigned long virt, unsigned long phys, int prot)
* the hardware pte table.
*/
static inline void
-alloc_init_page(unsigned long *mem, unsigned long virt, unsigned long phys, int domain, int prot)
+alloc_init_page(unsigned long virt, unsigned long phys, int domain, int prot)
{
pmd_t *pmdp;
pte_t *ptep;
pmdp = pmd_offset(pgd_offset_k(virt), virt);
-#define PTE_SIZE (PTRS_PER_PTE * BYTES_PER_PTR)
-
if (pmd_none(*pmdp)) {
- unsigned long memory = *mem;
-
- memory = (memory + PTE_SIZE - 1) & ~(PTE_SIZE - 1);
+ pte_t *ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
+ sizeof(pte_t));
- ptep = (pte_t *)memory;
- memzero(ptep, PTE_SIZE);
- memory += PTE_SIZE;
-
- ptep = (pte_t *)memory;
- memzero(ptep, PTE_SIZE);
+ memzero(ptep, 2 * PTRS_PER_PTE * sizeof(pte_t));
+ ptep += PTRS_PER_PTE;
set_pmd(pmdp, __mk_pmd(ptep, PMD_TYPE_TABLE | PMD_DOMAIN(domain)));
-
- *mem = memory + PTE_SIZE;
}
-
-#undef PTE_SIZE
-
ptep = pte_offset(pmdp, virt);
set_pte(ptep, mk_pte_phys(phys, __pgprot(prot)));
@@ -169,8 +193,7 @@ alloc_init_page(unsigned long *mem, unsigned long virt, unsigned long phys, int
* the clearance is done by the middle-level functions (pmd)
* rather than the top-level (pgd) functions.
*/
-static inline void
-free_init_section(unsigned long virt)
+static inline void free_init_section(unsigned long virt)
{
pmd_clear(pmd_offset(pgd_offset_k(virt), virt));
}
@@ -181,8 +204,7 @@ free_init_section(unsigned long virt)
* are able to cope here with varying sizes and address
* offsets, and we take full advantage of sections.
*/
-static void __init
-create_mapping(unsigned long *mem_ptr, struct map_desc *md)
+static void __init create_mapping(struct map_desc *md)
{
unsigned long virt, length;
int prot_sect, prot_pte;
@@ -205,7 +227,7 @@ create_mapping(unsigned long *mem_ptr, struct map_desc *md)
length = md->length;
while ((virt & 1048575 || (virt + off) & 1048575) && length >= PAGE_SIZE) {
- alloc_init_page(mem_ptr, virt, virt + off, md->domain, prot_pte);
+ alloc_init_page(virt, virt + off, md->domain, prot_pte);
virt += PAGE_SIZE;
length -= PAGE_SIZE;
@@ -219,7 +241,7 @@ create_mapping(unsigned long *mem_ptr, struct map_desc *md)
}
while (length >= PAGE_SIZE) {
- alloc_init_page(mem_ptr, virt, virt + off, md->domain, prot_pte);
+ alloc_init_page(virt, virt + off, md->domain, prot_pte);
virt += PAGE_SIZE;
length -= PAGE_SIZE;
@@ -227,17 +249,15 @@ create_mapping(unsigned long *mem_ptr, struct map_desc *md)
}
/*
- * Initial boot-time mapping. This covers just the
- * zero page, kernel and the flush area. NB: it
- * must be sorted by virtual address, and no
+ * Initial boot-time mapping. This covers just the zero page, kernel and
+ * the flush area. NB: it must be sorted by virtual address, and no
* virtual address overlaps.
- * init_map[2..4] are for architectures with small
- * amounts of banked memory.
+ * init_map[2..4] are for architectures with banked memory.
*/
static struct map_desc init_map[] __initdata = {
{ 0, 0, PAGE_SIZE, DOMAIN_USER, 0, 0, 1, 0 }, /* zero page */
{ 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, /* kernel memory */
- { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 },
+ { 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 }, /* (4 banks) */
{ 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 },
{ 0, 0, 0, DOMAIN_KERNEL, 0, 1, 1, 1 },
{ 0, 0, PGDIR_SIZE, DOMAIN_KERNEL, 1, 0, 1, 1 }, /* cache flush 1 */
@@ -246,19 +266,15 @@ static struct map_desc init_map[] __initdata = {
#define NR_INIT_MAPS (sizeof(init_map) / sizeof(init_map[0]))
-unsigned long __init
-setup_page_tables(unsigned long start_mem, unsigned long end_mem)
+void __init pagetable_init(void)
{
unsigned long address = 0;
- int idx = 0;
+ int i;
/*
- * Correct the above mappings
+ * Setup the above mappings
*/
- init_map[0].physical =
- init_map[1].physical = __virt_to_phys(PAGE_OFFSET);
- init_map[1].virtual = PAGE_OFFSET;
- init_map[1].length = end_mem - PAGE_OFFSET;
+ init_map[0].physical = PHYS_OFFSET;
init_map[5].physical = FLUSH_BASE_PHYS;
init_map[5].virtual = FLUSH_BASE;
#ifdef FLUSH_BASE_MINICACHE
@@ -267,109 +283,108 @@ setup_page_tables(unsigned long start_mem, unsigned long end_mem)
init_map[6].length = PGDIR_SIZE;
#endif
+ for (i = 0; i < meminfo.nr_banks; i++) {
+ init_map[i+1].physical = PHYS_OFFSET + meminfo.bank[i].start;
+ init_map[i+1].virtual = PAGE_OFFSET + meminfo.bank[i].start;
+ init_map[i+1].length = meminfo.bank[i].size;
+ }
+
/*
- * Firstly, go through the initial mappings,
- * but clear out any pgdir entries that are
- * not in the description.
+ * Go through the initial mappings, but clear out any
+ * pgdir entries that are not in the description.
*/
+ i = 0;
do {
- if (address < init_map[idx].virtual || idx == NR_INIT_MAPS) {
+ if (address < init_map[i].virtual || i == NR_INIT_MAPS) {
free_init_section(address);
address += PGDIR_SIZE;
} else {
- create_mapping(&start_mem, init_map + idx);
+ create_mapping(init_map + i);
- address = init_map[idx].virtual + init_map[idx].length;
+ address = init_map[i].virtual + init_map[i].length;
address = (address + PGDIR_SIZE - 1) & PGDIR_MASK;
do {
- idx += 1;
- } while (init_map[idx].length == 0 && idx < NR_INIT_MAPS);
+ i += 1;
+ } while (init_map[i].length == 0 && i < NR_INIT_MAPS);
}
} while (address != 0);
/*
- * Now, create the architecture specific mappings
+ * Create the architecture specific mappings
*/
- for (idx = 0; idx < io_desc_size; idx++)
- create_mapping(&start_mem, io_desc + idx);
+ for (i = 0; i < io_desc_size; i++)
+ create_mapping(io_desc + i);
flush_cache_all();
-
- return start_mem;
}
/*
- * The mem_map array can get very big. Mark the end of the
- * valid mem_map banks with PG_skip, and setup the address
- * validity bitmap.
+ * The mem_map array can get very big. Mark the end of the valid mem_map
+ * banks with PG_skip, and setup the address validity bitmap.
*/
-unsigned long __init
-create_mem_holes(unsigned long start_mem, unsigned long end_mem)
+void __init create_memmap_holes(void)
{
+ unsigned int start_pfn, end_pfn = -1;
struct page *pg = NULL;
unsigned int sz, i;
- if (!machine_is_riscpc())
- return start_mem;
+ for (i = 0; i < meminfo.nr_banks; i++) {
+ if (meminfo.bank[i].size == 0)
+ continue;
- sz = (end_mem - PAGE_OFFSET) >> 20;
- sz = (sz + 31) >> 3;
-
- valid_addr_bitmap = (unsigned long *)start_mem;
- start_mem += sz;
+ start_pfn = meminfo.bank[i].start >> PAGE_SHIFT;
- memset(valid_addr_bitmap, 0, sz);
+ /*
+ * subtle here - if we have a full bank, then
+ * start_pfn == end_pfn, and we don't want to
+ * set PG_skip, or next_hash
+ */
+ if (pg && start_pfn != end_pfn) {
+ set_bit(PG_skip, &pg->flags);
+ pg->next_hash = mem_map + start_pfn;
- if (start_mem > mem_desc[0].virt_end)
- printk(KERN_CRIT "*** Error: RAM bank 0 too small\n");
+ start_pfn = PAGE_ALIGN(__pa(pg + 1));
+ end_pfn = __pa(pg->next_hash) & PAGE_MASK;
- for (i = 0; i < mem_desc_size; i++) {
- unsigned int idx, end;
+ if (end_pfn != start_pfn)
+ free_bootmem(start_pfn, end_pfn - start_pfn);
- if (pg) {
- pg->next_hash = mem_map +
- MAP_NR(mem_desc[i].virt_start);
pg = NULL;
}
- idx = __kern_valid_idx(mem_desc[i].virt_start);
- end = __kern_valid_idx(mem_desc[i].virt_end);
-
- do
- set_bit(idx, valid_addr_bitmap);
- while (++idx < end);
-
- if (mem_desc[i].virt_end < end_mem) {
- pg = mem_map + MAP_NR(mem_desc[i].virt_end);
+ end_pfn = (meminfo.bank[i].start +
+ meminfo.bank[i].size) >> PAGE_SHIFT;
- set_bit(PG_skip, &pg->flags);
- }
+ if (end_pfn != meminfo.end >> PAGE_SHIFT)
+ pg = mem_map + end_pfn;
}
- if (pg)
+ if (pg) {
+ set_bit(PG_skip, &pg->flags);
pg->next_hash = NULL;
-
- return start_mem;
-}
-
-void __init
-mark_usable_memory_areas(unsigned long start_mem, unsigned long end_mem)
-{
- /*
- * Mark all of memory from the end of kernel to end of memory
- */
- while (start_mem < end_mem) {
- clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
- start_mem += PAGE_SIZE;
}
+#if 0
/*
- * Mark memory from page 1 to start of the swapper page directory
+ * setup address validity map
+ * - don't think this is used anymore?
*/
- start_mem = PAGE_OFFSET + PAGE_SIZE;
- while (start_mem < (unsigned long)&swapper_pg_dir) {
- clear_bit(PG_reserved, &mem_map[MAP_NR(start_mem)].flags);
- start_mem += PAGE_SIZE;
+ sz = meminfo.end >> (PAGE_SHIFT + 8); /* in MB */
+ sz = (sz + 31) >> 3;
+
+ valid_addr_bitmap = alloc_bootmem(sz);
+ memzero(valid_addr_bitmap, sz);
+
+ for (i = 0; i < meminfo.nr_banks; i++) {
+ int idx, end;
+
+ idx = meminfo.bank[i].start >> 20;
+ end = (meminfo.bank[i].start +
+ meminfo.bank[i].size) >> 20;
+ do
+ set_bit(idx, valid_addr_bitmap);
+ while (++idx < end);
}
-}
+#endif
+}
diff --git a/arch/arm/mm/mm-ebsa110.c b/arch/arm/mm/mm-ebsa110.c
index 8086bbc08..a1172b1f1 100644
--- a/arch/arm/mm/mm-ebsa110.c
+++ b/arch/arm/mm/mm-ebsa110.c
@@ -13,17 +13,11 @@
#include "map.h"
-struct mem_desc mem_desc[] __initdata = {
- 0, 0
-};
-
-unsigned int __initdata mem_desc_size = 0;
+#define SIZE(x) (sizeof(x) / sizeof(x[0]))
const struct map_desc io_desc[] __initdata = {
{ IO_BASE - PGDIR_SIZE, 0xc0000000, PGDIR_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
{ IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }
};
-#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0]))
-
-unsigned int __initdata io_desc_size = SIZEOFMAP;
+unsigned int __initdata io_desc_size = SIZE(io_desc);
diff --git a/arch/arm/mm/mm-footbridge.c b/arch/arm/mm/mm-footbridge.c
index 74bac27ea..b67cdec33 100644
--- a/arch/arm/mm/mm-footbridge.c
+++ b/arch/arm/mm/mm-footbridge.c
@@ -17,6 +17,8 @@
#include "map.h"
+#define SIZE(x) (sizeof(x) / sizeof(x[0]))
+
/*
* The first entry allows us to fiddle with the EEPROM from user-space.
* This entry will go away in time, once the fmu32 can mmap() the
@@ -89,17 +91,9 @@ unsigned long __bus_to_virt(unsigned long res)
#endif
-struct mem_desc mem_desc[] __initdata = {
- 0, 0
-};
-
-unsigned int __initdata mem_desc_size = 0;
-
struct map_desc io_desc[] __initdata = {
MAPPING
};
-#define SIZE(x) (sizeof(x) / sizeof(x[0]))
-
unsigned int __initdata io_desc_size = SIZE(io_desc);
diff --git a/arch/arm/mm/mm-nexuspci.c b/arch/arm/mm/mm-nexuspci.c
index a4ee48f8d..5b66faa51 100644
--- a/arch/arm/mm/mm-nexuspci.c
+++ b/arch/arm/mm/mm-nexuspci.c
@@ -18,11 +18,7 @@
#include "map.h"
-struct mem_desc mem_desc[] __initdata = {
- 0, 0
-};
-
-unsigned int __initdata mem_desc_size = 0;
+#define SIZE(x) (sizeof(x) / sizeof(x[0]))
const struct map_desc io_desc[] __initdata = {
{ 0xfff00000, 0x10000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
@@ -32,6 +28,4 @@ const struct map_desc io_desc[] __initdata = {
{ 0xfd000000, 0x88000000, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 }
};
-#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0]))
-
-unsigned int __initdata io_desc_size = SIZEOFMAP;
+unsigned int __initdata io_desc_size = SIZE(io_desc);
diff --git a/arch/arm/mm/mm-rpc.c b/arch/arm/mm/mm-rpc.c
index 634bb3c8f..0490cbdd0 100644
--- a/arch/arm/mm/mm-rpc.c
+++ b/arch/arm/mm/mm-rpc.c
@@ -16,28 +16,6 @@
#define SIZE(x) (sizeof(x) / sizeof(x[0]))
-struct mem_desc mem_desc[] __initdata = {
- { 0xc0000000, 0xc0000000 },
- { 0xc4000000, 0xc4000000 },
- { 0xc8000000, 0xc8000000 },
- { 0xcc000000, 0xcc000000 }
-};
-
-unsigned int __initdata mem_desc_size = SIZE(mem_desc);
-
-void __init
-init_dram_banks(struct param_struct *params)
-{
- unsigned int bank;
-
- for (bank = 0; bank < mem_desc_size; bank++)
- mem_desc[bank].virt_end += PAGE_SIZE *
- params->u1.s.pages_in_bank[bank];
-
- params->u1.s.nr_pages = mem_desc[3].virt_end - PAGE_OFFSET;
- params->u1.s.nr_pages /= PAGE_SIZE;
-}
-
struct map_desc io_desc[] __initdata = {
/* VRAM */
{ SCREEN2_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 },
diff --git a/arch/arm/mm/mm-tbox.c b/arch/arm/mm/mm-tbox.c
index a6dd2a28f..78250336e 100644
--- a/arch/arm/mm/mm-tbox.c
+++ b/arch/arm/mm/mm-tbox.c
@@ -18,11 +18,7 @@
#include "map.h"
-struct mem_desc mem_desc[] __initdata = {
- 0, 0
-};
-
-unsigned int __initdata mem_desc_size = 0;
+#define SIZE(x) (sizeof(x) / sizeof(x[0]))
/* Logical Physical
* 0xffff1000 0x00100000 DMA registers
@@ -60,6 +56,4 @@ const struct map_desc io_desc[] __initdata = {
{ 0xffffe000, 0x00e00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }
};
-#define SIZEOFMAP (sizeof(mapping) / sizeof(mapping[0]))
-
-unsigned int __initdata io_desc_size = SIZEOFMAP;
+unsigned int __initdata io_desc_size = SIZE(io_desc);
diff --git a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S
index df2e13357..dcb5c10dc 100644
--- a/arch/arm/mm/proc-arm2,3.S
+++ b/arch/arm/mm/proc-arm2,3.S
@@ -327,7 +327,7 @@ arm2_elf_name: .asciz "v1"
arm3_elf_name: .asciz "v2"
.align
- .section ".proc.info", #alloc
+ .section ".proc.info", #alloc, #execinstr
.long 0x41560200
.long 0xfffffff0
diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S
index f3819fa01..b085c3c4e 100644
--- a/arch/arm/mm/proc-arm6,7.S
+++ b/arch/arm/mm/proc-arm6,7.S
@@ -532,7 +532,7 @@ cpu_elf_name: .asciz "v3"
.size cpu_elf_name, . - cpu_elf_name
.align
- .section ".proc.info", #alloc
+ .section ".proc.info", #alloc, #execinstr
.type __arm6_proc_info, #object
__arm6_proc_info:
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 73c0f83df..266d960b5 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -446,7 +446,8 @@ ENTRY(cpu_sa1100_reset)
bl cpu_sa110_flush_tlb_all
mcr p15, 0, ip, c7, c7, 0 @ flush I,D caches
mrc p15, 0, r0, c1, c0, 0 @ ctrl register
- bic r0, r0, #1 @ ...............m
+ bic r0, r0, #0x000f @ ............wcam
+ bic r0, r0, #0x1100 @ ...i...s........
ldmfd sp!, {r1, pc}
/*
* Purpose : Function pointers used to access above functions - all calls
@@ -546,6 +547,7 @@ cpu_elf_name: .asciz "v4"
.align
.section ".proc.info", #alloc, #execinstr
+
.type __sa110_proc_info,#object
__sa110_proc_info:
.long 0x4401a100
diff --git a/arch/arm/mm/small_page.c b/arch/arm/mm/small_page.c
index 6bdc6cfc7..ac303d45e 100644
--- a/arch/arm/mm/small_page.c
+++ b/arch/arm/mm/small_page.c
@@ -21,205 +21,201 @@
#include <linux/swap.h>
#include <linux/smp.h>
-#if PAGE_SIZE == 4096
-/* 2K blocks */
-#define SMALL_ALLOC_SHIFT (11)
-#define NAME(x) x##_2k
-#elif PAGE_SIZE == 32768 || PAGE_SIZE == 16384
-/* 8K blocks */
-#define SMALL_ALLOC_SHIFT (13)
-#define NAME(x) x##_8k
-#endif
+#include <asm/bitops.h>
+#include <asm/pgtable.h>
-#define SMALL_ALLOC_SIZE (1 << SMALL_ALLOC_SHIFT)
-#define NR_BLOCKS (PAGE_SIZE / SMALL_ALLOC_SIZE)
-#define BLOCK_MASK ((1 << NR_BLOCKS) - 1)
+#define PEDANTIC
-#define USED(pg) ((atomic_read(&(pg)->count) >> 8) & BLOCK_MASK)
-#define SET_USED(pg,off) (atomic_read(&(pg)->count) |= 256 << off)
-#define CLEAR_USED(pg,off) (atomic_read(&(pg)->count) &= ~(256 << off))
-#define ALL_USED BLOCK_MASK
-#define IS_FREE(pg,off) (!(atomic_read(&(pg)->count) & (256 << off)))
-#define SM_PAGE_PTR(page,block) ((struct free_small_page *)((page) + \
- ((block) << SMALL_ALLOC_SHIFT)))
-
-#if NR_BLOCKS != 2 && NR_BLOCKS != 4
-#error I only support 2 or 4 blocks per page
-#endif
+/*
+ * Requirement:
+ * We need to be able to allocate naturally aligned memory of finer
+ * granularity than the page size. This is typically used for the
+ * second level page tables on 32-bit ARMs.
+ *
+ * Theory:
+ * We "misuse" the Linux memory management system. We use alloc_page
+ * to allocate a page and then mark it as reserved. The Linux memory
+ * management system will then ignore the "offset", "next_hash" and
+ * "pprev_hash" entries in the mem_map for this page.
+ *
+ * We then use a bitstring in the "offset" field to mark which segments
+ * of the page are in use, and manipulate this as required during the
+ * allocation and freeing of these small pages.
+ *
+ * We also maintain a queue of pages being used for this purpose using
+ * the "next_hash" and "pprev_hash" entries of mem_map;
+ */
-struct free_small_page {
- unsigned long next;
- unsigned long prev;
+struct order {
+ struct page *queue;
+ unsigned int mask; /* (1 << shift) - 1 */
+ unsigned int shift; /* (1 << shift) size of page */
+ unsigned int block_mask; /* nr_blocks - 1 */
+ unsigned int all_used; /* (1 << nr_blocks) - 1 */
};
-/*
- * To handle allocating small pages, we use the main get_free_page routine,
- * and split the page up into 4. The page is marked in mem_map as reserved,
- * so it can't be free'd by free_page. The count field is used to keep track
- * of which sections of this page are allocated.
- */
-static unsigned long small_page_ptr;
-
-static unsigned char offsets[1<<NR_BLOCKS] = {
- 0, /* 0000 */
- 1, /* 0001 */
- 0, /* 0010 */
- 2, /* 0011 */
-#if NR_BLOCKS == 4
- 0, /* 0100 */
- 1, /* 0101 */
- 0, /* 0110 */
- 3, /* 0111 */
- 0, /* 1000 */
- 1, /* 1001 */
- 0, /* 1010 */
- 2, /* 1011 */
- 0, /* 1100 */
- 1, /* 1101 */
- 0, /* 1110 */
- 4 /* 1111 */
+
+static struct order orders[] = {
+#if PAGE_SIZE == 4096
+ { NULL, 2047, 11, 1, 0x00000003 }
+#elif PAGE_SIZE == 32768
+ { NULL, 2047, 11, 15, 0x0000ffff },
+ { NULL, 8191, 13, 3, 0x0000000f }
+#else
+#error unsupported page size
#endif
};
-static inline void clear_page_links(unsigned long page)
-{
- struct free_small_page *fsp;
- int i;
+#define USED_MAP(pg) ((pg)->offset)
+#define TEST_AND_CLEAR_USED(pg,off) (test_and_clear_bit(off, &(pg)->offset))
+#define SET_USED(pg,off) (set_bit(off, &(pg)->offset))
- for (i = 0; i < NR_BLOCKS; i++) {
- fsp = SM_PAGE_PTR(page, i);
- fsp->next = fsp->prev = 0;
- }
-}
-
-static inline void set_page_links_prev(unsigned long page, unsigned long prev)
+static void add_page_to_queue(struct page *page, struct page **p)
{
- struct free_small_page *fsp;
- unsigned int mask;
- int i;
-
- if (!page)
- return;
-
- mask = USED(&mem_map[MAP_NR(page)]);
- for (i = 0; i < NR_BLOCKS; i++) {
- if (mask & (1 << i))
- continue;
- fsp = SM_PAGE_PTR(page, i);
- fsp->prev = prev;
- }
+#ifdef PEDANTIC
+ if (page->pprev_hash)
+ PAGE_BUG(page);
+#endif
+ page->next_hash = *p;
+ if (*p)
+ (*p)->pprev_hash = &page->next_hash;
+ *p = page;
+ page->pprev_hash = p;
}
-static inline void set_page_links_next(unsigned long page, unsigned long next)
+static void remove_page_from_queue(struct page *page)
{
- struct free_small_page *fsp;
- unsigned int mask;
- int i;
-
- if (!page)
- return;
-
- mask = USED(&mem_map[MAP_NR(page)]);
- for (i = 0; i < NR_BLOCKS; i++) {
- if (mask & (1 << i))
- continue;
- fsp = SM_PAGE_PTR(page, i);
- fsp->next = next;
+ if (page->pprev_hash) {
+ if (page->next_hash)
+ page->next_hash->pprev_hash = page->pprev_hash;
+ *page->pprev_hash = page->next_hash;
+ page->pprev_hash = NULL;
}
}
-unsigned long NAME(get_page)(int priority)
+static unsigned long __get_small_page(int priority, struct order *order)
{
- struct free_small_page *fsp;
- unsigned long new_page;
unsigned long flags;
struct page *page;
int offset;
save_flags(flags);
- if (!small_page_ptr)
+ if (!order->queue)
goto need_new_page;
+
cli();
+ page = order->queue;
again:
- page = mem_map + MAP_NR(small_page_ptr);
- offset = offsets[USED(page)];
+#ifdef PEDANTIC
+ if (USED_MAP(page) & ~order->all_used)
+ PAGE_BUG(page);
+#endif
+ offset = ffz(USED_MAP(page));
SET_USED(page, offset);
- new_page = (unsigned long)SM_PAGE_PTR(small_page_ptr, offset);
- if (USED(page) == ALL_USED) {
- fsp = (struct free_small_page *)new_page;
- set_page_links_prev (fsp->next, 0);
- small_page_ptr = fsp->next;
- }
+ if (USED_MAP(page) == order->all_used)
+ remove_page_from_queue(page);
restore_flags(flags);
- return new_page;
+
+ return page_address(page) + (offset << order->shift);
need_new_page:
- new_page = __get_free_page(priority);
- if (!small_page_ptr) {
- if (new_page) {
- set_bit (PG_reserved, &mem_map[MAP_NR(new_page)].flags);
- clear_page_links (new_page);
- cli();
- small_page_ptr = new_page;
- goto again;
- }
- restore_flags(flags);
- return 0;
+ page = alloc_page(priority);
+ if (!order->queue) {
+ if (!page)
+ goto no_page;
+ SetPageReserved(page);
+ USED_MAP(page) = 0;
+ cli();
+ add_page_to_queue(page, &order->queue);
+ } else {
+ __free_page(page);
+ cli();
+ page = order->queue;
}
- free_page(new_page);
- cli();
goto again;
+
+no_page:
+ restore_flags(flags);
+ return 0;
}
-void NAME(free_page)(unsigned long spage)
+static void __free_small_page(unsigned long spage, struct order *order)
{
- struct free_small_page *ofsp, *cfsp;
unsigned long flags;
+ unsigned long nr;
struct page *page;
- int offset, oldoffset;
-
- if (!spage)
- goto none;
-
- offset = (spage >> SMALL_ALLOC_SHIFT) & (NR_BLOCKS - 1);
- spage -= offset << SMALL_ALLOC_SHIFT;
-
- page = mem_map + MAP_NR(spage);
- if (!PageReserved(page) || !USED(page))
- goto non_small;
-
- if (IS_FREE(page, offset))
- goto free;
-
- save_flags_cli (flags);
- oldoffset = offsets[USED(page)];
- CLEAR_USED(page, offset);
- ofsp = SM_PAGE_PTR(spage, oldoffset);
- cfsp = SM_PAGE_PTR(spage, offset);
-
- if (oldoffset == NR_BLOCKS) { /* going from totally used to mostly used */
- cfsp->prev = 0;
- cfsp->next = small_page_ptr;
- set_page_links_prev (small_page_ptr, spage);
- small_page_ptr = spage;
- } else if (!USED(page)) {
- set_page_links_prev (ofsp->next, ofsp->prev);
- set_page_links_next (ofsp->prev, ofsp->next);
- if (spage == small_page_ptr)
- small_page_ptr = ofsp->next;
- clear_bit (PG_reserved, &page->flags);
+
+ nr = MAP_NR(spage);
+ if (nr < max_mapnr) {
+ page = mem_map + nr;
+
+ /*
+ * The container-page must be marked Reserved
+ */
+ if (!PageReserved(page) || spage & order->mask)
+ goto non_small;
+
+#ifdef PEDANTIC
+ if (USED_MAP(page) & ~order->all_used)
+ PAGE_BUG(page);
+#endif
+
+ spage = spage >> order->shift;
+ spage &= order->block_mask;
+
+ /*
+ * the following must be atomic wrt get_page
+ */
+ save_flags_cli(flags);
+
+ if (USED_MAP(page) == order->all_used)
+ add_page_to_queue(page, &order->queue);
+
+ if (!TEST_AND_CLEAR_USED(page, spage))
+ goto already_free;
+
+ if (USED_MAP(page) == 0)
+ goto free_page;
+
restore_flags(flags);
- free_page (spage);
- } else
- *cfsp = *ofsp;
+ }
+ return;
+
+free_page:
+ /*
+ * unlink the page from the small page queue and free it
+ */
+ remove_page_from_queue(page);
restore_flags(flags);
+ ClearPageReserved(page);
+ __free_page(page);
return;
non_small:
- printk ("Trying to free non-small page from %p\n", __builtin_return_address(0));
- return;
-free:
- printk ("Trying to free free small page from %p\n", __builtin_return_address(0));
-none:
+ printk("Trying to free non-small page from %p\n", __builtin_return_address(0));
return;
+already_free:
+ printk("Trying to free free small page from %p\n", __builtin_return_address(0));
}
+
+unsigned long get_page_2k(int priority)
+{
+ return __get_small_page(priority, orders+0);
+}
+
+void free_page_2k(unsigned long spage)
+{
+ __free_small_page(spage, orders+0);
+}
+
+#if PAGE_SIZE > 8192
+unsigned long get_page_8k(int priority)
+{
+ return __get_small_page(priority, orders+1);
+}
+
+void free_page_8k(unsigned long spage)
+{
+ __free_small_page(spage, orders+1);
+}
+#endif
diff --git a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in
index 446f49924..5fbafe77a 100644
--- a/arch/arm/vmlinux-armo.lds.in
+++ b/arch/arm/vmlinux-armo.lds.in
@@ -7,7 +7,8 @@ ENTRY(stext)
SECTIONS
{
. = TEXTADDR;
- __init_begin = .;
+
+ __init_begin = .; /* Init code and data */
.text.init : { *(.text.init) }
__proc_info_begin = .;
.proc.info : { *(.proc.info) }
@@ -27,43 +28,44 @@ SECTIONS
*(.init.task)
}
- _text = .; /* Text and read-only data */
+ _text = .; /* Text and read-only data */
.text : {
*(.text)
*(.fixup)
*(.gnu.warning)
}
+
.text.lock : { *(.text.lock) } /* out-of-line lock text */
.rodata : { *(.rodata) }
.kstrtab : { *(.kstrtab) }
- . = ALIGN(16); /* Exception table */
+ . = ALIGN(16); /* Exception table */
__start___ex_table = .;
__ex_table : { *(__ex_table) }
__stop___ex_table = .;
- __start___ksymtab = .; /* Kernel symbol table */
+ __start___ksymtab = .; /* Kernel symbol table */
__ksymtab : { *(__ksymtab) }
__stop___ksymtab = .;
- .got : { *(.got) } /* Global offset table */
+ .got : { *(.got) } /* Global offset table */
- _etext = .; /* End of text section */
+ _etext = .; /* End of text section */
- .data : { /* Data */
+ .data : { /* Data */
*(.data)
CONSTRUCTORS
}
- _edata = .; /* End of data section */
+ _edata = .; /* End of data section */
- __bss_start = .; /* BSS */
+ __bss_start = .; /* BSS */
.bss : {
*(.bss)
}
_end = . ;
- /* Stabs debugging sections. */
+ /* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
index 128b53427..92ae6af45 100644
--- a/arch/i386/boot/compressed/misc.c
+++ b/arch/i386/boot/compressed/misc.c
@@ -9,6 +9,7 @@
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
*/
+#include <linux/mm.h>
#include <asm/segment.h>
#include <asm/io.h>
diff --git a/arch/i386/config.in b/arch/i386/config.in
index 47b2fce5a..03433d968 100644
--- a/arch/i386/config.in
+++ b/arch/i386/config.in
@@ -104,6 +104,11 @@ source drivers/pcmcia/Config.in
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 a.out binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
@@ -116,7 +121,6 @@ if [ "$CONFIG_APM" != "n" ]; then
bool ' Enable PM at boot time' CONFIG_APM_DO_ENABLE
bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
- bool ' Power off on shutdown' CONFIG_APM_POWER_OFF
bool ' Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
bool ' Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE
bool ' RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index a2d091cae..6aa8412c1 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -63,6 +63,8 @@ CONFIG_I82365=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=y
@@ -297,6 +299,9 @@ CONFIG_PCMCIA_PCNET=y
# CONFIG_PCMCIA_NMCLAN is not set
# CONFIG_PCMCIA_SMC91C92 is not set
# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_3C575 is not set
+# CONFIG_PCMCIA_TULIP is not set
+# CONFIG_PCMCIA_EPIC100 is not set
CONFIG_PCMCIA_RAYCS=y
# CONFIG_PCMCIA_NETWAVE is not set
# CONFIG_PCMCIA_WAVELAN is not set
@@ -343,6 +348,10 @@ CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
@@ -366,6 +375,12 @@ CONFIG_PSMOUSE=y
# CONFIG_FTAPE is not set
#
+# PCMCIA character device support
+#
+# CONFIG_PCMCIA_SERIAL_CS is not set
+# CONFIG_PCMCIA_SERIAL_CB is not set
+
+#
# USB drivers - not for the faint of heart
#
# CONFIG_USB is not set
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index 29afabd7a..55790ac25 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -59,7 +59,4 @@ ifdef CONFIG_X86_VISWS_APIC
O_OBJS += visws_apic.o
endif
-head.o: head.S
- $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $*.S -o $*.o
-
include $(TOPDIR)/Rules.make
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index a54994667..cdeaf9a35 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -1,8 +1,8 @@
/* -*- linux-c -*-
* APM BIOS driver for Linux
- * Copyright 1994-1998 Stephen Rothwell
- * (Stephen.Rothwell@canb.auug.org.au)
- * Development of this driver was funded by NEC Australia P/L
+ * Copyright 1994-1999 Stephen Rothwell (sfr@linuxcare.com)
+ *
+ * Initial development of this driver was funded by NEC Australia P/L
* and NEC Corporation
*
* This program is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
* Nov 1998, Version 1.7
* Jan 1999, Version 1.8
* Jan 1999, Version 1.9
+ * Oct 1999, Version 1.10
*
* History:
* 0.6b: first version in official kernel, Linux 1.3.46
@@ -90,6 +91,16 @@
* Use CONFIG_SMP instead of __SMP__
* Ignore BOUNCES for three seconds.
* Stephen Rothwell
+ * 1.10: Fix for Thinkpad return code.
+ * Merge 2.2 and 2.3 drivers.
+ * Remove APM dependencies in arch/i386/kernel/process.c
+ * Remove APM dependencies in drivers/char/sysrq.c
+ * Reset time across standby.
+ * Allow more inititialisation on SMP.
+ * Remove CONFIG_APM_POWER_OFF and make it boot time
+ * configurable (default on).
+ * Make debug only a boot time parameter (remove APM_DEBUG).
+ * Try to blank all devices on any error.
*
* APM 1.1 Reference:
*
@@ -106,11 +117,8 @@
* Intel Corporation, Microsoft Corporation. Advanced Power Management
* (APM) BIOS Interface Specification, Revision 1.2, February 1996.
*
- * [This document is available from Intel at:
- * http://www.intel.com/IAL/powermgm
- * or Microsoft at
- * http://www.microsoft.com/windows/thirdparty/hardware/pcfuture.htm
- * ]
+ * [This document is available from Microsoft at:
+ * http://www.microsoft.com/hwdev/busbios/amp_12.htm]
*/
#include <linux/config.h>
@@ -122,7 +130,6 @@
#include <linux/timer.h>
#include <linux/fcntl.h>
#include <linux/malloc.h>
-#include <linux/linkage.h>
#include <linux/stat.h>
#include <linux/proc_fs.h>
#include <linux/miscdevice.h>
@@ -133,62 +140,32 @@
#include <asm/uaccess.h>
#include <asm/desc.h>
+/*
+ * Make APM look as much as just another ACPI module as possible..
+ */
+#include <linux/acpi.h>
+
EXPORT_SYMBOL(apm_register_callback);
EXPORT_SYMBOL(apm_unregister_callback);
extern unsigned long get_cmos_time(void);
+extern void (*sysrq_power_off)(void);
+
/*
* The apm_bios device is one of the misc char devices.
* This is its minor number.
*/
#define APM_MINOR_DEV 134
-/* Configurable options:
- *
- * CONFIG_APM_IGNORE_USER_SUSPEND: define to ignore USER SUSPEND requests.
- * This is necessary on the NEC Versa M series, which generates these when
- * resuming from SYSTEM SUSPEND. However, enabling this on other laptops
- * will cause the laptop to generate a CRITICAL SUSPEND when an appropriate
- * USER SUSPEND is ignored -- this may prevent the APM driver from updating
- * the system time on a RESUME.
- *
- * CONFIG_APM_DO_ENABLE: enable APM features at boot time. From page 36 of
- * the specification: "When disabled, the APM BIOS does not automatically
- * power manage devices, enter the Standby State, enter the Suspend State,
- * or take power saving steps in response to CPU Idle calls." This driver
- * will make CPU Idle calls when Linux is idle (unless this feature is
- * turned off -- see below). This should always save battery power, but
- * more complicated APM features will be dependent on your BIOS
- * implementation. You may need to turn this option off if your computer
- * hangs at boot time when using APM support, or if it beeps continuously
- * instead of suspending. Turn this off if you have a NEC UltraLite Versa
- * 33/C or a Toshiba T400CDT. This is off by default since most machines
- * do fine without this feature.
- *
- * CONFIG_APM_CPU_IDLE: enable calls to APM CPU Idle/CPU Busy inside the
- * idle loop. On some machines, this can activate improved power savings,
- * such as a slowed CPU clock rate, when the machine is idle. These idle
- * call is made after the idle loop has run for some length of time (e.g.,
- * 333 mS). On some machines, this will cause a hang at boot time or
- * whenever the CPU becomes idle.
- *
- * CONFIG_APM_DISPLAY_BLANK: enable console blanking using the APM. Some
- * laptops can use this to turn of the LCD backlight when the VC screen
- * blanker blanks the screen. Note that this is only used by the VC screen
- * blanker, and probably won't turn off the backlight when using X11. Some
- * problems have been reported when using this option with gpm (if you'd
- * like to debug this, please do so).
- *
- * CONFIG_APM_IGNORE_MULTIPLE_SUSPEND: The IBM TP560 bios seems to insist
- * on returning multiple suspend/standby events whenever one occurs. We
- * really only need one at a time, so just ignore any beyond the first.
- * This is probably safe on most laptops.
- *
- * If you are debugging the APM support for your laptop, note that code for
- * all of these options is contained in this file, so you can #define or
- * #undef these on the next line to avoid recompiling the whole kernel.
+/*
+ * See Documentation/Config.help for the configuration options.
*
+ * Various options can be changed at boot time as follows:
+ * apm=on/off enable/disable APM
+ * [no-]debug log some debugging messages
+ * [no-]power-off power off on shutdown
+ * [no-]smp-power-off allow power off even for SMP
*/
/* KNOWN PROBLEM MACHINES:
@@ -207,11 +184,6 @@ extern unsigned long get_cmos_time(void);
*/
/*
- * Define to have debug messages.
- */
-#undef APM_DEBUG
-
-/*
* Define to always call the APM BIOS busy routine even if the clock was
* not slowed by the idle routine.
*/
@@ -266,26 +238,6 @@ extern unsigned long get_cmos_time(void);
__asm__ __volatile__("movl %%" #seg ",%0" : "=m" (where))
/*
- * Forward declarations
- */
-static void suspend(void);
-static void standby(void);
-static void set_time(void);
-
-static void check_events(void);
-
-static int do_open(struct inode *, struct file *);
-static int do_release(struct inode *, struct file *);
-static ssize_t do_read(struct file *, char *, size_t , loff_t *);
-static unsigned int do_poll(struct file *, poll_table *);
-static int do_ioctl(struct inode *, struct file *, u_int, u_long);
-
-static int apm_get_info(char *, char **, off_t, int, int);
-
-extern int apm_register_callback(int (*)(apm_event_t));
-extern void apm_unregister_callback(int (*)(apm_event_t));
-
-/*
* Local variables
*/
static struct {
@@ -312,13 +264,13 @@ static int got_clock_diff = 0;
#endif
static int debug = 0;
static int apm_disabled = 0;
+static int power_off_enabled = 1;
static DECLARE_WAIT_QUEUE_HEAD(apm_waitqueue);
static struct apm_bios_struct * user_list = NULL;
-static char driver_version[] = "1.9"; /* no spaces */
+static char driver_version[] = "1.10"; /* no spaces */
-#ifdef APM_DEBUG
static char * apm_event_name[] = {
"system standby",
"system suspend",
@@ -335,28 +287,6 @@ static char * apm_event_name[] = {
};
#define NR_APM_EVENT_NAME \
(sizeof(apm_event_name) / sizeof(apm_event_name[0]))
-#endif
-
-static struct file_operations apm_bios_fops = {
- NULL, /* lseek */
- do_read,
- NULL, /* write */
- NULL, /* readdir */
- do_poll,
- do_ioctl,
- NULL, /* mmap */
- do_open,
- NULL, /* flush */
- do_release,
- NULL, /* fsync */
- NULL /* fasync */
-};
-
-static struct miscdevice apm_device = {
- APM_MINOR_DEV,
- "apm",
- &apm_bios_fops
-};
typedef struct callback_list_t {
int (* callback)(apm_event_t);
@@ -386,6 +316,7 @@ static const lookup_t error_table[] = {
{ APM_RESUME_DISABLED, "Resume timer disabled" },
{ APM_BAD_STATE, "Unable to enter requested state" },
/* N/A { APM_NO_EVENTS, "No events pending" }, */
+ { APM_NO_ERROR, "BIOS did not set a return code" },
{ APM_NOT_PRESENT, "No APM present" }
};
#define ERROR_COUNT (sizeof(error_table)/sizeof(lookup_t))
@@ -412,9 +343,10 @@ static const lookup_t error_table[] = {
# define APM_DO_CLI
#endif
#ifdef APM_ZERO_SEGS
+# define APM_DECL_SEGS \
+ unsigned int saved_fs; unsigned int saved_gs;
# define APM_DO_SAVE_SEGS \
- savesegment(fs, saved_fs); \
- savesegment(gs, saved_gs)
+ savesegment(fs, saved_fs); savesegment(gs, saved_gs)
# define APM_DO_ZERO_SEGS \
"pushl %%ds\n\t" \
"pushl %%es\n\t" \
@@ -427,20 +359,19 @@ static const lookup_t error_table[] = {
"popl %%es\n\t" \
"popl %%ds\n\t"
# define APM_DO_RESTORE_SEGS \
- loadsegment(fs, saved_fs); \
- loadsegment(gs, saved_gs)
+ loadsegment(fs, saved_fs); loadsegment(gs, saved_gs)
#else
+# define APM_DECL_SEGS
# define APM_DO_SAVE_SEGS
# define APM_DO_ZERO_SEGS
# define APM_DO_POP_SEGS
# define APM_DO_RESTORE_SEGS
#endif
-static u8 apm_bios_call(u32 eax_in, u32 ebx_in, u32 ecx_in,
+static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
u32 *eax, u32 *ebx, u32 *ecx, u32 *edx, u32 *esi)
{
- unsigned int saved_fs;
- unsigned int saved_gs;
+ APM_DECL_SEGS
unsigned long flags;
__save_flags(flags);
@@ -456,7 +387,7 @@ static u8 apm_bios_call(u32 eax_in, u32 ebx_in, u32 ecx_in,
APM_DO_POP_SEGS
: "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx),
"=S" (*esi)
- : "a" (eax_in), "b" (ebx_in), "c" (ecx_in)
+ : "a" (func), "b" (ebx_in), "c" (ecx_in)
: "memory", "cc");
APM_DO_RESTORE_SEGS;
__restore_flags(flags);
@@ -467,12 +398,10 @@ static u8 apm_bios_call(u32 eax_in, u32 ebx_in, u32 ecx_in,
* This version only returns one value (usually an error code)
*/
-static u8 apm_bios_call_simple(u32 eax_in, u32 ebx_in, u32 ecx_in,
- u32 *eax)
+static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
{
u8 error;
- unsigned int saved_fs;
- unsigned int saved_gs;
+ APM_DECL_SEGS
unsigned long flags;
__save_flags(flags);
@@ -491,7 +420,7 @@ static u8 apm_bios_call_simple(u32 eax_in, u32 ebx_in, u32 ecx_in,
APM_DO_POP_SEGS
: "=a" (*eax), "=b" (error), "=c" (cx), "=d" (dx),
"=S" (si)
- : "a" (eax_in), "b" (ebx_in), "c" (ecx_in)
+ : "a" (func), "b" (ebx_in), "c" (ecx_in)
: "memory", "cc");
}
APM_DO_RESTORE_SEGS;
@@ -499,11 +428,11 @@ static u8 apm_bios_call_simple(u32 eax_in, u32 ebx_in, u32 ecx_in,
return error;
}
-static int apm_driver_version(u_short *val)
+static int __init apm_driver_version(u_short *val)
{
u32 eax;
- if (apm_bios_call_simple(0x530e, 0, *val, &eax))
+ if (apm_bios_call_simple(APM_FUNC_VERSION, 0, *val, &eax))
return (eax >> 8) & 0xff;
*val = eax;
return APM_SUCCESS;
@@ -516,7 +445,8 @@ static int apm_get_event(apm_event_t *event, apm_eventinfo_t *info)
u32 ecx;
u32 dummy;
- if (apm_bios_call(0x530b, 0, 0, &eax, &ebx, &ecx, &dummy, &dummy))
+ if (apm_bios_call(APM_FUNC_GET_EVENT, 0, 0, &eax, &ebx, &ecx,
+ &dummy, &dummy))
return (eax >> 8) & 0xff;
*event = ebx;
if (apm_bios_info.version < 0x0102)
@@ -530,16 +460,44 @@ static int set_power_state(u_short what, u_short state)
{
u32 eax;
- if (apm_bios_call_simple(0x5307, what, state, &eax))
+ if (apm_bios_call_simple(APM_FUNC_SET_STATE, what, state, &eax))
return (eax >> 8) & 0xff;
return APM_SUCCESS;
}
static int apm_set_power_state(u_short state)
{
- return set_power_state(0x0001, state);
+ return set_power_state(APM_DEVICE_ALL, state);
}
+#ifdef CONFIG_APM_CPU_IDLE
+static int apm_do_idle(void)
+{
+ u32 dummy;
+
+ if (apm_bios_call_simple(APM_FUNC_IDLE, 0, 0, &dummy))
+ return 0;
+
+#ifdef ALWAYS_CALL_BUSY
+ clock_slowed = 1;
+#else
+ clock_slowed = (apm_bios_info.flags & APM_IDLE_SLOWS_CLOCK) != 0;
+#endif
+ return 1;
+}
+
+static void apm_do_busy(void)
+{
+ u32 dummy;
+
+ if (clock_slowed) {
+ (void) apm_bios_call_simple(APM_FUNC_BUSY, 0, 0, &dummy);
+ clock_slowed = 0;
+ }
+}
+
+extern int hlt_counter;
+
/*
* If no process has been interested in this
* CPU for some time, we want to wake up the
@@ -551,12 +509,10 @@ static int apm_set_power_state(u_short state)
/* This should wake up kapmd and ask it to slow the CPU */
#define powermanagement_idle() do { } while (0)
-extern int hlt_counter;
-
/*
* This is the idle thing.
*/
-void apm_cpu_idle(void)
+static void apm_cpu_idle(void)
{
unsigned int start_idle;
@@ -583,8 +539,9 @@ void apm_cpu_idle(void)
start_idle = jiffies;
}
}
+#endif
-void apm_power_off(void)
+static void apm_power_off(void)
{
/*
* smp_hack == 2 means that we would have enabled APM support
@@ -606,7 +563,7 @@ static int apm_set_display_power_state(u_short state)
/* Blank the first display device */
error = set_power_state(0x0100, state);
- if (error == APM_BAD_DEVICE)
+ if (error != APM_SUCCESS)
/* try to blank them all instead */
error = set_power_state(0x01ff, state);
return error;
@@ -618,8 +575,7 @@ static int __init apm_enable_power_management(void)
{
u32 eax;
- if (apm_bios_call_simple(0x5308,
- (apm_bios_info.version > 0x100) ? 0x0001 : 0xffff,
+ if (apm_bios_call_simple(APM_FUNC_ENABLE_PM, APM_DEVICE_BALL,
1, &eax))
return (eax >> 8) & 0xff;
apm_bios_info.flags &= ~APM_BIOS_DISABLED;
@@ -635,7 +591,8 @@ static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
u32 edx;
u32 dummy;
- if (apm_bios_call(0x530a, 1, 0, &eax, &ebx, &ecx, &edx, &dummy))
+ if (apm_bios_call(APM_FUNC_GET_STATUS, APM_DEVICE_ALL, 0,
+ &eax, &ebx, &ecx, &edx, &dummy))
return (eax >> 8) & 0xff;
*status = ebx;
*bat = ecx;
@@ -643,11 +600,40 @@ static int apm_get_power_status(u_short *status, u_short *bat, u_short *life)
return APM_SUCCESS;
}
+#if 0
+static int apm_get_battery_status(u_short which, u_short *status,
+ u_short *bat, u_short *life, u_short *nbat)
+{
+ u32 eax;
+ u32 ebx;
+ u32 ecx;
+ u32 edx;
+ u32 esi;
+
+ if (apm_bios_info.version < 0x0102) {
+ /* pretend we only have one battery. */
+ if (which != 1)
+ return APM_BAD_DEVICE;
+ *nbat = 1;
+ return apm_get_power_status(status, bat, life);
+ }
+
+ if (apm_bios_call(APM_FUNC_GET_STATUS, (0x8000 | (which)), 0, &eax,
+ &ebx, &ecx, &edx, &esi))
+ return (eax >> 8) & 0xff;
+ *status = ebx;
+ *bat = ecx;
+ *life = edx;
+ *nbat = esi;
+ return APM_SUCCESS;
+}
+#endif
+
static int __init apm_engage_power_management(u_short device)
{
u32 eax;
- if (apm_bios_call_simple(0x530f, device, 1, &eax))
+ if (apm_bios_call_simple(APM_FUNC_ENGAGE_PM, device, 1, &eax))
return (eax >> 8) & 0xff;
return APM_SUCCESS;
}
@@ -669,14 +655,12 @@ static void apm_error(char *str, int err)
int apm_display_blank(void)
{
#ifdef CONFIG_APM_DISPLAY_BLANK
- int error;
-
- if (!apm_enabled)
- return 0;
- error = apm_set_display_power_state(APM_STATE_STANDBY);
- if (error == APM_SUCCESS)
- return 1;
- apm_error("set display standby", error);
+ if (apm_enabled) {
+ int error = apm_set_display_power_state(APM_STATE_STANDBY);
+ if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
+ return 1;
+ apm_error("set display standby", error);
+ }
#endif
return 0;
}
@@ -685,14 +669,12 @@ int apm_display_blank(void)
int apm_display_unblank(void)
{
#ifdef CONFIG_APM_DISPLAY_BLANK
- int error;
-
- if (!apm_enabled)
- return 0;
- error = apm_set_display_power_state(APM_STATE_READY);
- if (error == APM_SUCCESS)
- return 1;
- apm_error("set display ready", error);
+ if (apm_enabled) {
+ int error = apm_set_display_power_state(APM_STATE_READY);
+ if ((error == APM_SUCCESS) || (error == APM_NO_ERROR))
+ return 1;
+ apm_error("set display ready", error);
+ }
#endif
return 0;
}
@@ -734,12 +716,12 @@ static apm_event_t get_queued_event(struct apm_bios_struct * as)
return as->events[as->event_tail];
}
-static int queue_event(apm_event_t event, struct apm_bios_struct *sender)
+static void queue_event(apm_event_t event, struct apm_bios_struct *sender)
{
struct apm_bios_struct * as;
if (user_list == NULL)
- return 0;
+ return;
for (as = user_list; as != NULL; as = as->next) {
if (as == sender)
continue;
@@ -747,10 +729,8 @@ static int queue_event(apm_event_t event, struct apm_bios_struct *sender)
if (as->event_head == as->event_tail) {
static int notified;
- if (notified == 0) {
+ if (notified++ == 0)
printk(KERN_ERR "apm: an event queue overflowed\n");
- notified = 1;
- }
as->event_tail = (as->event_tail + 1) % APM_MAX_EVENTS;
}
as->events[as->event_head] = event;
@@ -771,28 +751,25 @@ static int queue_event(apm_event_t event, struct apm_bios_struct *sender)
}
}
wake_up_interruptible(&apm_waitqueue);
- return 1;
}
static void set_time(void)
{
unsigned long flags;
- if (!got_clock_diff) /* Don't know time zone, can't set clock */
- return;
-
- save_flags(flags);
- cli();
- CURRENT_TIME = get_cmos_time() + clock_cmos_diff;
- restore_flags(flags);
+ if (got_clock_diff) { /* Must know time zone in order to set clock */
+ save_flags(flags);
+ cli();
+ CURRENT_TIME = get_cmos_time() + clock_cmos_diff;
+ restore_flags(flags);
+ }
}
-static void suspend(void)
+static void get_time_diff(void)
{
+#ifndef CONFIG_APM_RTC_IS_GMT
unsigned long flags;
- int err;
-#ifndef CONFIG_APM_RTC_IS_GMT
/*
* Estimate time zone so that set_time can update the clock
*/
@@ -803,9 +780,18 @@ static void suspend(void)
got_clock_diff = 1;
restore_flags(flags);
#endif
+}
+static void suspend(void)
+{
+ int err;
+#ifdef INIT_TIMER_AFTER_SUSPEND
+ unsigned long flags;
+#endif
+
+ get_time_diff();
err = apm_set_power_state(APM_STATE_SUSPEND);
- if (err)
+ if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
apm_error("suspend", err);
#ifdef INIT_TIMER_AFTER_SUSPEND
save_flags(flags);
@@ -826,8 +812,9 @@ static void standby(void)
{
int err;
+ get_time_diff();
err = apm_set_power_state(APM_STATE_STANDBY);
- if (err)
+ if ((err != APM_SUCCESS) && (err != APM_NO_ERROR))
apm_error("standby", err);
}
@@ -850,7 +837,7 @@ static apm_event_t get_event(void)
return 0;
}
-static void send_event(apm_event_t event, apm_event_t undo,
+static int send_event(apm_event_t event, apm_event_t undo,
struct apm_bios_struct *sender)
{
callback_list_t * call;
@@ -862,11 +849,12 @@ static void send_event(apm_event_t event, apm_event_t undo,
fix->callback(undo);
if (apm_bios_info.version > 0x100)
apm_set_power_state(APM_STATE_REJECT);
- return;
+ return 0;
}
}
queue_event(event, sender);
+ return 1;
}
static void check_events(void)
@@ -878,14 +866,14 @@ static void check_events(void)
#endif
while ((event = get_event()) != 0) {
-#ifdef APM_DEBUG
- if (event <= NR_APM_EVENT_NAME)
- printk(KERN_DEBUG "apm: received %s notify\n",
- apm_event_name[event - 1]);
- else
- printk(KERN_DEBUG "apm: received unknown "
- "event 0x%02x\n", event);
-#endif
+ if (debug) {
+ if (event <= NR_APM_EVENT_NAME)
+ printk(KERN_DEBUG "apm: received %s notify\n",
+ apm_event_name[event - 1]);
+ else
+ printk(KERN_DEBUG "apm: received unknown "
+ "event 0x%02x\n", event);
+ }
#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
if (ignore_bounce
&& ((jiffies - last_resume) > BOUNCE_INTERVAL))
@@ -899,8 +887,8 @@ static void check_events(void)
return;
waiting_for_resume = 1;
#endif
- send_event(event, APM_STANDBY_RESUME, NULL);
- if (standbys_pending <= 0)
+ if (send_event(event, APM_STANDBY_RESUME, NULL)
+ && (standbys_pending <= 0))
standby();
break;
@@ -920,8 +908,8 @@ static void check_events(void)
return;
waiting_for_resume = 1;
#endif
- send_event(event, APM_NORMAL_RESUME, NULL);
- if (suspends_pending <= 0)
+ if (send_event(event, APM_NORMAL_RESUME, NULL)
+ && (suspends_pending <= 0))
suspend();
break;
@@ -939,9 +927,9 @@ static void check_events(void)
send_event(event, 0, NULL);
break;
+ case APM_CAPABILITY_CHANGE:
case APM_LOW_BATTERY:
case APM_POWER_STATUS_CHANGE:
- case APM_CAPABILITY_CHANGE:
send_event(event, 0, NULL);
break;
@@ -958,56 +946,22 @@ static void check_events(void)
static void apm_event_handler(void)
{
- static int pending_count = 0;
+ static int pending_count = 0;
if (((standbys_pending > 0) || (suspends_pending > 0))
- && (apm_bios_info.version > 0x100)
- && (pending_count-- <= 0)) {
- int err;
- pending_count = 4;
-
- err = apm_set_power_state(APM_STATE_BUSY);
- if (err)
- apm_error("busy", err);
- }
-
- if (!(((standbys_pending > 0) || (suspends_pending > 0))
- && (apm_bios_info.version == 0x100)))
+ && (apm_bios_info.version > 0x100)) {
+ if (pending_count-- <= 0) {
+ int err;
+
+ pending_count = 4;
+ err = apm_set_power_state(APM_STATE_BUSY);
+ if (err)
+ apm_error("busy", err);
+ }
+ } else {
+ pending_count = 0;
check_events();
-}
-
-static int apm_do_idle(void)
-{
-#ifdef CONFIG_APM_CPU_IDLE
- u32 dummy;
-
- if (!apm_enabled)
- return 0;
-
- if (apm_bios_call_simple(0x5305, 0, 0, &dummy))
- return 0;
-
-#ifdef ALWAYS_CALL_BUSY
- clock_slowed = 1;
-#else
- clock_slowed = (apm_bios_info.flags & APM_IDLE_SLOWS_CLOCK) != 0;
-#endif
- return 1;
-#else
- return 0;
-#endif
-}
-
-static void apm_do_busy(void)
-{
-#ifdef CONFIG_APM_CPU_IDLE
- u32 dummy;
-
- if (clock_slowed) {
- (void) apm_bios_call_simple(0x5306, 0, 0, &dummy);
- clock_slowed = 0;
}
-#endif
}
/*
@@ -1040,6 +994,7 @@ static void apm_mainloop(void)
*/
current->state = TASK_INTERRUPTIBLE;
apm_event_handler();
+#ifdef CONFIG_APM_CPU_IDLE
if (!system_idle())
continue;
if (apm_do_idle()) {
@@ -1052,6 +1007,7 @@ static void apm_mainloop(void)
apm_do_busy();
apm_event_handler();
}
+#endif
}
}
@@ -1069,7 +1025,7 @@ static ssize_t do_read(struct file *fp, char *buf, size_t count, loff_t *ppos)
struct apm_bios_struct * as;
int i;
apm_event_t event;
- DECLARE_WAITQUEUE(wait, current);
+ DECLARE_WAITQUEUE(wait, current);
as = fp->private_data;
if (check_apm_bios_struct(as, "read"))
@@ -1092,7 +1048,11 @@ repeat:
i = count;
while ((i >= sizeof(event)) && !queue_empty(as)) {
event = get_queued_event(as);
- copy_to_user(buf, &event, sizeof(event));
+ if (copy_to_user(buf, &event, sizeof(event))) {
+ if (i < count)
+ break;
+ return -EFAULT;
+ }
switch (event) {
case APM_SYS_SUSPEND:
case APM_USER_SUSPEND:
@@ -1131,6 +1091,7 @@ static int do_ioctl(struct inode * inode, struct file *filp,
u_int cmd, u_long arg)
{
struct apm_bios_struct * as;
+ int send_ok = 1;
as = filp->private_data;
if (check_apm_bios_struct(as, "ioctl"))
@@ -1145,8 +1106,9 @@ static int do_ioctl(struct inode * inode, struct file *filp,
standbys_pending--;
}
else
- send_event(APM_USER_STANDBY, APM_STANDBY_RESUME, as);
- if (standbys_pending <= 0)
+ send_ok = send_event(APM_USER_STANDBY,
+ APM_STANDBY_RESUME, as);
+ if (send_ok && (standbys_pending <= 0))
standby();
break;
case APM_IOC_SUSPEND:
@@ -1156,8 +1118,9 @@ static int do_ioctl(struct inode * inode, struct file *filp,
suspends_pending--;
}
else
- send_event(APM_USER_SUSPEND, APM_NORMAL_RESUME, as);
- if (suspends_pending <= 0)
+ send_ok = send_event(APM_USER_SUSPEND,
+ APM_NORMAL_RESUME, as);
+ if (send_ok && (suspends_pending <= 0))
suspend();
break;
default:
@@ -1171,9 +1134,9 @@ static int do_release(struct inode * inode, struct file * filp)
struct apm_bios_struct * as;
as = filp->private_data;
- filp->private_data = NULL;
if (check_apm_bios_struct(as, "release"))
return 0;
+ filp->private_data = NULL;
if (as->standbys_pending > 0) {
standbys_pending -= as->standbys_pending;
if (standbys_pending <= 0)
@@ -1266,7 +1229,7 @@ int apm_get_info(char *buf, char **start, off_t fpos, int length, int dummy)
from the Get Power Status (0x0a) call unless otherwise noted.
0) Linux driver version (this will change if format changes)
- 1) APM BIOS Version. Usually 1.0 or 1.1.
+ 1) APM BIOS Version. Usually 1.0, 1.1 or 1.2.
2) APM flags from APM Installation Check (0x00):
bit 0: APM_16_BIT_SUPPORT
bit 1: APM_32_BIT_SUPPORT
@@ -1276,13 +1239,14 @@ int apm_get_info(char *buf, char **start, off_t fpos, int length, int dummy)
3) AC line status
0x00: Off-line
0x01: On-line
- 0x02: On backup power (APM BIOS 1.1 only)
+ 0x02: On backup power (BIOS >= 1.1 only)
0xff: Unknown
4) Battery status
0x00: High
0x01: Low
0x02: Critical
0x03: Charging
+ 0x04: Selected battery not present (BIOS >= 1.2 only)
0xff: Unknown
5) Battery flag
bit 0: High
@@ -1340,7 +1304,7 @@ static int apm(void *unused)
if (debug) {
printk(KERN_INFO "apm: Connection version %d.%d\n",
(apm_bios_info.version >> 8) & 0xff,
- apm_bios_info.version & 0xff );
+ apm_bios_info.version & 0xff);
error = apm_get_power_status(&bx, &cx, &dx);
if (error)
@@ -1400,6 +1364,13 @@ static int apm(void *unused)
apm_bios_info.flags &= ~APM_BIOS_DISENGAGED;
}
+ /* Install our power off handler.. */
+ if (power_off_enabled)
+ acpi_power_off = apm_power_off;
+
+#ifdef CONFIG_MAGIC_SYSRQ
+ sysrq_power_off = apm_power_off;
+#endif
apm_mainloop();
return 0;
}
@@ -1418,6 +1389,8 @@ static int __init apm_setup(char *str)
str += 3;
if (strncmp(str, "debug", 5) == 0)
debug = !invert;
+ if (strncmp(str, "power-off", 9) == 0)
+ power_off_enabled = !invert;
if (strncmp(str, "smp-power-off", 13) == 0)
smp_hack = !invert;
str = strchr(str, ',');
@@ -1429,6 +1402,29 @@ static int __init apm_setup(char *str)
__setup("apm=", apm_setup);
+static struct file_operations apm_bios_fops = {
+ NULL, /* lseek */
+ do_read,
+ NULL, /* write */
+ NULL, /* readdir */
+ do_poll,
+ do_ioctl,
+ NULL, /* mmap */
+ do_open,
+ NULL, /* flush */
+ do_release,
+ NULL, /* fsync */
+ NULL /* fasync */
+};
+
+static struct miscdevice apm_device = {
+ APM_MINOR_DEV,
+ "apm",
+ &apm_bios_fops
+};
+
+#define APM_INIT_ERROR_RETURN return -1
+
/*
* Just start the APM thread. We do NOT want to do APM BIOS
* calls from anything but the APM thread, if for no other reason
@@ -1441,11 +1437,9 @@ __setup("apm=", apm_setup);
*/
static int __init apm_init(void)
{
- static struct proc_dir_entry *ent;
-
if (apm_bios_info.version == 0) {
printk(KERN_INFO "apm: BIOS not found.\n");
- return -1;
+ APM_INIT_ERROR_RETURN;
}
printk(KERN_INFO
"apm: BIOS version %d.%d Flags 0x%02x (Driver version %s)\n",
@@ -1455,7 +1449,7 @@ static int __init apm_init(void)
driver_version);
if ((apm_bios_info.flags & APM_32_BIT_SUPPORT) == 0) {
printk(KERN_INFO "apm: no 32 bit BIOS support\n");
- return -1;
+ APM_INIT_ERROR_RETURN;
}
/*
@@ -1484,17 +1478,8 @@ static int __init apm_init(void)
if (apm_disabled) {
printk(KERN_NOTICE "apm: disabled on user request.\n");
- return -1;
- }
-
-#ifdef CONFIG_SMP
- if (smp_num_cpus > 1) {
- printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n");
- if (smp_hack)
- smp_hack = 2;
- return -1;
+ APM_INIT_ERROR_RETURN;
}
-#endif
/*
* Set up a segment that references the real mode segment 0x40
@@ -1536,9 +1521,16 @@ static int __init apm_init(void)
}
#endif
- ent = create_proc_entry("apm", 0, 0);
- if (ent != NULL)
- ent->get_info = apm_get_info;
+#ifdef CONFIG_SMP
+ if (smp_num_cpus > 1) {
+ printk(KERN_NOTICE "apm: disabled - APM is not SMP safe.\n");
+ if (smp_hack)
+ smp_hack = 2;
+ APM_INIT_ERROR_RETURN;
+ }
+#endif
+
+ create_proc_info_entry("apm", 0, 0, apm_get_info);
misc_register(&apm_device);
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index c0cb65324..59e420749 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -476,7 +476,7 @@ ENTRY(sys_call_table)
.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)
@@ -591,6 +591,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
.long SYMBOL_NAME(sys_vfork) /* 190 */
+ .long SYMBOL_NAME(sys_getrlimit)
/*
* NOTE!! This doesn't have to be exact - we just have
@@ -598,6 +599,6 @@ ENTRY(sys_call_table)
* entries. Don't panic if you notice that this hasn't
* been shrunk every time we add a new system call.
*/
- .rept NR_syscalls-190
+ .rept NR_syscalls-191
.long SYMBOL_NAME(sys_ni_syscall)
.endr
diff --git a/arch/i386/kernel/head.S b/arch/i386/kernel/head.S
index 423308aae..b3f1335d0 100644
--- a/arch/i386/kernel/head.S
+++ b/arch/i386/kernel/head.S
@@ -8,6 +8,7 @@
*/
.text
+#include <linux/config.h>
#include <linux/threads.h>
#include <linux/linkage.h>
#include <asm/segment.h>
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index d9aa5ce58..b21a915aa 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -45,6 +45,7 @@ EXPORT_SYMBOL(disable_irq);
EXPORT_SYMBOL(disable_irq_nosync);
EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(acpi_idle);
+EXPORT_SYMBOL(acpi_power_off);
EXPORT_SYMBOL_NOVERS(__down_failed);
EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
@@ -128,3 +129,4 @@ EXPORT_SYMBOL(mca_is_adapter_used);
EXPORT_SYMBOL(screen_info);
#endif
+EXPORT_SYMBOL(get_wchan);
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index 75659aac4..1bccad67b 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -650,6 +650,19 @@ int request_irq(unsigned int irq,
int retval;
struct irqaction * action;
+#if 1
+ /*
+ * Sanity-check: shared interrupts should REALLY pass in
+ * a real dev-ID, otherwise we'll have trouble later trying
+ * to figure out which interrupt is which (messes up the
+ * interrupt freeing logic etc).
+ */
+ if (irqflags & SA_SHIRQ) {
+ if (!dev_id)
+ printk("Bad boy: %s (at 0x%x) called us without a dev_id!\n", devname, (&irq)[-1]);
+ }
+#endif
+
if (irq >= NR_IRQS)
return -EINVAL;
if (!handler)
diff --git a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c
index 792cc8c0d..86fc022e6 100644
--- a/arch/i386/kernel/mca.c
+++ b/arch/i386/kernel/mca.c
@@ -29,6 +29,9 @@
* David Weinehall March 24th, 1999
* - Fixed the output of 'Driver Installed' in /proc/mca/pos
* - Made the Integrated Video & SCSI show up even if they have id 0000
+ *
+ * AV November 9th, 1999
+ * - switched to regular procfs methods.
*/
#include <linux/types.h>
@@ -105,52 +108,7 @@ static struct MCA_info* mca_info = NULL;
/*--------------------------------------------------------------------*/
#ifdef CONFIG_PROC_FS
-
static void mca_do_proc_init(void);
-static int mca_default_procfn(char* buf, int slot);
-
-static ssize_t proc_mca_read(struct file*, char*, size_t, loff_t *);
-
-static struct file_operations proc_mca_operations = {
- NULL, /* llseek */
- proc_mca_read, /* read */
- NULL, /* write */
- NULL, /* readdir */
- NULL, /* poll */
- NULL, /* ioctl */
- NULL, /* mmap */
- NULL, /* open */
- NULL, /* flush */
- NULL, /* release */
- NULL, /* fsync */
- NULL, /* fascync */
- NULL, /* check_media_change */
- NULL, /* revalidate */
- NULL /* lock */
-};
-
-static struct inode_operations proc_mca_inode_operations = {
- &proc_mca_operations, /* default file-ops */
- NULL, /* create */
- NULL, /* lookup */
- NULL, /* link */
- NULL, /* unlink */
- NULL, /* symlink */
- NULL, /* mkdir */
- NULL, /* rmdir */
- NULL, /* mknod */
- NULL, /* rename */
- NULL, /* readlink */
- NULL, /* follow_link */
- NULL, /* get_block */
- NULL, /* readpage */
- NULL, /* writepage */
- NULL, /* flushpage */
- NULL, /* truncate */
- NULL, /* permission */
- NULL, /* smap */
- NULL /* revalidate */
-};
#endif
/*--------------------------------------------------------------------*/
@@ -657,7 +615,8 @@ int mca_isenabled(int slot)
#ifdef CONFIG_PROC_FS
-int get_mca_info(char *buf)
+int get_mca_info(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
{
int i, j, len = 0;
@@ -667,101 +626,45 @@ int get_mca_info(char *buf)
for(i=0; i<MCA_MAX_SLOT_NR; i++)
{
- len += sprintf(buf+len, "Slot %d: ", i+1);
+ len += sprintf(page+len, "Slot %d: ", i+1);
for(j=0; j<8; j++)
- len += sprintf(buf+len, "%02x ", mca_info->slot[i].pos[j]);
- len += sprintf(buf+len, " %s\n", mca_info->slot[i].name);
+ len += sprintf(page+len, "%02x ", mca_info->slot[i].pos[j]);
+ len += sprintf(page+len, " %s\n", mca_info->slot[i].name);
}
/* Format POS registers of integrated video subsystem */
- len += sprintf(buf+len, "Video : ");
+ len += sprintf(page+len, "Video : ");
for(j=0; j<8; j++)
- len += sprintf(buf+len, "%02x ", mca_info->slot[MCA_INTEGVIDEO].pos[j]);
- len += sprintf(buf+len, " %s\n", mca_info->slot[MCA_INTEGVIDEO].name);
+ len += sprintf(page+len, "%02x ", mca_info->slot[MCA_INTEGVIDEO].pos[j]);
+ len += sprintf(page+len, " %s\n", mca_info->slot[MCA_INTEGVIDEO].name);
/* Format POS registers of integrated SCSI subsystem */
- len += sprintf(buf+len, "SCSI : ");
+ len += sprintf(page+len, "SCSI : ");
for(j=0; j<8; j++)
- len += sprintf(buf+len, "%02x ", mca_info->slot[MCA_INTEGSCSI].pos[j]);
- len += sprintf(buf+len, " %s\n", mca_info->slot[MCA_INTEGSCSI].name);
+ len += sprintf(page+len, "%02x ", mca_info->slot[MCA_INTEGSCSI].pos[j]);
+ len += sprintf(page+len, " %s\n", mca_info->slot[MCA_INTEGSCSI].name);
} else {
/* Leave it empty if MCA not detected - this should *never*
* happen!
*/
}
+ if (len <= off+count) *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len>count) len = count;
+ if (len<0) len = 0;
return len;
}
-
-/*--------------------------------------------------------------------*/
-
-void __init mca_do_proc_init(void)
-{
- int i;
- struct proc_dir_entry* node = NULL;
-
- if(mca_info == NULL) return; /* Should never happen */
-
- proc_register(&proc_mca, &(struct proc_dir_entry) {
- PROC_MCA_REGISTERS, 3, "pos", S_IFREG|S_IRUGO,
- 1, 0, 0, 0, &proc_mca_inode_operations,});
-
- proc_register(&proc_mca, &(struct proc_dir_entry) {
- PROC_MCA_MACHINE, 7, "machine", S_IFREG|S_IRUGO,
- 1, 0, 0, 0, &proc_mca_inode_operations,});
-
- /* Initialize /proc/mca entries for existing adapters */
-
- for(i = 0; i < MCA_NUMADAPTERS; i++) {
- mca_info->slot[i].procfn = 0;
- mca_info->slot[i].dev = 0;
-
- if(!mca_isadapter(i)) continue;
-
- node = (struct proc_dir_entry *)kmalloc(sizeof(struct proc_dir_entry), GFP_KERNEL);
-
- if(node == NULL) {
- printk("Failed to allocate memory for MCA proc-entries!");
- return;
- }
- memset(node, 0, sizeof(struct proc_dir_entry));
-
- if(i < MCA_MAX_SLOT_NR) {
- node->low_ino = PROC_MCA_SLOT + i;
- node->namelen = sprintf(mca_info->slot[i].procname,
- "slot%d", i+1);
- } else if(i == MCA_INTEGVIDEO) {
- node->low_ino = PROC_MCA_VIDEO;
- node->namelen = sprintf(mca_info->slot[i].procname,
- "video");
- } else if(i == MCA_INTEGSCSI) {
- node->low_ino = PROC_MCA_SCSI;
- node->namelen = sprintf(mca_info->slot[i].procname,
- "scsi");
- }
- node->name = mca_info->slot[i].procname;
- node->mode = S_IFREG | S_IRUGO;
- node->ops = &proc_mca_inode_operations;
- proc_register(&proc_mca, node);
- }
-
-} /* mca_do_proc_init() */
-
/*--------------------------------------------------------------------*/
-int mca_default_procfn(char* buf, int slot)
+static int mca_default_procfn(char* buf, struct MCA_adapter *p)
{
int len = 0, i;
-
- /* This really shouldn't happen... */
-
- if(mca_info == NULL) {
- *buf = 0;
- return 0;
- }
+ int slot = p - mca_info->slot;
/* Print out the basic information */
@@ -772,21 +675,21 @@ int mca_default_procfn(char* buf, int slot)
} else if(slot == MCA_INTEGVIDEO) {
len += sprintf(buf+len, "Integrated Video Adapter\n");
}
- if(mca_info->slot[slot].name[0]) {
+ if(p->name[0]) {
/* Drivers might register a name without /proc handler... */
len += sprintf(buf+len, "Adapter Name: %s\n",
- mca_info->slot[slot].name);
+ p->name);
} else {
len += sprintf(buf+len, "Adapter Name: Unknown\n");
}
len += sprintf(buf+len, "Id: %02x%02x\n",
- mca_info->slot[slot].pos[1], mca_info->slot[slot].pos[0]);
+ p->pos[1], p->pos[0]);
len += sprintf(buf+len, "Enabled: %s\nPOS: ",
mca_isenabled(slot) ? "Yes" : "No");
for(i=0; i<8; i++) {
- len += sprintf(buf+len, "%02x ", mca_info->slot[slot].pos[i]);
+ len += sprintf(buf+len, "%02x ", p->pos[i]);
}
len += sprintf(buf+len, "\nDriver Installed: %s",
mca_is_adapter_used(slot) ? "Yes" : "No");
@@ -796,111 +699,80 @@ int mca_default_procfn(char* buf, int slot)
return len;
} /* mca_default_procfn() */
-static int get_mca_machine_info(char* buf)
+static int get_mca_machine_info(char* page, char **start, off_t off,
+ int count, int *eof, void *data)
{
int len = 0;
- len += sprintf(buf+len, "Model Id: 0x%x\n", machine_id);
- len += sprintf(buf+len, "Submodel Id: 0x%x\n", machine_submodel_id);
- len += sprintf(buf+len, "BIOS Revision: 0x%x\n", BIOS_revision);
+ len += sprintf(page+len, "Model Id: 0x%x\n", machine_id);
+ len += sprintf(page+len, "Submodel Id: 0x%x\n", machine_submodel_id);
+ len += sprintf(page+len, "BIOS Revision: 0x%x\n", BIOS_revision);
+ if (len <= off+count) *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len>count) len = count;
+ if (len<0) len = 0;
return len;
}
-static int mca_fill(char* page, int pid, int type, char** start,
- loff_t *offset, int length)
+static int mca_read_proc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
{
+ struct MCA_adapter *p = (struct MCA_adapter *)data;
int len = 0;
- int slot = 0;
-
- switch(type) {
- case PROC_MCA_REGISTERS:
- return get_mca_info(page);
- case PROC_MCA_MACHINE:
- return get_mca_machine_info(page);
- case PROC_MCA_VIDEO:
- slot = MCA_INTEGVIDEO;
- break;
- case PROC_MCA_SCSI:
- slot = MCA_INTEGSCSI;
- break;
- default:
- if(type < PROC_MCA_SLOT || type >= PROC_MCA_LAST) {
- return -EBADF;
- }
- slot = type - PROC_MCA_SLOT;
- break;
- }
-
- /* If we made it here, we better have a valid slot */
/* Get the standard info */
- len = mca_default_procfn(page, slot);
+ len = mca_default_procfn(page, p);
/* Do any device-specific processing, if there is any */
- if(mca_info->slot[slot].procfn) {
- len += mca_info->slot[slot].procfn(page+len, slot,
- mca_info->slot[slot].dev);
+ if(p->procfn) {
+ len += p->procfn(page+len, p-mca_info->slot, p->dev);
}
-
+ if (len <= off+count) *eof = 1;
+ *start = page + off;
+ len -= off;
+ if (len>count) len = count;
+ if (len<0) len = 0;
return len;
-} /* mca_fill() */
+} /* mca_read_proc() */
-/* Blatantly stolen from fs/proc/array.c, and thus is probably overkill */
-
-#define PROC_BLOCK_SIZE (3*1024)
+/*--------------------------------------------------------------------*/
-static ssize_t proc_mca_read(struct file* file,
- char* buf, size_t count, loff_t *ppos)
+void __init mca_do_proc_init(void)
{
- unsigned long page;
- char *start;
- int length;
- int end;
- unsigned int type, pid;
- struct proc_dir_entry *dp;
- struct inode *inode = file->f_dentry->d_inode;
-
- if(count < 0)
- return -EINVAL;
- if(count > PROC_BLOCK_SIZE)
- count = PROC_BLOCK_SIZE;
- if(!(page = __get_free_page(GFP_KERNEL)))
- return -ENOMEM;
- type = inode->i_ino;
- pid = type >> 16;
- type &= 0x0000ffff;
- start = NULL;
- dp = (struct proc_dir_entry *) inode->u.generic_ip;
- length = mca_fill((char *) page, pid, type,
- &start, ppos, count);
- if(length < 0) {
- free_page(page);
- return length;
- }
- if(start != NULL) {
- /* We have had block-adjusting processing! */
+ int i;
+ struct proc_dir_entry* node = NULL;
+ struct MCA_adapter *p;
- copy_to_user(buf, start, length);
- *ppos += length;
- count = length;
- } else {
- /* Static 4kB (or whatever) block capacity */
+ if(mca_info == NULL) return; /* Should never happen */
+
+ create_proc_read_entry("pos",0,proc_mca,get_mca_info,NULL);
+ create_proc_read_entry("machine",0,proc_mca,get_mca_machine_info,NULL);
+
+ /* Initialize /proc/mca entries for existing adapters */
+
+ for(i = 0; i < MCA_NUMADAPTERS; i++) {
+ p = &mca_info->slot[i];
+ p->procfn = 0;
+
+ if(i < MCA_MAX_SLOT_NR) sprintf(p->procname,"slot%d", i+1);
+ else if(i == MCA_INTEGVIDEO) sprintf(p->procname,"video");
+ else if(i == MCA_INTEGSCSI) sprintf(p->procname,"scsi");
- if(*ppos >= length) {
- free_page(page);
- return 0;
+ if(!mca_isadapter(i)) continue;
+
+ node = create_proc_read_entry(p->procname, 0, proc_mca,
+ mca_read_proc, (void *)p);
+
+ if(node == NULL) {
+ printk("Failed to allocate memory for MCA proc-entries!");
+ return;
}
- if(count + *ppos > length)
- count = length - *ppos;
- end = count + *ppos;
- copy_to_user(buf, (char *) page + *ppos, count);
- *ppos = end;
}
- free_page(page);
- return count;
-} /* proc_mca_read() */
+
+} /* mca_do_proc_init() */
#endif
diff --git a/arch/i386/kernel/mtrr.c b/arch/i386/kernel/mtrr.c
index f55e86b61..9e612451c 100644
--- a/arch/i386/kernel/mtrr.c
+++ b/arch/i386/kernel/mtrr.c
@@ -1204,7 +1204,7 @@ int mtrr_add (unsigned long base, unsigned long size, unsigned int type,
i = (*get_free_region) (base, size);
if (i < 0)
{
- spin_unlock (&main_lock);
+ up(&main_lock);
printk ("mtrr: no more MTRRs available\n");
return i;
}
@@ -1516,7 +1516,7 @@ static struct inode_operations proc_mtrr_inode_operations = {
};
static struct proc_dir_entry proc_root_mtrr = {
- PROC_MTRR, 4, "mtrr",
+ 0, 4, "mtrr",
S_IFREG | S_IWUSR | S_IRUGO, 1, 0, 0,
0, &proc_mtrr_inode_operations
};
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 225246d97..429c4eacd 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -29,9 +29,6 @@
#include <linux/delay.h>
#include <linux/reboot.h>
#include <linux/init.h>
-#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
-#include <linux/apm_bios.h>
-#endif
#include <asm/uaccess.h>
#include <asm/pgtable.h>
@@ -67,6 +64,11 @@ void enable_hlt(void)
void (*acpi_idle)(void) = NULL;
/*
+ * Power off function, if any
+ */
+void (*acpi_power_off)(void) = NULL;
+
+/*
* The idle thread. There's no useful work to be
* done, so just try to conserve power and have a
* low exit latency (ie sit in a loop waiting for
@@ -310,9 +312,8 @@ void machine_halt(void)
void machine_power_off(void)
{
-#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
- apm_power_off();
-#endif
+ if (acpi_power_off)
+ acpi_power_off();
}
@@ -684,3 +685,37 @@ 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 ebp, esp, eip;
+ unsigned long stack_page;
+ int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+ stack_page = (unsigned long)p;
+ esp = p->thread.esp;
+ if (!stack_page || esp < stack_page || esp > 8188+stack_page)
+ return 0;
+ /* include/asm-i386/system.h:switch_to() pushes ebp last. */
+ ebp = *(unsigned long *) esp;
+ do {
+ if (ebp < stack_page || ebp > 8184+stack_page)
+ return 0;
+ eip = *(unsigned long *) (ebp+4);
+ if (eip < first_sched || eip >= last_sched)
+ return eip;
+ ebp = *(unsigned long *) ebp;
+ } while (count++ < 16);
+ return 0;
+}
+#undef last_sched
+#undef first_sched
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index 029c79334..e10277255 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -583,6 +583,7 @@ void __init setup_arch(char **cmdline_p)
#define VMALLOC_RESERVE (unsigned long)(128 << 20)
#define MAXMEM (unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE)
#define MAXMEM_PFN PFN_DOWN(MAXMEM)
+#define MAX_NONPAE_PFN (1 << 20)
/*
* partially used pages are not usable - thus
@@ -608,8 +609,26 @@ void __init setup_arch(char **cmdline_p)
* Determine low and high memory ranges:
*/
max_low_pfn = max_pfn;
- if (max_low_pfn > MAXMEM_PFN)
+ if (max_low_pfn > MAXMEM_PFN) {
max_low_pfn = MAXMEM_PFN;
+#ifndef CONFIG_HIGHMEM
+ /* Maximum memory usable is what is directly addressable */
+ printk(KERN_WARNING "Warning only %ldMB will be used.\n",
+ MAXMEM>>20);
+ if (max_pfn > MAX_NONPAE_PFN)
+ printk(KERN_WARNING "Use a PAE enabled kernel.\n");
+ else
+ printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
+#else /* !CONFIG_HIGHMEM */
+#ifndef CONFIG_X86_PAE
+ if (max_pfn > MAX_NONPAE_PFN) {
+ max_pfn = MAX_NONPAE_PFN;
+ printk(KERN_WARNING "Warning only 4GB will be used.\n");
+ printk(KERN_WARNING "Use a PAE enabled kernel.\n");
+ }
+#endif /* !CONFIG_X86_PAE */
+#endif /* !CONFIG_HIGHMEM */
+ }
#ifdef CONFIG_HIGHMEM
highstart_pfn = highend_pfn = max_pfn;
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 4386e8dd0..85f439978 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -821,8 +821,9 @@ void __init init_smp_mappings(void)
* could use the real zero-page, but it's safer
* this way if some buggy code writes to this page ...
*/
- apic_phys = __pa(alloc_bootmem_pages(PAGE_SIZE));
+ apic_phys = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
memset((void *)apic_phys, 0, PAGE_SIZE);
+ apic_phys = __pa(apic_phys);
}
set_fixmap(FIX_APIC_BASE, apic_phys);
dprintk("mapped APIC to %08lx (%08lx)\n", APIC_BASE, apic_phys);
@@ -836,8 +837,9 @@ void __init init_smp_mappings(void)
if (smp_found_config) {
ioapic_phys = mp_ioapics[i].mpc_apicaddr;
} else {
- ioapic_phys = __pa(alloc_bootmem_pages(PAGE_SIZE));
+ ioapic_phys = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
memset((void *)ioapic_phys, 0, PAGE_SIZE);
+ ioapic_phys = __pa(ioapic_phys);
}
set_fixmap(idx,ioapic_phys);
dprintk("mapped IOAPIC to %08lx (%08lx)\n",
diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c
index f7987718b..289220d91 100644
--- a/arch/i386/kernel/sys_i386.c
+++ b/arch/i386/kernel/sys_i386.c
@@ -116,86 +116,71 @@ asmlinkage int sys_ipc (uint call, int first, int second,
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
- if (call <= SEMCTL)
- switch (call) {
- case SEMOP:
- return sys_semop (first, (struct sembuf *)ptr, second);
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
+ switch (call) {
+ case SEMOP:
+ return sys_semop (first, (struct sembuf *)ptr, second);
+ case SEMGET:
+ return sys_semget (first, second, third);
+ case SEMCTL: {
+ union semun fourth;
+ if (!ptr)
+ return -EINVAL;
+ if (get_user(fourth.__pad, (void **) ptr))
+ return -EFAULT;
+ return sys_semctl (first, second, third, fourth);
+ }
+
+ case MSGSND:
+ return sys_msgsnd (first, (struct msgbuf *) ptr,
+ second, third);
+ case MSGRCV:
+ switch (version) {
+ case 0: {
+ struct ipc_kludge tmp;
if (!ptr)
return -EINVAL;
- if (get_user(fourth.__pad, (void **) ptr))
+
+ if (copy_from_user(&tmp,
+ (struct ipc_kludge *) ptr,
+ sizeof (tmp)))
return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
- default:
- return -EINVAL;
+ return sys_msgrcv (first, tmp.msgp, second,
+ tmp.msgtyp, third);
}
-
- if (call <= MSGCTL)
- switch (call) {
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge *) ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first,
- (struct msgbuf *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second,
- (struct msqid_ds *) ptr);
default:
- return -EINVAL;
+ return sys_msgrcv (first,
+ (struct msgbuf *) ptr,
+ second, fifth, third);
}
- if (call <= SHMCTL)
- switch (call) {
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = sys_shmat (first, (char *) ptr,
- second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong *) third);
- }
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- return sys_shmat (first, (char *) ptr,
- second, (ulong *) third);
- }
- case SHMDT:
- return sys_shmdt ((char *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds *) ptr);
- default:
- return -EINVAL;
+ case MSGGET:
+ return sys_msgget ((key_t) first, second);
+ case MSGCTL:
+ return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+
+ case SHMAT:
+ switch (version) {
+ default: {
+ ulong raddr;
+ ret = sys_shmat (first, (char *) ptr, second, &raddr);
+ if (ret)
+ return ret;
+ return put_user (raddr, (ulong *) third);
}
-
- return -EINVAL;
+ case 1: /* iBCS2 emulator entry point */
+ if (!segment_eq(get_fs(), get_ds()))
+ return -EINVAL;
+ return sys_shmat (first, (char *) ptr, second, (ulong *) third);
+ }
+ case SHMDT:
+ return sys_shmdt ((char *)ptr);
+ case SHMGET:
+ return sys_shmget (first, second, third);
+ case SHMCTL:
+ return sys_shmctl (first, second,
+ (struct shmid_ds *) ptr);
+ default:
+ return -EINVAL;
+ }
}
/*
diff --git a/arch/i386/lib/mmx.c b/arch/i386/lib/mmx.c
index 5257aeba6..0314041f9 100644
--- a/arch/i386/lib/mmx.c
+++ b/arch/i386/lib/mmx.c
@@ -89,7 +89,7 @@ void *_mmx_memcpy(void *to, const void *from, size_t len)
return p;
}
-static void fast_clear_page(long page)
+static void fast_clear_page(void *page)
{
int i;
if (!(current->flags & PF_USEDFPU))
@@ -129,7 +129,7 @@ static void fast_clear_page(long page)
stts();
}
-static void fast_copy_page(long to, long from)
+static void fast_copy_page(void *to, void *from)
{
int i;
if (!(current->flags & PF_USEDFPU))
@@ -196,7 +196,7 @@ static void fast_copy_page(long to, long from)
* Favour MMX for page clear and copy.
*/
-static void slow_zero_page(long page)
+static void slow_zero_page(void * page)
{
int d0, d1;
__asm__ __volatile__( \
@@ -207,7 +207,7 @@ static void slow_zero_page(long page)
:"memory");
}
-void mmx_clear_page(long page)
+void mmx_clear_page(void * page)
{
if(in_interrupt())
slow_zero_page(page);
@@ -215,7 +215,7 @@ void mmx_clear_page(long page)
fast_clear_page(page);
}
-static void slow_copy_page(long to, long from)
+static void slow_copy_page(void *to, void *from)
{
int d0, d1, d2;
__asm__ __volatile__( \
@@ -227,7 +227,7 @@ static void slow_copy_page(long to, long from)
}
-void mmx_copy_page(long to, long from)
+void mmx_copy_page(void *to, void *from)
{
if(in_interrupt())
slow_copy_page(to, from);
diff --git a/arch/i386/math-emu/README b/arch/i386/math-emu/README
index 04434b618..e6235491d 100644
--- a/arch/i386/math-emu/README
+++ b/arch/i386/math-emu/README
@@ -1,9 +1,9 @@
+---------------------------------------------------------------------------+
| wm-FPU-emu an FPU emulator for 80386 and 80486SX microprocessors. |
| |
- | Copyright (C) 1992,1993,1994,1995,1996,1997 |
+ | Copyright (C) 1992,1993,1994,1995,1996,1997,1999 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@suburbia.net |
+ | Australia. E-mail billm@melbpc.org.au |
| |
| This program is free software; you can redistribute it and/or modify |
| it under the terms of the GNU General Public License version 2 as |
@@ -42,14 +42,15 @@ but is very close. See "Limitations" later in this file for a list of
some differences.
Please report bugs, etc to me at:
- billm@suburbia.net
+ billm@melbpc.org.au
+or b.metzenthen@medoto.unimelb.edu.au
For more information on the emulator and on floating point topics, see
my web pages, currently at http://www.suburbia.net/~billm/
--Bill Metzenthen
- December 1997
+ December 1999
----------------------- Internals of wm-FPU-emu -----------------------
@@ -98,7 +99,7 @@ form of re-entrancy which is required by the Linux kernel.
----------------------- Limitations of wm-FPU-emu -----------------------
There are a number of differences between the current wm-FPU-emu
-(version 2.00) and the 80486 FPU (apart from bugs). The differences
+(version 2.01) and the 80486 FPU (apart from bugs). The differences
are fewer than those which applied to the 1.xx series of the emulator.
Some of the more important differences are listed below:
diff --git a/arch/i386/math-emu/fpu_trig.c b/arch/i386/math-emu/fpu_trig.c
index 57a902162..30b72910e 100644
--- a/arch/i386/math-emu/fpu_trig.c
+++ b/arch/i386/math-emu/fpu_trig.c
@@ -3,9 +3,9 @@
| |
| Implementation of the FPU "transcendental" functions. |
| |
- | Copyright (C) 1992,1993,1994,1997 |
+ | Copyright (C) 1992,1993,1994,1997,1999 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@suburbia.net |
+ | Australia. E-mail billm@melbpc.org.au |
| |
| |
+---------------------------------------------------------------------------*/
@@ -85,7 +85,8 @@ static int trig_arg(FPU_REG *st0_ptr, int even)
FPU_normalize(&tmp);
tmptag =
FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION, SIGN_POS,
- exponent16(&CONST_PI2extra) + exponent16(&tmp));
+ exponent(&CONST_PI2extra) + exponent(&tmp));
+ setsign(&tmp, getsign(&CONST_PI2extra));
st0_tag = FPU_add(&tmp, tmptag, 0, FULL_PRECISION);
if ( signnegative(st0_ptr) )
{
@@ -117,7 +118,8 @@ static int trig_arg(FPU_REG *st0_ptr, int even)
FPU_normalize(&tmp); /* This must return TAG_Valid */
tmptag = FPU_u_mul(&CONST_PI2extra, &tmp, &tmp, FULL_PRECISION,
SIGN_POS,
- exponent16(&CONST_PI2extra) + exponent16(&tmp));
+ exponent(&CONST_PI2extra) + exponent(&tmp));
+ setsign(&tmp, getsign(&CONST_PI2extra));
st0_tag = FPU_sub(LOADED|(tmptag & 0x0f), (int)&tmp,
FULL_PRECISION);
if ( (exponent(st0_ptr) == exponent(&CONST_PI2)) &&
@@ -827,18 +829,29 @@ static void rem_kernel(unsigned long long st0, unsigned long long *y,
unsigned long long st1,
unsigned long long q, int n)
{
+ int dummy;
unsigned long long x;
x = st0 << n;
/* Do the required multiplication and subtraction in the one operation */
- asm volatile ("movl %2,%%eax; mull %4; subl %%eax,%0; sbbl %%edx,%1;
- movl %3,%%eax; mull %4; subl %%eax,%1;
- movl %2,%%eax; mull %5; subl %%eax,%1;"
- :"=m" (x), "=m" (((unsigned *)&x)[1])
- :"m" (st1),"m" (((unsigned *)&st1)[1]),
- "m" (q),"m" (((unsigned *)&q)[1])
- :"%ax","%dx");
+
+ /* lsw x -= lsw st1 * lsw q */
+ asm volatile ("mull %4; subl %%eax,%0; sbbl %%edx,%1"
+ :"=m" (((unsigned *)&x)[0]), "=m" (((unsigned *)&x)[1]),
+ "=a" (dummy)
+ :"2" (((unsigned *)&st1)[0]), "m" (((unsigned *)&q)[0])
+ :"%dx");
+ /* msw x -= msw st1 * lsw q */
+ asm volatile ("mull %3; subl %%eax,%0"
+ :"=m" (((unsigned *)&x)[1]), "=a" (dummy)
+ :"1" (((unsigned *)&st1)[1]), "m" (((unsigned *)&q)[0])
+ :"%dx");
+ /* msw x -= lsw st1 * msw q */
+ asm volatile ("mull %3; subl %%eax,%0"
+ :"=m" (((unsigned *)&x)[1]), "=a" (dummy)
+ :"1" (((unsigned *)&st1)[0]), "m" (((unsigned *)&q)[1])
+ :"%dx");
*y = x;
}
diff --git a/arch/i386/math-emu/poly.h b/arch/i386/math-emu/poly.h
index 37ddfa0ef..5cfce7baf 100644
--- a/arch/i386/math-emu/poly.h
+++ b/arch/i386/math-emu/poly.h
@@ -3,9 +3,9 @@
| |
| Header file for the FPU-emu poly*.c source files. |
| |
- | Copyright (C) 1994 |
+ | Copyright (C) 1994,1999 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@vaxc.cc.monash.edu.au |
+ | Australia. E-mail billm@melbpc.org.au |
| |
| Declarations and definitions for functions operating on Xsig (12-byte |
| extended-significand) quantities. |
@@ -55,15 +55,20 @@ asmlinkage void div_Xsig(Xsig *x1, const Xsig *x2, const Xsig *dest);
actually be in-line.
*/
-/* Multiply two fixed-point 32 bit numbers. */
-extern inline void mul_32_32(const unsigned long arg1,
- const unsigned long arg2,
- unsigned long *out)
+/* Multiply two fixed-point 32 bit numbers, producing a 32 bit result.
+ The answer is the ms word of the product. */
+/* Some versions of gcc make it difficult to stop eax from being clobbered.
+ Merely specifying that it is used doesn't work...
+ */
+extern inline unsigned long mul_32_32(const unsigned long arg1,
+ const unsigned long arg2)
{
- asm volatile ("movl %1,%%eax; mull %2; movl %%edx,%0" \
- :"=g" (*out) \
- :"g" (arg1), "g" (arg2) \
- :"ax","dx");
+ int retval;
+ asm volatile ("mull %2; movl %%edx,%%eax" \
+ :"=a" (retval) \
+ :"0" (arg1), "g" (arg2) \
+ :"dx");
+ return retval;
}
diff --git a/arch/i386/math-emu/poly_sin.c b/arch/i386/math-emu/poly_sin.c
index f03df4c00..a83b51206 100644
--- a/arch/i386/math-emu/poly_sin.c
+++ b/arch/i386/math-emu/poly_sin.c
@@ -4,9 +4,9 @@
| Computation of an approximation of the sin function and the cosine |
| function by a polynomial. |
| |
- | Copyright (C) 1992,1993,1994,1997 |
+ | Copyright (C) 1992,1993,1994,1997,1999 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
- | E-mail billm@suburbia.net |
+ | E-mail billm@melbpc.org.au |
| |
| |
+---------------------------------------------------------------------------*/
@@ -132,6 +132,9 @@ void poly_sine(FPU_REG *st0_ptr)
}
/* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
fixed_arg = 0x921fb54442d18469LL - fixed_arg;
+ /* There is a special case which arises due to rounding, to fix here. */
+ if ( fixed_arg == 0xffffffffffffffffLL )
+ fixed_arg = 0;
XSIG_LL(argSqrd) = fixed_arg; argSqrd.lsw = 0;
mul64_Xsig(&argSqrd, &fixed_arg);
@@ -172,10 +175,9 @@ void poly_sine(FPU_REG *st0_ptr)
if ( argSqrd.msw & 0xffc00000 )
{
/* Get about 32 bit precision in these: */
- mul_32_32(0x898cc517, argSqrd.msw, &adj);
- fix_up -= adj/6;
+ fix_up -= mul_32_32(0x898cc517, argSqrd.msw) / 6;
}
- mul_32_32(fix_up, LL_MSW(fixed_arg), &fix_up);
+ fix_up = mul_32_32(fix_up, LL_MSW(fixed_arg));
adj = accumulator.lsw; /* temp save */
accumulator.lsw -= fix_up;
@@ -211,7 +213,6 @@ void poly_cos(FPU_REG *st0_ptr)
FPU_REG result;
long int exponent, exp2, echange;
Xsig accumulator, argSqrd, fix_up, argTo4;
- unsigned long adj;
unsigned long long fixed_arg;
#ifdef PARANOID
@@ -300,6 +301,9 @@ void poly_cos(FPU_REG *st0_ptr)
}
/* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
fixed_arg = 0x921fb54442d18469LL - fixed_arg;
+ /* There is a special case which arises due to rounding, to fix here. */
+ if ( fixed_arg == 0xffffffffffffffffLL )
+ fixed_arg = 0;
exponent = -1;
exp2 = -1;
@@ -363,10 +367,8 @@ void poly_cos(FPU_REG *st0_ptr)
if ( argSqrd.msw & 0xffc00000 )
{
/* Get about 32 bit precision in these: */
- mul_32_32(0x898cc517, argSqrd.msw, &adj);
- fix_up.msw -= adj/2;
- mul_32_32(0x898cc517, argTo4.msw, &adj);
- fix_up.msw += adj/24;
+ fix_up.msw -= mul_32_32(0x898cc517, argSqrd.msw) / 2;
+ fix_up.msw += mul_32_32(0x898cc517, argTo4.msw) / 24;
}
exp2 += norm_Xsig(&accumulator);
diff --git a/arch/i386/math-emu/poly_tan.c b/arch/i386/math-emu/poly_tan.c
index 1743d6f0f..13a32b9fc 100644
--- a/arch/i386/math-emu/poly_tan.c
+++ b/arch/i386/math-emu/poly_tan.c
@@ -3,9 +3,9 @@
| |
| Compute the tan of a FPU_REG, using a polynomial approximation. |
| |
- | Copyright (C) 1992,1993,1994,1997 |
+ | Copyright (C) 1992,1993,1994,1997,1999 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, |
- | Australia. E-mail billm@suburbia.net |
+ | Australia. E-mail billm@melbpc.org.au |
| |
| |
+---------------------------------------------------------------------------*/
@@ -84,6 +84,14 @@ void poly_tan(FPU_REG *st0_ptr)
}
/* pi/2 in hex is: 1.921fb54442d18469 898CC51701B839A2 52049C1 */
XSIG_LL(accum) = 0x921fb54442d18469LL - XSIG_LL(accum);
+ /* This is a special case which arises due to rounding. */
+ if ( XSIG_LL(accum) == 0xffffffffffffffffLL )
+ {
+ FPU_settag0(TAG_Valid);
+ significand(st0_ptr) = 0x8a51e04daabda360LL;
+ setexponent16(st0_ptr, 0x41 + EXTENDED_Ebias | SIGN_Negative);
+ return;
+ }
argSignif.lsw = accum.lsw;
XSIG_LL(argSignif) = XSIG_LL(accum);
@@ -177,11 +185,11 @@ void poly_tan(FPU_REG *st0_ptr)
else if ( exponent > -30 )
{
adj = accum.msw >> -(exponent+1); /* tan */
- mul_32_32(adj, adj, &adj); /* tan^2 */
+ adj = mul_32_32(adj, adj); /* tan^2 */
}
else
adj = 0;
- mul_32_32(0x898cc517, adj, &adj); /* delta * tan^2 */
+ adj = mul_32_32(0x898cc517, adj); /* delta * tan^2 */
fix_up.msw += adj;
if ( !(fix_up.msw & 0x80000000) ) /* did fix_up overflow ? */
diff --git a/arch/i386/math-emu/reg_round.S b/arch/i386/math-emu/reg_round.S
index f6c11eb7d..ba00f5c5a 100644
--- a/arch/i386/math-emu/reg_round.S
+++ b/arch/i386/math-emu/reg_round.S
@@ -365,7 +365,7 @@ LRound_nearest_64:
jne LDo_64_round_up
/* Now test for round-to-even */
- testb $1,%ebx
+ testb $1,%bl
jz LCheck_truncate_64
LDo_64_round_up:
diff --git a/arch/i386/math-emu/version.h b/arch/i386/math-emu/version.h
index 2f819087d..a0d73a1d2 100644
--- a/arch/i386/math-emu/version.h
+++ b/arch/i386/math-emu/version.h
@@ -2,11 +2,11 @@
| version.h |
| |
| |
- | Copyright (C) 1992,1993,1994,1996,1997 |
+ | Copyright (C) 1992,1993,1994,1996,1997,1999 |
| W. Metzenthen, 22 Parker St, Ormond, Vic 3163, Australia |
- | E-mail billm@suburbia.net |
+ | E-mail billm@melbpc.org.au |
| |
| |
+---------------------------------------------------------------------------*/
-#define FPU_VERSION "wm-FPU-emu version 2.00"
+#define FPU_VERSION "wm-FPU-emu version 2.01"
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index d2089fbd0..7a05654d8 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -171,9 +171,11 @@ int do_check_pgt_cache(int low, int high)
return freed;
}
-/* NOTE: fixmap_init alloc all the fixmap pagetables contigous on the
- physical space so we can cache the place of the first one and move
- around without checking the pgd every time. */
+/*
+ * NOTE: pagetable_init alloc all the fixmap pagetables contiguous on the
+ * physical space so we can cache the place of the first one and move
+ * around without checking the pgd every time.
+ */
#if CONFIG_HIGHMEM
pte_t *kmap_pte;
@@ -268,6 +270,44 @@ void set_fixmap (enum fixed_addresses idx, unsigned long phys)
set_pte_phys (address,phys);
}
+static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
+{
+ pgd_t *pgd;
+ pmd_t *pmd;
+ pte_t *pte;
+ int i, j;
+
+ i = __pgd_offset(start);
+ j = __pmd_offset(start);
+ pgd = pgd_base + i;
+
+ for ( ; (i < PTRS_PER_PGD) && (start != end); pgd++, i++) {
+#if CONFIG_X86_PAE
+ if (pgd_none(*pgd)) {
+ pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+ memset((void*)pmd, 0, PAGE_SIZE);
+ pgd_val(*pgd) = __pa(pmd) + 0x1;
+ if (pmd != pmd_offset(pgd, start))
+ BUG();
+ }
+ pmd = pmd_offset(pgd, start);
+#else
+ pmd = (pmd_t *)pgd;
+#endif
+ for (; (j < PTRS_PER_PMD) && start; pmd++, j++) {
+ if (pmd_none(*pmd)) {
+ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
+ memset((void*)pte, 0, PAGE_SIZE);
+ pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte);
+ if (pte != pte_offset(pmd, 0))
+ BUG();
+ }
+ start += PMD_SIZE;
+ }
+ j = 0;
+ }
+}
+
static void __init pagetable_init(void)
{
pgd_t *pgd, *pgd_base;
@@ -331,37 +371,21 @@ static void __init pagetable_init(void)
* Fixed mappings, only the page table structure has to be
* created - mappings will be set by set_fixmap():
*/
-
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
- i = __pgd_offset(vaddr);
- j = __pmd_offset(vaddr);
- pgd = pgd_base + i;
+ fixrange_init(vaddr, 0, pgd_base);
- for ( ; (i < PTRS_PER_PGD) && vaddr; pgd++, i++) {
-#if CONFIG_X86_PAE
- if (pgd_none(*pgd)) {
- pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- memset((void*)pmd, 0, PAGE_SIZE);
- pgd_val(*pgd) = __pa(pmd) + 0x1;
- if (pmd != pmd_offset(pgd, vaddr))
- BUG();
- }
- pmd = pmd_offset(pgd, vaddr);
-#else
- pmd = (pmd_t *)pgd;
+#if CONFIG_HIGHMEM
+ /*
+ * Permanent kmaps:
+ */
+ vaddr = PKMAP_BASE;
+ fixrange_init(vaddr, vaddr + 4*1024*1024, pgd_base);
+
+ pgd = swapper_pg_dir + __pgd_offset(vaddr);
+ pmd = pmd_offset(pgd, vaddr);
+ pte = pte_offset(pmd, vaddr);
+ pkmap_page_table = pte;
#endif
- for (; (j < PTRS_PER_PMD) && vaddr; pmd++, j++) {
- if (pmd_none(*pmd)) {
- pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- memset((void*)pte, 0, PAGE_SIZE);
- pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte);
- if (pte != pte_offset(pmd, 0))
- BUG();
- }
- vaddr += PMD_SIZE;
- }
- j = 0;
- }
#if CONFIG_X86_PAE
/*
@@ -379,10 +403,17 @@ void __init zap_low_mappings (void)
{
int i;
/*
- * Zap initial low-memory mappings:
+ * Zap initial low-memory mappings.
+ *
+ * Note that "pgd_clear()" doesn't do it for
+ * us in this case, because pgd_clear() is a
+ * no-op in the 2-level case (pmd_clear() is
+ * the thing that clears the page-tables in
+ * that case).
*/
for (i = 0; i < USER_PTRS_PER_PGD; i++)
- pgd_clear(swapper_pg_dir + i);
+ pgd_val(swapper_pg_dir[i]) = 0;
+ flush_tlb_all();
}
/*
@@ -414,13 +445,18 @@ void __init paging_init(void)
#endif
#ifdef CONFIG_HIGHMEM
- kmap_init(); /* run after fixmap_init */
-#endif
-#ifdef CONFIG_HIGHMEM
- free_area_init(highend_pfn);
-#else
- free_area_init(max_low_pfn);
+ kmap_init();
#endif
+ {
+ unsigned int zones_size[3];
+
+ zones_size[0] = virt_to_phys((char *)MAX_DMA_ADDRESS)
+ >> PAGE_SHIFT;
+ zones_size[1] = max_low_pfn - zones_size[0];
+ zones_size[2] = highend_pfn - zones_size[0] - zones_size[1];
+
+ free_area_init(zones_size);
+ }
return;
}
@@ -435,7 +471,6 @@ void __init test_wp_bit(void)
/*
* Ok, all PAE-capable CPUs are definitely handling the WP bit right.
*/
-//#ifndef CONFIG_X86_PAE
const unsigned long vaddr = PAGE_OFFSET;
pgd_t *pgd;
pmd_t *pmd;
@@ -472,7 +507,6 @@ void __init test_wp_bit(void)
#endif
} else
printk(".\n");
-//#endif
}
static inline int page_is_ram (unsigned long pagenr)
@@ -535,7 +569,7 @@ void __init mem_init(void)
totalram_pages += totalhigh_pages;
#endif
printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\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),
reservedpages << (PAGE_SHIFT-10),
@@ -566,7 +600,7 @@ void __init mem_init(void)
void free_initmem(void)
{
unsigned long addr;
-
+
addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
ClearPageReserved(mem_map + MAP_NR(addr));
@@ -581,10 +615,10 @@ 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/m68k/config.in b/arch/m68k/config.in
index a458ff609..4888b4b48 100644
--- a/arch/m68k/config.in
+++ b/arch/m68k/config.in
@@ -70,6 +70,11 @@ bool 'Networking support' CONFIG_NET
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 a.out binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
diff --git a/arch/m68k/defconfig b/arch/m68k/defconfig
index 109ce19fa..b88a48984 100644
--- a/arch/m68k/defconfig
+++ b/arch/m68k/defconfig
@@ -38,6 +38,8 @@ CONFIG_M68040=y
CONFIG_NET=y
CONFIG_SYSVIPC=y
CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
CONFIG_ZORRO=y
diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c
index 64af7cf7c..d9750560f 100644
--- a/arch/m68k/kernel/m68k_ksyms.c
+++ b/arch/m68k/kernel/m68k_ksyms.c
@@ -75,3 +75,5 @@ EXPORT_SYMBOL_NOVERS(__down_failed);
EXPORT_SYMBOL_NOVERS(__down_failed_interruptible);
EXPORT_SYMBOL_NOVERS(__down_failed_trylock);
EXPORT_SYMBOL_NOVERS(__up_wakeup);
+
+EXPORT_SYMBOL(get_wchan);
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index ba94860f6..030b3e136 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -102,10 +102,6 @@ void machine_halt(void)
void machine_power_off(void)
{
-#if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
- apm_set_power_state(APM_STATE_OFF);
-#endif
-
if (mach_power_off)
mach_power_off();
for (;;);
@@ -350,3 +346,34 @@ 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 fp, pc;
+ unsigned long stack_page;
+ int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
+ stack_page = (unsigned long)p;
+ fp = ((struct switch_stack *)p->thread.ksp)->a6;
+ do {
+ if (fp < stack_page+sizeof(struct task_struct) ||
+ fp >= 8184+stack_page)
+ return 0;
+ pc = ((unsigned long *)fp)[1];
+ /* FIXME: This depends on the order of these functions. */
+ if (pc < first_sched || pc >= last_sched)
+ return pc;
+ fp = *(unsigned long *) fp;
+ } while (count++ < 16);
+ return 0;
+}
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c
index ab07e3d48..26a0518db 100644
--- a/arch/m68k/mac/iop.c
+++ b/arch/m68k/mac/iop.c
@@ -125,21 +125,9 @@
int iop_scc_present,iop_ism_present;
#ifdef CONFIG_PROC_FS
-
-/*
- * sneaky reuse of the PROC_MAC_VIA inode. It's not needed by via.c
- * anymore so we'll use it to debut the IOPs.
- */
-
-int iop_get_proc_info(char *, char **, off_t, int, int);
-
-static struct proc_dir_entry proc_mac_iop = {
- PROC_MAC_VIA, 7, "mac_iop",
- S_IFREG | S_IRUGO, 1, 0, 0,
- 0, &proc_array_inode_operations,
- &iop_get_proc_info
-};
-
+static int iop_get_proc_info(char *, char **, off_t, int, int);
+#else
+static int iop_get_proc_info(char *, char **, off_t, int, int) {}
#endif /* CONFIG_PROC_FS */
/* structure for tracking channel listeners */
@@ -315,9 +303,7 @@ void __init iop_init(void)
iop_listeners[IOP_NUM_ISM][i].handler = NULL;
}
-#ifdef CONFIG_PROC_FS
- proc_register(&proc_root, &proc_mac_iop);
-#endif
+ create_proc_info_entry("mac_iop",0,0,iop_get_proc_info);
}
/*
@@ -722,4 +708,5 @@ int iop_get_proc_info(char *buf, char **start, off_t pos, int count, int wr)
}
return (count > cnt) ? cnt : count;
}
+
#endif /* CONFIG_PROC_FS */
diff --git a/arch/m68k/math-emu/fp_emu.h b/arch/m68k/math-emu/fp_emu.h
index 9344b939b..1a4e16802 100644
--- a/arch/m68k/math-emu/fp_emu.h
+++ b/arch/m68k/math-emu/fp_emu.h
@@ -38,10 +38,11 @@
#ifndef _FP_EMU_H
#define _FP_EMU_H
-#ifndef __ASSEMBLY__
-
+#include "../kernel/m68k_defs.h"
#include <asm/math-emu.h>
+#ifndef __ASSEMBLY__
+
#define IS_INF(a) ((a)->exp == 0x7fff)
#define IS_ZERO(a) ((a)->mant.m64 == 0)
@@ -114,9 +115,6 @@ extern const struct fp_ext fp_Inf;
#else /* __ASSEMBLY__ */
-#include "../kernel/m68k_defs.h"
-#include <asm/math-emu.h>
-
/*
* set, reset or clear a bit in the fp status register
*/
diff --git a/arch/mips/config.in b/arch/mips/config.in
index 14256b262..c6a6bd704 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.35 2000/01/26 00:07:44 ralf Exp $
+# $Id: config.in,v 1.36 2000/01/27 23:45:24 ralf Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
@@ -110,6 +110,9 @@ else
bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
fi
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+ define_bool CONFIG_KCORE_ELF y
+fi
define_bool CONFIG_ELF_KERNEL y
if [ "$CONFIG_CPU_LITTLE_ENDIAN" = "n" ]; then
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 3e8d63570..48c4298cb 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -39,6 +39,7 @@ CONFIG_CPU_HAS_LLSC=y
# General setup
#
# CONFIG_CPU_LITTLE_ENDIAN is not set
+CONFIG_KCORE_ELF=y
CONFIG_ELF_KERNEL=y
CONFIG_BINFMT_IRIX=y
CONFIG_FORWARD_KEYBOARD=y
@@ -58,16 +59,6 @@ CONFIG_MODULES=y
CONFIG_KMOD=y
#
-# I2O device support
-#
-# CONFIG_I2O is not set
-# CONFIG_I2O_PCI is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
-
-#
# Plug and Play configuration
#
# CONFIG_PNP is not set
@@ -171,10 +162,20 @@ CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_SGIWD93=y
#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_PCI is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
# Network device support
#
CONFIG_NETDEVICES=y
-CONFIG_DUMMY=y
+# CONFIG_DUMMY is not set
# CONFIG_SLIP is not set
# CONFIG_PPP is not set
CONFIG_SGISEEQ=y
@@ -201,6 +202,10 @@ CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
@@ -225,6 +230,11 @@ CONFIG_PSMOUSE=y
# CONFIG_DRM is not set
#
+# PCMCIA character device support
+#
+# CONFIG_PCMCIA_SERIAL_CS is not set
+
+#
# USB drivers - not for the faint of heart
#
# CONFIG_USB is not set
@@ -242,6 +252,7 @@ CONFIG_AUTOFS_FS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
diff --git a/arch/mips/kernel/ipc.c b/arch/mips/kernel/ipc.c
index 8e48497f7..4db570ec8 100644
--- a/arch/mips/kernel/ipc.c
+++ b/arch/mips/kernel/ipc.c
@@ -30,84 +30,69 @@ asmlinkage int sys_ipc (uint call, int first, int second,
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
- if (call <= SEMCTL)
- switch (call) {
- case SEMOP:
- return sys_semop (first, (struct sembuf *)ptr, second);
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
+ switch (call) {
+ case SEMOP:
+ return sys_semop (first, (struct sembuf *)ptr, second);
+ case SEMGET:
+ return sys_semget (first, second, third);
+ case SEMCTL: {
+ union semun fourth;
+ if (!ptr)
+ return -EINVAL;
+ if (get_user(fourth.__pad, (void **) ptr))
+ return -EFAULT;
+ return sys_semctl (first, second, third, fourth);
+ }
+
+ case MSGSND:
+ return sys_msgsnd (first, (struct msgbuf *) ptr,
+ second, third);
+ case MSGRCV:
+ switch (version) {
+ case 0: {
+ struct ipc_kludge tmp;
if (!ptr)
return -EINVAL;
- if (get_user(fourth.__pad, (void **) ptr))
+
+ if (copy_from_user(&tmp,
+ (struct ipc_kludge *) ptr,
+ sizeof (tmp)))
return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
+ return sys_msgrcv (first, tmp.msgp, second,
+ tmp.msgtyp, third);
+ }
default:
- return -EINVAL;
+ return sys_msgrcv (first,
+ (struct msgbuf *) ptr,
+ second, fifth, third);
}
+ case MSGGET:
+ return sys_msgget ((key_t) first, second);
+ case MSGCTL:
+ return sys_msgctl (first, second, (struct msqid_ds *) ptr);
- if (call <= MSGCTL)
- switch (call) {
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge *) ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first,
- (struct msgbuf *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second,
- (struct msqid_ds *) ptr);
- default:
- return -EINVAL;
+ case SHMAT:
+ switch (version) {
+ default: {
+ ulong raddr;
+ ret = sys_shmat (first, (char *) ptr, second, &raddr);
+ if (ret)
+ return ret;
+ return put_user (raddr, (ulong *) third);
}
- if (call <= SHMCTL)
- switch (call) {
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = sys_shmat (first, (char *) ptr,
- second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong *) third);
- }
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- return sys_shmat (first, (char *) ptr,
- second, (ulong *) third);
- }
- case SHMDT:
- return sys_shmdt ((char *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds *) ptr);
- default:
- return -EINVAL;
+ case 1: /* iBCS2 emulator entry point */
+ if (!segment_eq(get_fs(), get_ds()))
+ return -EINVAL;
+ return sys_shmat (first, (char *) ptr, second, (ulong *) third);
}
-
- return -EINVAL;
+ case SHMDT:
+ return sys_shmdt ((char *)ptr);
+ case SHMGET:
+ return sys_shmget (first, second, third);
+ case SHMCTL:
+ return sys_shmctl (first, second,
+ (struct shmid_ds *) ptr);
+ default:
+ return -EINVAL;
+ }
}
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 86883ea45..080e08cfb 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -1,4 +1,4 @@
-/* $Id: irixelf.c,v 1.21 1999/09/28 22:25:46 ralf Exp $
+/* $Id: irixelf.c,v 1.22 1999/10/09 00:00:58 ralf Exp $
*
* irixelf.c: Code to load IRIX ELF executables which conform to
* the MIPS ABI.
@@ -404,9 +404,8 @@ static unsigned int load_irix_interp(struct elfhdr * interp_elf_ex,
/* Check sanity of IRIX elf executable header. */
static int verify_binary(struct elfhdr *ehp, struct linux_binprm *bprm)
{
- if (ehp->e_ident[0] != 0x7f || strncmp(&ehp->e_ident[1], "ELF", 3)) {
- return -ENOEXEC;
- }
+ if (memcmp(ehp->e_ident, ELFMAG, SELFMAG) != 0)
+ return -ENOEXEC;
/* First of all, some simple consistency checks */
if((ehp->e_type != ET_EXEC && ehp->e_type != ET_DYN) ||
@@ -495,7 +494,7 @@ out:
static inline int verify_irix_interpreter(struct elfhdr *ihp)
{
- if(ihp->e_ident[0] != 0x7f || strncmp(&ihp->e_ident[1], "ELF", 3))
+ if (memcmp(ihp->e_ident, ELFMAG, SELFMAG) != 0)
return -ELIBBAD;
return 0;
}
@@ -872,8 +871,7 @@ static inline int do_load_irix_library(struct file *file)
if (error != sizeof(elf_ex))
return -ENOEXEC;
- if (elf_ex.e_ident[0] != 0x7f ||
- strncmp(&elf_ex.e_ident[1], "ELF",3) != 0)
+ if (memcmp(elf_ex.e_ident, ELFMAG, SELFMAG) != 0)
return -ENOEXEC;
/* First of all, some simple consistency checks. */
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index 2b12f0e34..74d7373d4 100644
--- a/arch/mips/kernel/mips_ksyms.c
+++ b/arch/mips/kernel/mips_ksyms.c
@@ -1,4 +1,4 @@
-/* $Id: mips_ksyms.c,v 1.21 1999/10/21 00:23:04 ralf Exp $
+/* $Id: mips_ksyms.c,v 1.22 1999/12/04 03:59:00 ralf Exp $
*
* Export MIPS-specific functions needed for loadable modules.
*
@@ -125,3 +125,4 @@ EXPORT_SYMBOL(unregister_fpe);
EXPORT_SYMBOL(screen_info);
#endif
+EXPORT_SYMBOL(get_wchan);
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index f0c346b61..959e7b339 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.16 1999/10/09 00:00:58 ralf Exp $
+/* $Id: process.c,v 1.17 1999/12/04 03:59:00 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -186,3 +186,37 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
return retval;
}
+
+/*
+ * 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;
+
+ pc = thread_saved_pc(&p->thread);
+ if (pc == (unsigned long) interruptible_sleep_on
+ || pc == (unsigned long) sleep_on) {
+ schedule_frame = ((unsigned long *)p->thread.reg30)[9];
+ return ((unsigned long *)schedule_frame)[15];
+ }
+ if (pc == (unsigned long) interruptible_sleep_on_timeout
+ || pc == (unsigned long) sleep_on_timeout) {
+ schedule_frame = ((unsigned long *)p->thread.reg30)[9];
+ return ((unsigned long *)schedule_frame)[16];
+ }
+ if (pc >= first_sched && pc < last_sched) {
+ printk(KERN_DEBUG "Bug in %s\n", __FUNCTION__);
+ }
+
+ return pc;
+}
diff --git a/arch/mips/kernel/scall_o32.S b/arch/mips/kernel/scall_o32.S
index a6e4d2e90..5d7b42a2a 100644
--- a/arch/mips/kernel/scall_o32.S
+++ b/arch/mips/kernel/scall_o32.S
@@ -1,4 +1,4 @@
-/* $Id: scall_o32.S,v 1.7 1999/07/26 19:42:40 harald Exp $
+/* $Id: scall_o32.S,v 1.8 1999/12/04 03:59:00 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -189,3 +189,4 @@ illegal_syscall:
li t0, 1 # set error flag
sw t0, PT_R7(sp)
j ret_from_sys_call
+ END(handle_sys)
diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h
index 688162211..7dd03b640 100644
--- a/arch/mips/kernel/syscalls.h
+++ b/arch/mips/kernel/syscalls.h
@@ -1,4 +1,4 @@
-/* $Id: syscalls.h,v 1.17 1999/09/28 22:25:48 ralf Exp $
+/* $Id: syscalls.h,v 1.18 1999/10/09 00:00:58 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -91,7 +91,7 @@ SYS(sys_sigsuspend, 0)
SYS(sys_sigpending, 1)
SYS(sys_sethostname, 2)
SYS(sys_setrlimit, 2) /* 4075 */
-SYS(sys_getrlimit, 2)
+SYS(sys_old_getrlimit, 2)
SYS(sys_getrusage, 2)
SYS(sys_gettimeofday, 2)
SYS(sys_settimeofday, 2)
@@ -225,3 +225,4 @@ SYS(sys_sigaltstack, 0)
SYS(sys_sendfile, 3)
SYS(sys_ni_syscall, 0)
SYS(sys_ni_syscall, 0)
+SYS(sys_getrlimit, 2) /* 4210 */
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 182024ce8..afd1c6b70 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.22 2000/01/27 23:21:57 ralf Exp $
+/* $Id: init.c,v 1.23 2000/01/27 23:45:25 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -20,6 +20,7 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
+#include <linux/highmem.h>
#include <linux/swap.h>
#include <linux/swapctl.h>
#ifdef CONFIG_BLK_DEV_INITRD
@@ -248,10 +249,17 @@ extern char __init_begin, __init_end;
void __init paging_init(void)
{
+ unsigned int zones_size[2];
+
/* Initialize the entire pgd. */
pgd_init((unsigned long)swapper_pg_dir);
pgd_init((unsigned long)swapper_pg_dir + PAGE_SIZE / 2);
return free_area_init(max_low_pfn);
+
+ zones_size[0] = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ zones_size[1] = max_low_pfn - zones_size[0];
+
+ free_area_init(zones_size);
}
extern int page_is_ram(unsigned long pagenr);
@@ -279,9 +287,9 @@ void __init mem_init(void)
datasize = (unsigned long) &_edata - (unsigned long) &_fdata;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
- printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
+ printk("Memory: %uk/%luk available (%ldk kernel code, %ldk reserved, "
"%ldk data, %ldk init)\n",
- (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
+ (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
ram << (PAGE_SHIFT-10),
codesize >> 10,
reservedpages << (PAGE_SHIFT-10),
@@ -314,10 +322,10 @@ 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 = 0;
- val->freehigh = 0;
+ val->freehigh = nr_free_highpages();
val->mem_unit = PAGE_SIZE;
return;
diff --git a/arch/mips/mm/umap.c b/arch/mips/mm/umap.c
index 73b5d643d..3ca4424eb 100644
--- a/arch/mips/mm/umap.c
+++ b/arch/mips/mm/umap.c
@@ -123,7 +123,7 @@ static inline void free_pte(pte_t page)
current->mm->rss--;
return;
}
- swap_free(page);
+ swap_free(pte_to_swp_entry(page));
}
static inline void forget_pte(pte_t page)
diff --git a/arch/mips64/Makefile b/arch/mips64/Makefile
index d7ffcedb9..218c22ec4 100644
--- a/arch/mips64/Makefile
+++ b/arch/mips64/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.4 2000/01/17 23:32:46 ralf Exp $
+# $Id: Makefile,v 1.5 2000/01/21 22:34:03 ralf Exp $
#
# This file is subject to the terms and conditions of the GNU General Public
# License. See the file "COPYING" in the main directory of this archive
@@ -141,6 +141,7 @@ archclean:
@$(MAKEBOOT) clean
$(MAKE) -C arch/$(ARCH)/kernel clean
$(MAKE) -C arch/$(ARCH)/tools clean
+ rm -f vmlinux.64
archmrproper:
diff --git a/arch/mips64/config.in b/arch/mips64/config.in
index 823c375a6..4325d507e 100644
--- a/arch/mips64/config.in
+++ b/arch/mips64/config.in
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.7 2000/01/20 23:50:27 ralf Exp $
+# $Id: config.in,v 1.8 2000/01/27 23:45:25 ralf Exp $
#
# For a description of the syntax of this configuration file,
# see the Configure script.
@@ -182,6 +182,10 @@ if [ "$CONFIG_VT" = "y" ]; then
endmenu
fi
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+ define_bool CONFIG_KCORE_ELF y
+fi
+
mainmenu_option next_comment
comment 'Sound'
diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig
index ab794d555..d57fa71c6 100644
--- a/arch/mips64/defconfig
+++ b/arch/mips64/defconfig
@@ -280,6 +280,7 @@ CONFIG_MSDOS_PARTITION=y
CONFIG_SGI_PARTITION=y
# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
+CONFIG_KCORE_ELF=y
#
# Sound
diff --git a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22
index b270cb5dd..fb7026b19 100644
--- a/arch/mips64/defconfig-ip22
+++ b/arch/mips64/defconfig-ip22
@@ -195,6 +195,10 @@ CONFIG_VT_CONSOLE=y
# CONFIG_BUSMOUSE is not set
# CONFIG_MOUSE is not set
# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
# CONFIG_WATCHDOG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
@@ -218,6 +222,10 @@ CONFIG_VT_CONSOLE=y
# CONFIG_FTAPE is not set
#
+# PCMCIA character device support
+#
+
+#
# USB drivers - not for the faint of heart
#
# CONFIG_USB is not set
@@ -274,6 +282,7 @@ CONFIG_SGI_PARTITION=y
# Console drivers
#
CONFIG_SGI_NEWPORT_CONSOLE=y
+CONFIG_KCORE_ELF=y
#
# Sound
diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27
index ab794d555..d57fa71c6 100644
--- a/arch/mips64/defconfig-ip27
+++ b/arch/mips64/defconfig-ip27
@@ -280,6 +280,7 @@ CONFIG_MSDOS_PARTITION=y
CONFIG_SGI_PARTITION=y
# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
+CONFIG_KCORE_ELF=y
#
# Sound
diff --git a/arch/mips64/kernel/mips64_ksyms.c b/arch/mips64/kernel/mips64_ksyms.c
index cc077a486..d0647e4c5 100644
--- a/arch/mips64/kernel/mips64_ksyms.c
+++ b/arch/mips64/kernel/mips64_ksyms.c
@@ -1,4 +1,4 @@
-/* $Id: mips64_ksyms.c,v 1.4 1999/11/19 20:35:22 ralf Exp $
+/* $Id: mips64_ksyms.c,v 1.5 2000/01/17 23:32:46 ralf Exp $
*
* Export MIPS64-specific functions needed for loadable modules.
*
@@ -111,3 +111,5 @@ EXPORT_SYMBOL(unregister_fpe);
#ifdef CONFIG_VT
EXPORT_SYMBOL(screen_info);
#endif
+
+EXPORT_SYMBOL(get_wchan);
diff --git a/arch/mips64/kernel/process.c b/arch/mips64/kernel/process.c
index fa10427e7..f6998a6bb 100644
--- a/arch/mips64/kernel/process.c
+++ b/arch/mips64/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.7 1999/12/21 12:40:52 ralf Exp $
+/* $Id: process.c,v 1.4 2000/01/16 01:34:01 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -177,3 +177,37 @@ int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags)
return retval;
}
+
+/*
+ * 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;
+
+ pc = thread_saved_pc(&p->thread);
+ if (pc == (unsigned long) interruptible_sleep_on
+ || pc == (unsigned long) sleep_on) {
+ schedule_frame = ((unsigned long *)p->thread.reg30)[9];
+ return ((unsigned long *)schedule_frame)[15];
+ }
+ if (pc == (unsigned long) interruptible_sleep_on_timeout
+ || pc == (unsigned long) sleep_on_timeout) {
+ schedule_frame = ((unsigned long *)p->thread.reg30)[9];
+ return ((unsigned long *)schedule_frame)[16];
+ }
+ if (pc >= first_sched && pc < last_sched) {
+ printk(KERN_DEBUG "Bug in %s\n", __FUNCTION__);
+ }
+
+ return pc;
+}
diff --git a/arch/mips64/kernel/r4k_tlb_debug.c b/arch/mips64/kernel/r4k_tlb_debug.c
index a9d41cb46..e9ae2d604 100644
--- a/arch/mips64/kernel/r4k_tlb_debug.c
+++ b/arch/mips64/kernel/r4k_tlb_debug.c
@@ -1,4 +1,4 @@
-/* $Id: r4k_tlb_debug.c,v 1.6 1999/11/23 17:12:49 ralf Exp $
+/* $Id: r4k_tlb_debug.c,v 1.2 2000/01/17 23:32:46 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -19,6 +19,9 @@
#include <asm/ptrace.h>
#include <asm/system.h>
+asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write,
+ unsigned long address);
+
asmlinkage void tlb_refill_debug(struct pt_regs regs)
{
show_regs(&regs);
diff --git a/arch/mips64/kernel/scall_o32.S b/arch/mips64/kernel/scall_o32.S
index 56b087a7b..f33a4afb2 100644
--- a/arch/mips64/kernel/scall_o32.S
+++ b/arch/mips64/kernel/scall_o32.S
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: scall_o32.S,v 1.3 2000/01/17 23:32:46 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -267,7 +267,7 @@ illegal_syscall:
sys sys32_sigpending 1
sys sys_sethostname 2
sys sys_setrlimit 2 /* 4075 */
- sys sys_getrlimit 2
+ sys sys_old_getrlimit 2
sys sys_getrusage 2
sys sys_gettimeofday 2
sys sys_settimeofday 2
@@ -401,6 +401,7 @@ illegal_syscall:
sys sys_sendfile 3
sys sys_ni_syscall 0
sys sys_ni_syscall 0
+ sys sys_getrlimit 2 /* 4210 */
.endm
.macro sys function, nargs
diff --git a/arch/mips64/kernel/syscall.c b/arch/mips64/kernel/syscall.c
index 31273522c..8273d5285 100644
--- a/arch/mips64/kernel/syscall.c
+++ b/arch/mips64/kernel/syscall.c
@@ -1,4 +1,4 @@
-/* $Id: syscall.c,v 1.3 1999/10/19 20:51:46 ralf Exp $
+/* $Id: syscall.c,v 1.1 1999/12/04 03:59:00 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -240,86 +240,71 @@ asmlinkage int sys_ipc (uint call, int first, int second,
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
- if (call <= SEMCTL)
- switch (call) {
- case SEMOP:
- return sys_semop (first, (struct sembuf *)ptr, second);
- case SEMGET:
- return sys_semget (first, second, third);
- case SEMCTL: {
- union semun fourth;
+ switch (call) {
+ case SEMOP:
+ return sys_semop (first, (struct sembuf *)ptr, second);
+ case SEMGET:
+ return sys_semget (first, second, third);
+ case SEMCTL: {
+ union semun fourth;
+ if (!ptr)
+ return -EINVAL;
+ if (get_user(fourth.__pad, (void **) ptr))
+ return -EFAULT;
+ return sys_semctl (first, second, third, fourth);
+ }
+
+ case MSGSND:
+ return sys_msgsnd (first, (struct msgbuf *) ptr,
+ second, third);
+ case MSGRCV:
+ switch (version) {
+ case 0: {
+ struct ipc_kludge tmp;
if (!ptr)
return -EINVAL;
- if (get_user(fourth.__pad, (void **) ptr))
+
+ if (copy_from_user(&tmp,
+ (struct ipc_kludge *) ptr,
+ sizeof (tmp)))
return -EFAULT;
- return sys_semctl (first, second, third, fourth);
- }
- default:
- return -EINVAL;
+ return sys_msgrcv (first, tmp.msgp, second,
+ tmp.msgtyp, third);
}
-
- if (call <= MSGCTL)
- switch (call) {
- case MSGSND:
- return sys_msgsnd (first, (struct msgbuf *) ptr,
- second, third);
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- if (!ptr)
- return -EINVAL;
-
- if (copy_from_user(&tmp,
- (struct ipc_kludge *) ptr,
- sizeof (tmp)))
- return -EFAULT;
- return sys_msgrcv (first, tmp.msgp, second,
- tmp.msgtyp, third);
- }
- default:
- return sys_msgrcv (first,
- (struct msgbuf *) ptr,
- second, fifth, third);
- }
- case MSGGET:
- return sys_msgget ((key_t) first, second);
- case MSGCTL:
- return sys_msgctl (first, second,
- (struct msqid_ds *) ptr);
default:
- return -EINVAL;
+ return sys_msgrcv (first,
+ (struct msgbuf *) ptr,
+ second, fifth, third);
}
- if (call <= SHMCTL)
- switch (call) {
- case SHMAT:
- switch (version) {
- default: {
- ulong raddr;
- ret = sys_shmat (first, (char *) ptr,
- second, &raddr);
- if (ret)
- return ret;
- return put_user (raddr, (ulong *) third);
- }
- case 1: /* iBCS2 emulator entry point */
- if (!segment_eq(get_fs(), get_ds()))
- return -EINVAL;
- return sys_shmat (first, (char *) ptr,
- second, (ulong *) third);
- }
- case SHMDT:
- return sys_shmdt ((char *)ptr);
- case SHMGET:
- return sys_shmget (first, second, third);
- case SHMCTL:
- return sys_shmctl (first, second,
- (struct shmid_ds *) ptr);
- default:
- return -EINVAL;
+ case MSGGET:
+ return sys_msgget ((key_t) first, second);
+ case MSGCTL:
+ return sys_msgctl (first, second, (struct msqid_ds *) ptr);
+
+ case SHMAT:
+ switch (version) {
+ default: {
+ ulong raddr;
+ ret = sys_shmat (first, (char *) ptr, second, &raddr);
+ if (ret)
+ return ret;
+ return put_user (raddr, (ulong *) third);
}
-
- return -EINVAL;
+ case 1: /* iBCS2 emulator entry point */
+ if (!segment_eq(get_fs(), get_ds()))
+ return -EINVAL;
+ return sys_shmat (first, (char *) ptr, second, (ulong *) third);
+ }
+ case SHMDT:
+ return sys_shmdt ((char *)ptr);
+ case SHMGET:
+ return sys_shmget (first, second, third);
+ case SHMCTL:
+ return sys_shmctl (first, second,
+ (struct shmid_ds *) ptr);
+ default:
+ return -EINVAL;
+ }
}
/*
diff --git a/arch/mips64/mm/init.c b/arch/mips64/mm/init.c
index d4da03f56..06b047ef9 100644
--- a/arch/mips64/mm/init.c
+++ b/arch/mips64/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.8 2000/01/27 23:21:57 ralf Exp $
+/* $Id: init.c,v 1.9 2000/01/27 23:45:25 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -20,6 +20,7 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/bootmem.h>
+#include <linux/highmem.h>
#include <linux/swap.h>
#include <linux/swapctl.h>
#ifdef CONFIG_BLK_DEV_INITRD
@@ -342,11 +343,17 @@ extern char __init_begin, __init_end;
void __init paging_init(void)
{
+ unsigned int zones_size[2];
+
/* Initialize the entire pgd. */
pgd_init((unsigned long)swapper_pg_dir);
pgd_init((unsigned long)swapper_pg_dir + PAGE_SIZE / 2);
pmd_init((unsigned long)invalid_pmd_table);
- return free_area_init(max_low_pfn);
+
+ zones_size[0] = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ zones_size[1] = max_low_pfn - zones_size[0];
+
+ free_area_init(zones_size);
}
extern int page_is_ram(unsigned long pagenr);
@@ -374,9 +381,9 @@ void __init mem_init(void)
datasize = (unsigned long) &_edata - (unsigned long) &_fdata;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
- printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
+ printk("Memory: %uk/%luk available (%ldk kernel code, %ldk reserved, "
"%ldk data, %ldk init)\n",
- (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
+ (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
ram << (PAGE_SHIFT-10),
codesize >> 10,
reservedpages << (PAGE_SHIFT-10),
@@ -412,10 +419,10 @@ 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 = 0;
- val->freehigh = 0;
+ val->freehigh = nr_free_highpages();
val->mem_unit = PAGE_SIZE;
return;
diff --git a/arch/mips64/mm/umap.c b/arch/mips64/mm/umap.c
index dc80a2eff..5fefe091d 100644
--- a/arch/mips64/mm/umap.c
+++ b/arch/mips64/mm/umap.c
@@ -1,4 +1,4 @@
-/* $Id: umap.c,v 1.2 1999/12/04 03:59:01 ralf Exp $
+/* $Id: umap.c,v 1.3 2000/01/27 01:05:24 ralf Exp $
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file "COPYING" in the main directory of this archive
@@ -118,7 +118,7 @@ static inline void free_pte(pte_t page)
current->mm->rss--;
return;
}
- swap_free(page);
+ swap_free(pte_to_swp_entry(page));
}
static inline void forget_pte(pte_t page)
diff --git a/arch/ppc/amiga/Makefile b/arch/ppc/amiga/Makefile
index 2d5ec4811..8288eabc2 100644
--- a/arch/ppc/amiga/Makefile
+++ b/arch/ppc/amiga/Makefile
@@ -9,7 +9,8 @@
O_TARGET := amiga.o
O_OBJS := config.o amiints.o cia.o time.o \
- bootinfo.o amisound.o chipram.o ints.o
+ bootinfo.o amisound.o chipram.o
+
OX_OBJS := amiga_ksyms.o
ifdef CONFIG_AMIGA_PCMCIA
diff --git a/arch/ppc/amiga/amiints.c b/arch/ppc/amiga/amiints.c
index 408f8211c..75d90312b 100644
--- a/arch/ppc/amiga/amiints.c
+++ b/arch/ppc/amiga/amiints.c
@@ -53,10 +53,10 @@
#include <asm/amigappc.h>
#endif
-extern int cia_request_irq(struct ciabase *base,int irq,
+extern int cia_request_irq(int irq,
void (*handler)(int, void *, struct pt_regs *),
unsigned long flags, const char *devname, void *dev_id);
-extern void cia_free_irq(struct ciabase *base, unsigned int irq, void *dev_id);
+extern void cia_free_irq(unsigned int irq, void *dev_id);
extern void cia_init_IRQ(struct ciabase *base);
extern int cia_get_irq_list(struct ciabase *base, char *buf);
@@ -89,7 +89,8 @@ static void ami_badint(int irq, void *dev_id, struct pt_regs *fp)
* the amiga IRQ handling routines.
*/
-void __init amiga_init_IRQ(void)
+__init
+void amiga_init_IRQ(void)
{
int i;
@@ -216,13 +217,8 @@ int amiga_request_irq(unsigned int irq,
return sys_request_irq(irq - IRQ_AMIGA_AUTO, handler,
flags, devname, dev_id);
- if (irq >= IRQ_AMIGA_CIAB)
- return cia_request_irq(&ciab_base, irq - IRQ_AMIGA_CIAB,
- handler, flags, devname, dev_id);
-
if (irq >= IRQ_AMIGA_CIAA)
- return cia_request_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA,
- handler, flags, devname, dev_id);
+ return cia_request_irq(irq, handler, flags, devname, dev_id);
/*
* IRQ_AMIGA_PORTS & IRQ_AMIGA_EXTER defaults to shared,
@@ -262,13 +258,8 @@ void amiga_free_irq(unsigned int irq, void *dev_id)
if (irq >= IRQ_AMIGA_AUTO)
sys_free_irq(irq - IRQ_AMIGA_AUTO, dev_id);
- if (irq >= IRQ_AMIGA_CIAB) {
- cia_free_irq(&ciab_base, irq - IRQ_AMIGA_CIAB, dev_id);
- return;
- }
-
if (irq >= IRQ_AMIGA_CIAA) {
- cia_free_irq(&ciaa_base, irq - IRQ_AMIGA_CIAA, dev_id);
+ cia_free_irq(irq, dev_id);
return;
}
@@ -314,17 +305,9 @@ void amiga_enable_irq(unsigned int irq)
return;
}
- if (irq >= IRQ_AMIGA_CIAB) {
- cia_set_irq(&ciab_base, (1 << (irq - IRQ_AMIGA_CIAB)));
- cia_able_irq(&ciab_base, CIA_ICR_SETCLR |
- (1 << (irq - IRQ_AMIGA_CIAB)));
- return;
- }
-
if (irq >= IRQ_AMIGA_CIAA) {
- cia_set_irq(&ciaa_base, (1 << (irq - IRQ_AMIGA_CIAA)));
- cia_able_irq(&ciaa_base, CIA_ICR_SETCLR |
- (1 << (irq - IRQ_AMIGA_CIAA)));
+ cia_set_irq(irq, 0);
+ cia_able_irq(irq, 1);
return;
}
@@ -349,13 +332,8 @@ void amiga_disable_irq(unsigned int irq)
return;
}
- if (irq >= IRQ_AMIGA_CIAB) {
- cia_able_irq(&ciab_base, 1 << (irq - IRQ_AMIGA_CIAB));
- return;
- }
-
if (irq >= IRQ_AMIGA_CIAA) {
- cia_able_irq(&ciaa_base, 1 << (irq - IRQ_AMIGA_CIAA));
+ cia_able_irq(irq, 0);
return;
}
@@ -528,10 +506,20 @@ static void ami_int7(int irq, void *dev_id, struct pt_regs *fp)
panic ("level 7 interrupt received\n");
}
+#ifdef CONFIG_APUS
+/* The PPC irq handling links all handlers requested on the same vector
+ and executes them in a loop. Having ami_badint at the end of the chain
+ is a bad idea. */
+void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
+ NULL, ami_int1, NULL, NULL /* FB expects to replace ami_int3*/,
+ ami_int4, ami_int5, NULL, ami_int7
+};
+#else
void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = {
ami_badint, ami_int1, ami_badint, ami_int3,
ami_int4, ami_int5, ami_badint, ami_int7
};
+#endif
int amiga_get_irq_list(char *buf)
{
diff --git a/arch/ppc/amiga/cia.c b/arch/ppc/amiga/cia.c
index ea35c79b3..85133f8da 100644
--- a/arch/ppc/amiga/cia.c
+++ b/arch/ppc/amiga/cia.c
@@ -1 +1,235 @@
-#include "../../m68k/amiga/cia.c"
+/*
+ * linux/arch/m68k/amiga/cia.c - CIA support
+ *
+ * Copyright (C) 1996 Roman Zippel
+ *
+ * The concept of some functions bases on the original Amiga OS function
+ *
+ * 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.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/amigahw.h>
+#include <asm/amigaints.h>
+
+struct ciabase {
+ volatile struct CIA *cia;
+ u_char icr_mask, icr_data;
+ u_short int_mask;
+ int handler_irq, cia_irq, server_irq;
+ char *name;
+ struct irq_server server;
+ irq_handler_t irq_list[CIA_IRQS];
+} ciaa_base = {
+ &ciaa, 0, 0, IF_PORTS,
+ IRQ_AMIGA_AUTO_2, IRQ_AMIGA_CIAA,
+ IRQ_AMIGA_PORTS,
+ "CIAA handler", {0, 0}
+}, ciab_base = {
+ &ciab, 0, 0, IF_EXTER,
+ IRQ_AMIGA_AUTO_6, IRQ_AMIGA_CIAB,
+ IRQ_AMIGA_EXTER,
+ "CIAB handler", {0, 0}
+};
+
+#define CIA_SET_BASE_ADJUST_IRQ(base, irq) \
+do { \
+ if (irq >= IRQ_AMIGA_CIAB) { \
+ base = &ciab_base; \
+ irq =- IRQ_AMIGA_CIAB; \
+ } else { \
+ base = &ciaa_base; \
+ irq =- IRQ_AMIGA_CIAA; \
+ } \
+} while (0)
+
+/*
+ * Cause or clear CIA interrupts, return old interrupt status.
+ */
+
+static unsigned char cia_set_irq_private(struct ciabase *base,
+ unsigned char mask)
+{
+ u_char old;
+
+ old = (base->icr_data |= base->cia->icr);
+ if (mask & CIA_ICR_SETCLR)
+ base->icr_data |= mask;
+ else
+ base->icr_data &= ~mask;
+ if (base->icr_data & base->icr_mask)
+ custom.intreq = IF_SETCLR | base->int_mask;
+ return old & base->icr_mask;
+}
+
+unsigned char cia_set_irq(unsigned int irq, int set)
+{
+ struct ciabase *base;
+ unsigned char mask;
+
+ if (irq >= IRQ_AMIGA_CIAB)
+ mask = (1 << (irq - IRQ_AMIGA_CIAB));
+ else
+ mask = (1 << (irq - IRQ_AMIGA_CIAA));
+ mask |= (set) ? CIA_ICR_SETCLR : 0;
+
+ CIA_SET_BASE_ADJUST_IRQ(base, irq);
+
+ return cia_set_irq_private(base, mask);
+}
+
+unsigned char cia_get_irq_mask(unsigned int irq)
+{
+ struct ciabase *base;
+
+ CIA_SET_BASE_ADJUST_IRQ(base, irq);
+
+ return base->cia->icr;
+}
+
+/*
+ * Enable or disable CIA interrupts, return old interrupt mask,
+ * interrupts will only be enabled if a handler exists
+ */
+
+static unsigned char cia_able_irq_private(struct ciabase *base,
+ unsigned char mask)
+{
+ u_char old, tmp;
+ int i;
+
+ old = base->icr_mask;
+ base->icr_data |= base->cia->icr;
+ base->cia->icr = mask;
+ if (mask & CIA_ICR_SETCLR)
+ base->icr_mask |= mask;
+ else
+ base->icr_mask &= ~mask;
+ base->icr_mask &= CIA_ICR_ALL;
+ for (i = 0, tmp = 1; i < CIA_IRQS; i++, tmp <<= 1) {
+ if ((tmp & base->icr_mask) && !base->irq_list[i].handler) {
+ base->icr_mask &= ~tmp;
+ base->cia->icr = tmp;
+ }
+ }
+ if (base->icr_data & base->icr_mask)
+ custom.intreq = IF_SETCLR | base->int_mask;
+ return old;
+}
+
+unsigned char cia_able_irq(unsigned int irq, int enable)
+{
+ struct ciabase *base;
+ unsigned char mask;
+
+ if (irq >= IRQ_AMIGA_CIAB)
+ mask = (1 << (irq - IRQ_AMIGA_CIAB));
+ else
+ mask = (1 << (irq - IRQ_AMIGA_CIAA));
+ mask |= (enable) ? CIA_ICR_SETCLR : 0;
+
+ CIA_SET_BASE_ADJUST_IRQ(base, irq);
+
+ return cia_able_irq_private(base, mask);
+}
+
+int cia_request_irq(unsigned int irq,
+ void (*handler)(int, void *, struct pt_regs *),
+ unsigned long flags, const char *devname, void *dev_id)
+{
+ u_char mask;
+ struct ciabase *base;
+
+ CIA_SET_BASE_ADJUST_IRQ(base, irq);
+
+ base->irq_list[irq].handler = handler;
+ base->irq_list[irq].flags = flags;
+ base->irq_list[irq].dev_id = dev_id;
+ base->irq_list[irq].devname = devname;
+
+ /* enable the interrupt */
+ mask = 1 << irq;
+ cia_set_irq_private(base, mask);
+ cia_able_irq_private(base, CIA_ICR_SETCLR | mask);
+ return 0;
+}
+
+void cia_free_irq(unsigned int irq, void *dev_id)
+{
+ struct ciabase *base;
+
+ CIA_SET_BASE_ADJUST_IRQ(base, irq);
+
+ if (base->irq_list[irq].dev_id != dev_id)
+ printk("%s: removing probably wrong IRQ %i from %s\n",
+ __FUNCTION__, base->cia_irq + irq,
+ base->irq_list[irq].devname);
+
+ base->irq_list[irq].handler = NULL;
+ base->irq_list[irq].flags = 0;
+
+ cia_able_irq_private(base, 1 << irq);
+}
+
+static void cia_handler(int irq, void *dev_id, struct pt_regs *fp)
+{
+ struct ciabase *base = (struct ciabase *)dev_id;
+ int mach_irq, i;
+ unsigned char ints;
+
+ mach_irq = base->cia_irq;
+ irq = SYS_IRQS + mach_irq;
+ ints = cia_set_irq_private(base, CIA_ICR_ALL);
+ custom.intreq = base->int_mask;
+ for (i = 0; i < CIA_IRQS; i++, irq++, mach_irq++) {
+ if (ints & 1) {
+ kstat.irqs[0][irq]++;
+ base->irq_list[i].handler(mach_irq, base->irq_list[i].dev_id, fp);
+ }
+ ints >>= 1;
+ }
+ amiga_do_irq_list(base->server_irq, fp, &base->server);
+}
+
+void __init cia_init_IRQ(struct ciabase *base)
+{
+ int i;
+
+ /* init isr handlers */
+ for (i = 0; i < CIA_IRQS; i++) {
+ base->irq_list[i].handler = NULL;
+ base->irq_list[i].flags = 0;
+ }
+
+ /* clear any pending interrupt and turn off all interrupts */
+ cia_set_irq_private(base, CIA_ICR_ALL);
+ cia_able_irq_private(base, CIA_ICR_ALL);
+
+ /* install CIA handler */
+ request_irq(base->handler_irq, cia_handler, 0, base->name, base);
+
+ custom.intena = IF_SETCLR | base->int_mask;
+}
+
+int cia_get_irq_list(struct ciabase *base, char *buf)
+{
+ int i, j, len = 0;
+
+ j = base->cia_irq;
+ for (i = 0; i < CIA_IRQS; i++) {
+ len += sprintf(buf+len, "cia %2d: %10d ", j + i,
+ kstat.irqs[0][SYS_IRQS + j + i]);
+ len += sprintf(buf+len, " ");
+ len += sprintf(buf+len, "%s\n", base->irq_list[i].devname);
+ }
+ return len;
+}
diff --git a/arch/ppc/amiga/config.c b/arch/ppc/amiga/config.c
index 47b8f64ea..652eb1582 100644
--- a/arch/ppc/amiga/config.c
+++ b/arch/ppc/amiga/config.c
@@ -6,7 +6,6 @@
void (*mach_kbd_reset_setup) (char *, int) __initdata = 0;
#include <asm/io.h>
-#include <asm/system.h>
/*
* linux/arch/m68k/amiga/config.c
@@ -461,6 +460,8 @@ static void __init amiga_sched_init(void (*timer_routine)(int, void *,
#define TICK_SIZE 10000
+extern unsigned char cia_get_irq_mask(unsigned int irq);
+
/* This is always executed with interrupts disabled. */
static unsigned long amiga_gettimeoffset (void)
{
@@ -481,7 +482,7 @@ static unsigned long amiga_gettimeoffset (void)
if (ticks > jiffy_ticks / 2)
/* check for pending interrupt */
- if (cia_set_irq(&ciab_base, 0) & CIA_ICR_TA)
+ if (cia_get_irq_mask(IRQ_AMIGA_CIAB) & CIA_ICR_TA)
offset = 10000;
ticks = jiffy_ticks - ticks;
diff --git a/arch/ppc/common_defconfig b/arch/ppc/common_defconfig
index 0bcbf06aa..8b232d723 100644
--- a/arch/ppc/common_defconfig
+++ b/arch/ppc/common_defconfig
@@ -1,13 +1,19 @@
#
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
#
#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
# Platform support
#
CONFIG_PPC=y
CONFIG_6xx=y
# CONFIG_PPC64 is not set
+# CONFIG_82xx is not set
# CONFIG_8xx is not set
# CONFIG_PMAC is not set
# CONFIG_PREP is not set
@@ -15,17 +21,19 @@ CONFIG_6xx=y
CONFIG_ALL_PPC=y
# CONFIG_GEMINI is not set
# CONFIG_APUS is not set
-# CONFIG_MBX is not set
# CONFIG_SMP is not set
CONFIG_6xx=y
#
-# General setup
+# Loadable module support
#
-CONFIG_EXPERIMENTAL=y
CONFIG_MODULES=y
CONFIG_MODVERSIONS=y
CONFIG_KMOD=y
+
+#
+# General setup
+#
CONFIG_PCI=y
CONFIG_NET=y
CONFIG_SYSCTL=y
@@ -34,6 +42,11 @@ CONFIG_SYSVIPC=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
# CONFIG_BINFMT_MISC is not set
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
# CONFIG_PARPORT is not set
CONFIG_VGA_CONSOLE=y
CONFIG_FB=y
@@ -41,7 +54,6 @@ CONFIG_FB_COMPAT_XPMAC=y
CONFIG_PMAC_PBOOK=y
CONFIG_MAC_FLOPPY=y
CONFIG_MAC_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
CONFIG_ADB=y
CONFIG_ADB_CUDA=y
CONFIG_ADB_MACIO=y
@@ -57,21 +69,27 @@ CONFIG_BOOTX_TEXT=y
# Plug and Play configuration
#
# CONFIG_PNP is not set
-# CONFIG_ISAPNP is not set
#
# Block devices
#
CONFIG_BLK_DEV_FD=y
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=y
-# CONFIG_IDECD_SLOTS is not set
# CONFIG_BLK_DEV_IDETAPE is not set
CONFIG_BLK_DEV_IDEFLOPPY=y
# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
# CONFIG_BLK_DEV_IDEPCI is not set
@@ -83,12 +101,17 @@ CONFIG_BLK_DEV_IDEDMA=y
CONFIG_IDEDMA_AUTO=y
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_BLK_CPQ_DA is not set
+
+#
+# Additional Block Devices
+#
CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_MD is not set
CONFIG_BLK_DEV_RAM=y
CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
CONFIG_PARIDE_PARPORT=y
# CONFIG_PARIDE is not set
CONFIG_BLK_DEV_IDE_MODES=y
@@ -115,10 +138,18 @@ CONFIG_IP_MULTICAST=y
# CONFIG_IP_MROUTE is not set
CONFIG_IP_ALIAS=y
CONFIG_SYN_COOKIES=y
+
+#
+# (it is safe to leave these untouched)
+#
CONFIG_SKB_LARGE=y
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
+
+#
+#
+#
# CONFIG_IPX is not set
CONFIG_ATALK=m
# CONFIG_DECNET is not set
@@ -140,11 +171,19 @@ CONFIG_ATALK=m
# SCSI support
#
CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
CONFIG_BLK_DEV_SD=y
CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
# CONFIG_SCSI_MULTI_LUN is not set
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set
@@ -179,6 +218,7 @@ CONFIG_AIC7XXX_RESET_DELAY=15
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_NCR53C8XX is not set
CONFIG_SCSI_SYM53C8XX=y
@@ -226,17 +266,22 @@ CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
CONFIG_MACE=y
CONFIG_BMAC=y
+# CONFIG_NCR885E is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_YELLOWFIN is not set
# CONFIG_RTL8139 is not set
# CONFIG_SIS900 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_ACENIC is not set
+# CONFIG_DM9102 is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
CONFIG_NET_EISA=y
CONFIG_PCNET32=y
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_ACENIC is not set
# CONFIG_AC3200 is not set
# CONFIG_APRICOT is not set
# CONFIG_CS89x0 is not set
@@ -252,7 +297,6 @@ CONFIG_DE4X5=y
# CONFIG_ES3210 is not set
# CONFIG_EPIC100 is not set
# CONFIG_ZNET is not set
-# CONFIG_ADAPTEC_STARFIRE is not set
# CONFIG_NET_POCKET is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -265,13 +309,18 @@ CONFIG_DE4X5=y
# CONFIG_IPDDP is not set
CONFIG_PPP=y
# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
# CONFIG_PPP_DEFLATE is not set
# CONFIG_PPP_BSDCOMP is not set
# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
# CONFIG_NET_RADIO is not set
#
-# Token ring devices
+# Token Ring driver support
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
@@ -281,17 +330,7 @@ CONFIG_PPP=y
#
# Wan interfaces
#
-# CONFIG_HOSTESS_SV11 is not set
-# CONFIG_COSA is not set
-# CONFIG_SEALEVEL_4021 is not set
-# CONFIG_DLCI is not set
-
-#
-# PCMCIA network devices
-#
-# CONFIG_PCMCIA_PCNET is not set
-# CONFIG_PCMCIA_3C589 is not set
-# CONFIG_PCMCIA_RAYCS is not set
+# CONFIG_WAN is not set
#
# Amateur Radio support
@@ -311,6 +350,11 @@ CONFIG_PPP=y
#
# Console drivers
#
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
CONFIG_DUMMY_CONSOLE=y
# CONFIG_FB_CLGEN is not set
# CONFIG_FB_PM2 is not set
@@ -328,6 +372,8 @@ CONFIG_FB_MATROX_MYSTIQUE=y
CONFIG_FB_MATROX_G100=y
# CONFIG_FB_MATROX_MULTIHEAD is not set
CONFIG_FB_ATY=y
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_3DFX is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FBCON_ADVANCED is not set
CONFIG_FBCON_CFB8=y
@@ -362,7 +408,7 @@ CONFIG_BUSMOUSE=y
# CONFIG_ATIXL_BUSMOUSE is not set
# CONFIG_LOGIBUSMOUSE is not set
# CONFIG_MS_BUSMOUSE is not set
-# CONFIG_ADB_MOUSE is not set
+# CONFIG_ADBMOUSE is not set
CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
@@ -403,11 +449,11 @@ CONFIG_NVRAM=y
CONFIG_AUTOFS_FS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
+CONFIG_HFS_FS=y
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_VFAT_FS=y
# CONFIG_EFS_FS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
@@ -420,6 +466,7 @@ CONFIG_DEVPTS_FS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
+# CONFIG_BFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
@@ -446,7 +493,39 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
#
# Sound
@@ -463,27 +542,27 @@ CONFIG_DMASOUND=y
# CONFIG_SOUND_MSNDPIN is not set
CONFIG_SOUND_OSS=y
# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+CONFIG_SOUND_CS4232=m
# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_SB is not set
# CONFIG_SOUND_WAVEFRONT is not set
-CONFIG_SOUND_CS4232=m
-# CONFIG_SOUND_OPL3SA2 is not set
# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_VIA82CXXX is not set
# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
# CONFIG_SOUND_UART6850 is not set
#
diff --git a/arch/ppc/config.in b/arch/ppc/config.in
index 46908b644..325935ffe 100644
--- a/arch/ppc/config.in
+++ b/arch/ppc/config.in
@@ -5,6 +5,11 @@
mainmenu_name "Linux/PowerPC Kernel Configuration"
mainmenu_option next_comment
+comment 'Code maturity level options'
+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+endmenu
+
+mainmenu_option next_comment
comment 'Platform support'
define_bool CONFIG_PPC y
choice 'Processor type' \
@@ -39,6 +44,10 @@ else
fi
bool 'Symmetric multi-processing support' CONFIG_SMP
+if [ "$CONFIG_6xx" = "y" ];then
+ bool 'AltiVec Support' CONFIG_ALTIVEC
+fi
+
if [ "$CONFIG_ALL_PPC" != "y" ];then
define_bool CONFIG_MACH_SPECIFIC y
fi
@@ -53,14 +62,16 @@ fi
endmenu
mainmenu_option next_comment
-comment 'General setup'
-
-bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
+comment 'Loadable module support'
bool 'Enable loadable module support' CONFIG_MODULES
if [ "$CONFIG_MODULES" = "y" ]; then
- bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
- bool 'Kernel module loader' CONFIG_KMOD
+ bool ' Set version information on all module symbols' CONFIG_MODVERSIONS
+ bool ' Kernel module loader' CONFIG_KMOD
fi
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
if [ "$CONFIG_APUS" = "y" ]; then
define_bool CONFIG_PCI n
@@ -78,6 +89,9 @@ bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
# only elf supported, a.out is not -- Cort
+if [ "$CONFIG_PROC_FS" = "y" ]; then
+ define_bool CONFIG_KCORE_ELF y
+fi
define_bool CONFIG_BINFMT_ELF y
define_bool CONFIG_KERNEL_ELF y
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig
index cebd77dfe..8b232d723 100644
--- a/arch/ppc/defconfig
+++ b/arch/ppc/defconfig
@@ -3,6 +3,11 @@
#
#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
# Platform support
#
CONFIG_PPC=y
@@ -10,34 +15,25 @@ CONFIG_6xx=y
# CONFIG_PPC64 is not set
# CONFIG_82xx is not set
# CONFIG_8xx is not set
-# CONFIG_MPC821 is not set
-# CONFIG_MPC823 is not set
-# CONFIG_MPC850 is not set
-# CONFIG_MPC855 is not set
-# CONFIG_MPC860 is not set
-# CONFIG_MPC860T is not set
-# CONFIG_RPXLITE is not set
-# CONFIG_RPXCLASSIC is not set
-# CONFIG_BSEIP is not set
-# CONFIG_MBX is not set
-# CONFIG_WINCEPT is not set
# CONFIG_PMAC is not set
# CONFIG_PREP is not set
# CONFIG_CHRP is not set
-# CONFIG_ALL_PPC is not set
-CONFIG_GEMINI=y
+CONFIG_ALL_PPC=y
+# CONFIG_GEMINI is not set
# CONFIG_APUS is not set
# CONFIG_SMP is not set
-CONFIG_MACH_SPECIFIC=y
CONFIG_6xx=y
#
-# General setup
+# Loadable module support
#
-CONFIG_EXPERIMENTAL=y
CONFIG_MODULES=y
CONFIG_MODVERSIONS=y
CONFIG_KMOD=y
+
+#
+# General setup
+#
CONFIG_PCI=y
CONFIG_NET=y
CONFIG_SYSCTL=y
@@ -46,17 +42,28 @@ CONFIG_SYSVIPC=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
# CONFIG_BINFMT_MISC is not set
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
# CONFIG_PARPORT is not set
-# CONFIG_VGA_CONSOLE is not set
-# CONFIG_FB is not set
-# CONFIG_PMAC_PBOOK is not set
-# CONFIG_MAC_FLOPPY is not set
-# CONFIG_MAC_SERIAL is not set
-# CONFIG_ADB is not set
-# CONFIG_PROC_DEVICETREE is not set
+CONFIG_VGA_CONSOLE=y
+CONFIG_FB=y
+CONFIG_FB_COMPAT_XPMAC=y
+CONFIG_PMAC_PBOOK=y
+CONFIG_MAC_FLOPPY=y
+CONFIG_MAC_SERIAL=y
+CONFIG_ADB=y
+CONFIG_ADB_CUDA=y
+CONFIG_ADB_MACIO=y
+CONFIG_ADB_PMU=y
+CONFIG_ADB_KEYBOARD=y
+CONFIG_PROC_DEVICETREE=y
# CONFIG_TOTALMP is not set
-# CONFIG_BOOTX_TEXT is not set
+CONFIG_BOOTX_TEXT=y
# CONFIG_MOTOROLA_HOTSWAP is not set
+# CONFIG_CMDLINE_BOOL is not set
#
# Plug and Play configuration
@@ -66,26 +73,48 @@ CONFIG_KERNEL_ELF=y
#
# Block devices
#
-# CONFIG_BLK_DEV_FD is not set
-# CONFIG_BLK_DEV_IDE is not set
+CONFIG_BLK_DEV_FD=y
+CONFIG_BLK_DEV_IDE=y
#
# Please see Documentation/ide.txt for help/info on IDE drives
#
-# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_DEV_HD_IDE is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI is not set
+CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_IDE_PMAC=y
+CONFIG_BLK_DEV_IDEDMA_PMAC=y
+CONFIG_IDEDMA_PMAC_AUTO=y
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDE_CHIPSETS is not set
# CONFIG_BLK_CPQ_DA is not set
#
# Additional Block Devices
#
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_NBD is not set
# CONFIG_BLK_DEV_MD is not set
-# CONFIG_BLK_DEV_RAM is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
CONFIG_PARIDE_PARPORT=y
# CONFIG_PARIDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
+CONFIG_BLK_DEV_IDE_MODES=y
# CONFIG_BLK_DEV_HD is not set
#
@@ -122,7 +151,7 @@ CONFIG_SKB_LARGE=y
#
#
# CONFIG_IPX is not set
-# CONFIG_ATALK is not set
+CONFIG_ATALK=m
# CONFIG_DECNET is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
@@ -147,7 +176,7 @@ CONFIG_SCSI=y
# SCSI support type (disk, tape, CD-ROM)
#
CONFIG_BLK_DEV_SD=y
-# CONFIG_CHR_DEV_ST is not set
+CONFIG_CHR_DEV_ST=y
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
# CONFIG_CHR_DEV_SG is not set
@@ -167,7 +196,11 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_AHA152X is not set
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
-# CONFIG_SCSI_AIC7XXX is not set
+CONFIG_SCSI_AIC7XXX=y
+# CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT is not set
+CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
+CONFIG_AIC7XXX_PROC_STATS=y
+CONFIG_AIC7XXX_RESET_DELAY=15
# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
@@ -181,12 +214,11 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_GENERIC_NCR5380 is not set
-# CONFIG_SCSI_G_NCR5380_PORT is not set
-# CONFIG_SCSI_G_NCR5380_MEM is not set
# CONFIG_SCSI_INITIO is not set
# CONFIG_SCSI_INIA100 is not set
# CONFIG_SCSI_NCR53C406A is not set
# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_NCR53C8XX is not set
CONFIG_SCSI_SYM53C8XX=y
@@ -210,8 +242,9 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_ULTRASTOR is not set
# CONFIG_SCSI_DEBUG is not set
-# CONFIG_SCSI_MESH is not set
-# CONFIG_SCSI_MAC53C94 is not set
+CONFIG_SCSI_MESH=y
+CONFIG_SCSI_MESH_SYNC_RATE=5
+CONFIG_SCSI_MAC53C94=y
#
# Network device support
@@ -231,28 +264,63 @@ CONFIG_NETDEVICES=y
# Ethernet (10 or 100Mbit)
#
CONFIG_NET_ETHERNET=y
-# CONFIG_MACE is not set
-# CONFIG_BMAC is not set
-CONFIG_NCR885E=y
+CONFIG_MACE=y
+CONFIG_BMAC=y
+# CONFIG_NCR885E is not set
# CONFIG_NET_VENDOR_3COM is not set
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_YELLOWFIN is not set
# CONFIG_RTL8139 is not set
# CONFIG_SIS900 is not set
-# CONFIG_YELLOWFIN is not set
-# CONFIG_ACENIC is not set
+# CONFIG_DM9102 is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
-# CONFIG_NET_EISA is not set
+CONFIG_NET_EISA=y
+CONFIG_PCNET32=y
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_ACENIC is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_CS89x0 is not set
+CONFIG_DE4X5=y
+# CONFIG_DEC_ELCP is not set
+# CONFIG_DGRS is not set
+# CONFIG_EEXPRESS_PRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_NE3210 is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_TLAN is not set
+# CONFIG_VIA_RHINE is not set
+# CONFIG_ES3210 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_ZNET is not set
# CONFIG_NET_POCKET is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
-# CONFIG_PPP is not set
+
+#
+# Appletalk devices
+#
+# CONFIG_LTPC is not set
+# CONFIG_COPS is not set
+# CONFIG_IPDDP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
# CONFIG_NET_RADIO is not set
#
-# Token ring devices
+# Token Ring driver support
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
@@ -262,10 +330,7 @@ CONFIG_NCR885E=y
#
# Wan interfaces
#
-# CONFIG_HOSTESS_SV11 is not set
-# CONFIG_COSA is not set
-# CONFIG_SEALEVEL_4021 is not set
-# CONFIG_DLCI is not set
+# CONFIG_WAN is not set
#
# Amateur Radio support
@@ -287,12 +352,50 @@ CONFIG_NCR885E=y
#
#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+CONFIG_FB_OF=y
+CONFIG_FB_CONTROL=y
+CONFIG_FB_PLATINUM=y
+CONFIG_FB_VALKYRIE=y
+CONFIG_FB_IMSTT=y
+CONFIG_FB_CT65550=y
+# CONFIG_FB_S3TRIO is not set
+# CONFIG_FB_VGA16 is not set
+CONFIG_FB_MATROX=y
+# CONFIG_FB_MATROX_MILLENIUM is not set
+CONFIG_FB_MATROX_MYSTIQUE=y
+CONFIG_FB_MATROX_G100=y
+# CONFIG_FB_MATROX_MULTIHEAD is not set
+CONFIG_FB_ATY=y
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+CONFIG_FBCON_CFB32=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+CONFIG_FBCON_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+CONFIG_FONT_SUN8x16=y
+CONFIG_FONT_SUN12x22=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
# Character devices
#
CONFIG_VT=y
CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=y
-CONFIG_SERIAL_CONSOLE=y
+CONFIG_SERIAL=m
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
CONFIG_UNIX98_PTYS=y
@@ -305,13 +408,14 @@ CONFIG_BUSMOUSE=y
# CONFIG_ATIXL_BUSMOUSE is not set
# CONFIG_LOGIBUSMOUSE is not set
# CONFIG_MS_BUSMOUSE is not set
+# CONFIG_ADBMOUSE is not set
CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
# CONFIG_QIC02_TAPE is not set
# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
+CONFIG_NVRAM=y
# CONFIG_RTC is not set
#
@@ -331,14 +435,6 @@ CONFIG_PSMOUSE=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_FT_NORMAL_DEBUG is not set
-# CONFIG_FT_FULL_DEBUG is not set
-# CONFIG_FT_NO_TRACE is not set
-# CONFIG_FT_NO_TRACE_AT_ALL is not set
-# CONFIG_FT_STD_FDC is not set
-# CONFIG_FT_MACH2 is not set
-# CONFIG_FT_PROBE_FC10 is not set
-# CONFIG_FT_ALT_FDC is not set
# CONFIG_DRM is not set
#
@@ -350,11 +446,14 @@ CONFIG_PSMOUSE=y
# Filesystems
#
# CONFIG_QUOTA is not set
-# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS_FS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
-# CONFIG_FAT_FS is not set
+CONFIG_HFS_FS=y
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
# CONFIG_EFS_FS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
@@ -367,6 +466,7 @@ CONFIG_DEVPTS_FS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
+# CONFIG_BFS_FS is not set
# CONFIG_SYSV_FS is not set
# CONFIG_UFS_FS is not set
@@ -374,10 +474,11 @@ CONFIG_EXT2_FS=y
# Network File Systems
#
# CONFIG_CODA_FS is not set
-# CONFIG_NFS_FS is not set
-# CONFIG_NFSD is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_LOCKD is not set
+CONFIG_NFS_FS=y
+CONFIG_NFSD=y
+# CONFIG_NFSD_SUN is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
@@ -392,16 +493,86 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
-# CONFIG_NLS is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+# CONFIG_NLS_CODEPAGE_437 is not set
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_1 is not set
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
#
# Sound
#
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+CONFIG_DMASOUND=y
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+CONFIG_SOUND_OSS=y
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+CONFIG_SOUND_CS4232=m
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_UART6850 is not set
+
+#
+# Additional low level sound drivers
+#
+# CONFIG_LOWLEVEL_SOUND is not set
#
# Kernel hacking
#
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
# CONFIG_KGDB is not set
-# CONFIG_XMON is not set
+CONFIG_XMON=y
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 2f190db09..3677276b5 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -60,15 +60,12 @@ ifdef CONFIG_MBX
O_OBJS += i8259.o
endif
else
-ifeq ($(CONFIG_APUS),y)
-O_OBJS += apus_setup.o prom.o open_pic.o
-else
-ifneq ($(CONFIG_8xx),y)
O_OBJS += chrp_setup.o chrp_pci.o chrp_time.o \
pmac_time.o pmac_pci.o pmac_setup.o \
prom.o open_pic.o feature.o \
i8259.o pmac_pic.o indirect_pci.o \
gemini_pci.o gemini_prom.o gemini_setup.o
+
ifeq ($(CONFIG_NVRAM),y)
O_OBJS += pmac_support.o
endif
@@ -83,7 +80,8 @@ endif
ifeq ($(CONFIG_PMAC), y)
endif
-endif
+ifdef CONFIG_APUS
+O_OBJS += apus_setup.o
endif
endif
diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c
index 353482a18..a7b057fa1 100644
--- a/arch/ppc/kernel/apus_setup.c
+++ b/arch/ppc/kernel/apus_setup.c
@@ -32,7 +32,10 @@
#include <linux/ide.h>
#define ide_init_hwif_ports m68k_ide_init_hwif_ports
#define ide_default_irq m68k_ide_default_irq
+#undef ide_request_irq
#define ide_request_irq m68k_ide_request_irq
+#undef ide_free_irq
+#define ide_free_irq m68k_ide_free_irq
#define ide_default_io_base m68k_ide_default_io_base
#define ide_check_region m68k_ide_check_region
#define ide_request_region m68k_ide_request_region
@@ -40,7 +43,6 @@
#define ide_fix_driveid m68k_ide_fix_driveid
#define ide_init_default_hwifs m68k_ide_init_default_hwifs
#define select_t m68k_select_t
-#define ide_free_irq m68k_ide_free_irq
//#include <asm/hdreg.h>
#include <asm-m68k/ide.h>
#undef ide_free_irq
@@ -59,6 +61,7 @@
#include <asm/bootinfo.h>
#include <asm/setup.h>
#include <asm/amigahw.h>
+#include <asm/amigaints.h>
#include <asm/amigappc.h>
#include <asm/pgtable.h>
#include <asm/io.h>
@@ -71,6 +74,8 @@
unsigned long m68k_machtype __apusdata;
char debug_device[6] __apusdata = "";
+extern void amiga_init_IRQ(void);
+
void (*mach_sched_init) (void (*handler)(int, void *, struct pt_regs *)) __initdata;
/* machine dependent keyboard functions */
int (*mach_keyb_init) (void) __initdata;
@@ -162,57 +167,6 @@ int apus_set_rtc_time(unsigned long nowtime)
#endif
}
-__apus
-int apus_request_irq(unsigned int irq,
- void (*handler)(int, void *, struct pt_regs *),
- unsigned long flags, const char *devname,
- void *dev_id)
-{
-#ifdef CONFIG_APUS
- extern int amiga_request_irq(unsigned int irq,
- void (*handler)(int, void *,
- struct pt_regs *),
- unsigned long flags,
- const char *devname,
- void *dev_id);
-
- return amiga_request_irq (irq, handler, flags, devname, dev_id);
-#else
- return 0;
-#endif
-}
-
-__apus
-void apus_free_irq(unsigned int irq, void *dev_id)
-{
-#ifdef CONFIG_APUS
- extern void amiga_free_irq(unsigned int irq, void *dev_id);
-
- amiga_free_irq (irq, dev_id);
-#endif
-}
-
-__apus
-void apus_process_int(unsigned long vec, void *fp)
-{
-#ifdef CONFIG_APUS
- extern void process_int(unsigned long vec, struct pt_regs *fp);
-
- process_int (vec, (struct pt_regs*)fp);
-#endif
-}
-
-__apus
-int apus_get_irq_list(char *buf)
-{
-#ifdef CONFIG_APUS
- extern int m68k_get_irq_list (char*);
-
- return m68k_get_irq_list (buf);
-#else
- return 0;
-#endif
-}
/* Here some functions we don't support, but which the other ports reference */
@@ -297,6 +251,7 @@ void __init apus_setup_arch(void)
config_amiga();
+#if 0 /* Enable for logging - also include logging.o in Makefile rule */
{
#define LOG_SIZE 4096
void* base;
@@ -310,6 +265,7 @@ void __init apus_setup_arch(void)
LOG_INIT(base, base+sizeof(klog_data_t), LOG_SIZE);
}
#endif
+#endif
}
__apus
@@ -760,67 +716,122 @@ void apus_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port,
m68k_ide_init_hwif_ports(hw, data_port, ctrl_port, irq);
}
#endif
-/****************************************************** from irq.c */
-#define VEC_SPUR (24)
+/****************************************************** IRQ stuff */
-void
-apus_do_IRQ(struct pt_regs *regs,
- int cpu,
- int isfake)
+__apus
+int apus_get_irq_list(char *buf)
{
- int old_level, new_level;
+#ifdef CONFIG_APUS
+ extern int amiga_get_irq_list(char *buf);
+
+ return amiga_get_irq_list (buf);
+#else
+ return 0;
+#endif
+}
- new_level = (~(regs->mq) >> 3) & IPLEMU_IPLMASK;
-
- if (0 != new_level && 7 != new_level) {
- old_level = ~(regs->mq) & IPLEMU_IPLMASK;
+/* IPL must be between 0 and 7 */
+__apus
+static inline void apus_set_IPL(int ipl)
+{
+ APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
+ APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
+ APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | ((~ipl) & IPLEMU_IPLMASK));
+ APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
+}
- apus_process_int (VEC_SPUR+new_level, regs);
-
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
- APUS_WRITE(APUS_IPL_EMU, (IPLEMU_SETRESET
- | (~(old_level) & IPLEMU_IPLMASK)));
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
- }
+__apus
+static inline unsigned long apus_get_IPL(void)
+{
+ unsigned short __f;
+ APUS_READ(APUS_IPL_EMU, __f);
+ return ((~__f) & IPLEMU_IPLMASK);
}
__apus
-static void apus_save_flags(unsigned long* flags)
+static inline unsigned long apus_get_prev_IPL(void)
{
unsigned short __f;
APUS_READ(APUS_IPL_EMU, __f);
- return ((~__f) & IPLEMU_IPLMASK) << 8;
+ return ((~__f >> 3) & IPLEMU_IPLMASK);
+}
+
+
+__apus
+static void apus_save_flags(unsigned long* flags)
+{
+ *flags = apus_get_IPL();
}
__apus
static void apus_restore_flags(unsigned long flags)
{
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET
- | (~(flags >> 8) & IPLEMU_IPLMASK));
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
+ apus_set_IPL(flags);
}
__apus
static void apus_sti(void)
{
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_IPLMASK);
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
+ apus_set_IPL(0);
}
__apus
static void apus_cli(void)
{
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT);
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK);
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET);
- APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT);
+ apus_set_IPL(7);
+}
+
+
+#ifdef CONFIG_APUS
+void free_irq(unsigned int irq, void *dev_id)
+{
+ extern void amiga_free_irq(unsigned int irq, void *dev_id);
+
+ amiga_free_irq (irq, dev_id);
+}
+
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+ unsigned long irqflags, const char * devname, void *dev_id)
+{
+ extern int amiga_request_irq(unsigned int irq,
+ void (*handler)(int, void *,
+ struct pt_regs *),
+ unsigned long flags,
+ const char *devname,
+ void *dev_id);
+
+ return amiga_request_irq (irq, handler, irqflags, devname, dev_id);
+}
+#endif
+
+__apus
+int apus_get_irq(struct pt_regs* regs)
+{
+#ifdef CONFIG_APUS
+ int level = apus_get_IPL();
+ unsigned short ints = custom.intreqr & custom.intenar;
+
+ if (0 == level)
+ return -1;
+ if (7 == level)
+ return -2;
+
+ return level;
+#else
+ return 0;
+#endif
+}
+
+
+__apus
+void apus_post_irq(int level)
+{
+ /* Restore IPL to the previous value */
+ apus_set_IPL(apus_get_IPL());
}
+
+
/****************************************************** keyboard */
__apus
static int apus_kbd_setkeycode(unsigned int scancode, unsigned int keycode)
@@ -859,36 +870,54 @@ static void apus_kbd_init_hw(void)
#ifdef CONFIG_APUS
extern int amiga_keyb_init(void);
-printk("**** " __FUNCTION__ "\n");
amiga_keyb_init();
#endif
}
/****************************************************** init */
-extern void amiga_disable_irq(unsigned int irq);
-extern void amiga_enable_irq(unsigned int irq);
-extern void m68k_init_IRQ (void);
-
-struct hw_interrupt_type amiga_irq_ctl = {
- " Amiga ",
- NULL,
- NULL,
- NULL,
- amiga_enable_irq,
- amiga_disable_irq,
- NULL,
- 0
+
+/* The number of spurious interrupts */
+volatile unsigned int num_spurious;
+
+#define NUM_IRQ_NODES 100
+static irq_node_t nodes[NUM_IRQ_NODES];
+
+extern void (*amiga_default_handler[AUTO_IRQS])(int, void *, struct pt_regs *);
+
+static const char *default_names[SYS_IRQS] = {
+ "spurious int", "int1 handler", "int2 handler", "int3 handler",
+ "int4 handler", "int5 handler", "int6 handler", "int7 handler"
};
+irq_node_t *new_irq_node(void)
+{
+ irq_node_t *node;
+ short i;
+
+ for (node = nodes, i = NUM_IRQ_NODES-1; i >= 0; node++, i--)
+ if (!node->handler)
+ return node;
+
+ printk ("new_irq_node: out of nodes\n");
+ return NULL;
+}
+
__init
void apus_init_IRQ(void)
{
int i;
- for (i = 0; i < NR_IRQS; i++)
- irq_desc[i].ctl = &amiga_irq_ctl;
- m68k_init_IRQ ();
+ for (i = 0; i < NUM_IRQ_NODES; i++)
+ nodes[i].handler = NULL;
+
+ for (i = 0; i < AUTO_IRQS; i++) {
+ if (amiga_default_handler[i] != NULL)
+ sys_request_irq(i, amiga_default_handler[i],
+ 0, default_names[i], NULL);
+ }
+
+ amiga_init_IRQ();
int_control.int_sti = apus_sti;
int_control.int_cli = apus_cli;
@@ -924,7 +953,8 @@ void apus_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.get_cpuinfo = apus_get_cpuinfo;
ppc_md.irq_cannonicalize = NULL;
ppc_md.init_IRQ = apus_init_IRQ;
- ppc_md.do_IRQ = apus_do_IRQ;
+ ppc_md.get_irq = apus_get_irq;
+ ppc_md.post_irq = apus_post_irq;
#ifdef CONFIG_HEARTBEAT
ppc_md.heartbeat = apus_heartbeat;
ppc_md.heartbeat_count = 1;
@@ -969,3 +999,9 @@ void apus_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_ide_md.io_base = _IO_BASE;
#endif
}
+
+
+/*************************************************** coexistence */
+void __init adbdev_init(void)
+{
+}
diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c
index e70ba4dca..938cea36d 100644
--- a/arch/ppc/kernel/chrp_setup.c
+++ b/arch/ppc/kernel/chrp_setup.c
@@ -11,7 +11,6 @@
*/
#include <linux/config.h>
-#include <linux/module.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -576,9 +575,10 @@ void __init
ppc_md.calibrate_decr = chrp_calibrate_decr;
#ifdef CONFIG_VT
-#ifdef CONFIG_MAC_KEYBOAD
+#ifdef CONFIG_MAC_KEYBOARD
if (adb_driver == NULL)
{
+#endif /* CONFIG_MAC_KEYBOAD */
ppc_md.kbd_setkeycode = pckbd_setkeycode;
ppc_md.kbd_getkeycode = pckbd_getkeycode;
ppc_md.kbd_translate = pckbd_translate;
@@ -588,7 +588,8 @@ void __init
#ifdef CONFIG_MAGIC_SYSRQ
ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
SYSRQ_KEY = 0x54;
-#endif
+#endif /* CONFIG_MAGIC_SYSRQ */
+#ifdef CONFIG_MAC_KEYBOARD
}
else
{
@@ -601,24 +602,13 @@ void __init
#ifdef CONFIG_MAGIC_SYSRQ
ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate;
SYSRQ_KEY = 0x69;
-#endif
+#endif /* CONFIG_MAGIC_SYSRQ */
}
-#else
- ppc_md.kbd_setkeycode = pckbd_setkeycode;
- ppc_md.kbd_getkeycode = pckbd_getkeycode;
- ppc_md.kbd_translate = pckbd_translate;
- ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
- ppc_md.kbd_leds = pckbd_leds;
- ppc_md.kbd_init_hw = pckbd_init_hw;
-#ifdef CONFIG_MAGIC_SYSRQ
- ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
- SYSRQ_KEY = 0x54;
-#endif
+#endif /* CONFIG_MAC_KEYBOARD */
+#endif /* CONFIG_VT */
if ( rtas_data )
ppc_md.progress = chrp_progress;
-#endif
-#endif
-
+
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
ppc_ide_md.insw = chrp_ide_insw;
ppc_ide_md.outsw = chrp_ide_outsw;
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 9c940a037..6133f32ca 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -411,9 +411,9 @@ enter_rtas:
addis r7,r7,-KERNELBASE@h
lis r8,rtas_entry@ha
lwz r8,rtas_entry@l(r8)
- addis r5,r8,-KERNELBASE@h
mfmsr r9
stw r9,8(r1)
+ li r0,0
ori r0,r0,MSR_EE|MSR_SE|MSR_BE
andc r0,r9,r0
andi. r9,r9,MSR_ME|MSR_RI
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index b3b07a003..57ff53992 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -365,10 +365,10 @@ InstructionAccess:
/* External interrupt */
. = 0x500;
HardwareInterrupt:
-#ifndef CONFIG_APUS
EXCEPTION_PROLOG;
addi r3,r1,STACK_FRAME_OVERHEAD
li r20,MSR_KERNEL
+#ifndef CONFIG_APUS
li r4,0
bl transfer_to_handler
.globl do_IRQ_intercept
@@ -376,9 +376,6 @@ do_IRQ_intercept:
.long do_IRQ;
.long ret_from_except
#else
- EXCEPTION_PROLOG;
- addi r3,r1,STACK_FRAME_OVERHEAD
- li r20,MSR_KERNEL
bl apus_interrupt_entry
#endif /* CONFIG_APUS */
@@ -447,7 +444,7 @@ SystemCall:
STD_EXCEPTION(0xd00, SingleStep, SingleStepException)
STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
- STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
+ STD_EXCEPTION(0xf20, AltiVec, AltiVecUnavailable)
/*
* Handle TLB miss for instruction on 603/603e.
@@ -807,6 +804,73 @@ KernelFP:
.align 4
/*
+ * Take away the altivec regs.
+ *
+ * For now, ignore the vrsave regs and save them all
+ * -- Cort
+ */
+ .globl giveup_altivec
+giveup_altivec:
+#ifdef CONFIG_ALTIVEC
+ /* check for altivec */
+ mfspr r4,PVR
+ srwi r4,r4,16
+ cmpi 0,r4,12
+ bnelr
+
+ /* enable altivec so we can save */
+ mfmsr r4
+ oris r4,r4,MSR_VEC@h
+ mtmsr r4
+
+ /* make sure our tsk pointer is valid */
+ cmpi 0,r3,0
+ beqlr
+
+ /* save altivec regs */
+ addi r4,r3,THREAD+THREAD_VRSAVE
+ mfspr r5,256 /* vrsave */
+ stw r5,0(r4)
+
+ /* get regs for the task */
+ addi r4,r3,THREAD+PT_REGS
+ /* turn off the altivec bit in the tasks regs */
+ lwz r5,_MSR(r4)
+ lis r6,MSR_VEC@h
+ andi. r5,r5,r6
+ stw r5,_MSR(r4)
+
+ /* we've given up the altivec - clear the pointer */
+ li r3,0
+ lis r4,last_task_used_altivec@h
+ stw r3,last_task_used_altivec@l(r4)
+#endif /* CONFIG_ALTIVEC */
+ blr
+
+ .globl load_up_altivec
+load_up_altivec:
+#ifdef CONFIG_ALTIVEC
+ /* check for altivec */
+ mfspr r4,PVR
+ srwi r4,r4,16
+ cmpi 0,r4,12
+ bnelr
+
+ /* restore altivec regs */
+ addi r4,r3,THREAD+THREAD_VRSAVE
+ lwz r5,0(r4)
+ mtspr 256,r5 /* vrsave */
+
+ /* get regs for the task */
+ addi r4,r3,THREAD+PT_REGS
+ /* turn on the altivec bit in the tasks regs */
+ lwz r5,_MSR(r4)
+ oris r5,r5,MSR_VEC@h
+ stw r5,_MSR(r4)
+#endif /* CONFIG_ALTIVEC */
+ blr
+
+/*
* giveup_fpu(tsk)
* Disable FP for the task given as the argument,
* and save the floating-point registers in its thread_struct.
@@ -957,14 +1021,69 @@ fix_mem_constants:
isync /* No speculative loading until now */
blr
+
+apus_interrupt_entry:
+ /* This is horrible, but there's no way around it. Enable the
+ * data cache so the IRQ hardware register can be accessed
+ * without cache intervention. Then disable interrupts and get
+ * the current emulated m68k IPL value.
+ */
+
+ mfmsr 20
+ xori r20,r20,MSR_DR
+ sync
+ mtmsr r20
+ sync
- /* On APUS the first 0x4000 bytes of the kernel will be mapped
- * at a different physical address than the rest. For this
- * reason, the exception code cannot use relative branches to
- * access the code below.
- */
- . = 0x4000
-#endif
+ lis r4,APUS_IPL_EMU@h
+
+ li r20,(IPLEMU_SETRESET|IPLEMU_DISABLEINT)
+ stb r20,APUS_IPL_EMU@l(r4)
+ eieio
+
+ lbz r3,APUS_IPL_EMU@l(r4)
+
+ li r2,IPLEMU_IPLMASK
+ rlwinm. r20,r3,32-3,29,31
+ bne 2f
+ mr r20,r2 /* lvl7! Need to reset state machine. */
+ b 3f
+2: cmp 0,r20,r2
+ beq 1f
+3: eieio
+ stb r2,APUS_IPL_EMU@l(r4)
+ ori r20,r20,IPLEMU_SETRESET
+ eieio
+ stb r20,APUS_IPL_EMU@l(r4)
+1: eieio
+ li r20,IPLEMU_DISABLEINT
+ stb r20,APUS_IPL_EMU@l(r4)
+
+ /* At this point we could do some magic to avoid the overhead
+ * of calling the C interrupt handler in case of a spurious
+ * interrupt. Could not get a simple hack to work though.
+ */
+
+ mfmsr r20
+ xori r20,r20,MSR_DR
+ sync
+ mtmsr r20
+ sync
+
+ stw r3,(_CCR+4)(r21);
+
+ addi r3,r1,STACK_FRAME_OVERHEAD;
+ li r20,MSR_KERNEL;
+ bl transfer_to_handler;
+ .long do_IRQ;
+ .long ret_from_except
+
+/***********************************************************************
+ * Please note that on APUS the exception handlers are located at the
+ * physical address 0xfff0000. For this reason, the exception handlers
+ * cannot use relative branches to access the code below.
+ ***********************************************************************/
+#endif /* CONFIG_APUS */
#ifdef CONFIG_SMP
.globl __secondary_hold
@@ -1165,6 +1284,19 @@ start_here:
bl identify_machine
bl MMU_init
+#ifdef CONFIG_APUS
+ /* Copy exception code to exception vector base on APUS. */
+ lis r4,KERNELBASE@h
+#ifdef CONFIG_APUS_FAST_EXCEPT
+ lis r3,0xfff0 /* Copy to 0xfff00000 */
+#else
+ lis r3,0 /* Copy to 0x00000000 */
+#endif
+ li r5,0x4000 /* # bytes of memory to copy */
+ li r6,0
+ bl copy_and_flush /* copy the first 0x4000 bytes */
+#endif /* CONFIG_APUS */
+
/*
* Go back to running unmapped so we can load up new values
* for SDR1 (hash table pointer) and the segment registers
@@ -1283,3 +1415,4 @@ clear_bats:
mtspr IBAT3L,r20
blr
+
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index d851569d5..4427e801f 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -67,14 +67,6 @@ void disable_irq(unsigned int irq_nr);
volatile unsigned char *chrp_int_ack_special;
-#ifdef CONFIG_APUS
-/* Rename a few functions. Requires the CONFIG_APUS protection. */
-#define request_irq nop_ppc_request_irq
-#define free_irq nop_ppc_free_irq
-#define get_irq_list nop_get_irq_list
-#define VEC_SPUR (24)
-#endif
-
#define MAXCOUNT 10000000
#define NR_MASK_WORDS ((NR_IRQS + 31) / 32)
@@ -94,8 +86,9 @@ atomic_t ppc_n_lost_interrupts;
* this needs to be removed.
* -- Cort
*/
-static char cache_bitmask = 0;
-static struct irqaction malloc_cache[8];
+#define IRQ_KMALLOC_ENTRIES 8
+static int cache_bitmask = 0;
+static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES];
extern int mem_init_done;
void *irq_kmalloc(size_t size, int pri)
@@ -103,7 +96,7 @@ void *irq_kmalloc(size_t size, int pri)
unsigned int i;
if ( mem_init_done )
return kmalloc(size,pri);
- for ( i = 0; i <= 3 ; i++ )
+ for ( i = 0; i < IRQ_KMALLOC_ENTRIES ; i++ )
if ( ! ( cache_bitmask & (1<<i) ) )
{
cache_bitmask |= (1<<i);
@@ -115,7 +108,7 @@ void *irq_kmalloc(size_t size, int pri)
void irq_kfree(void *ptr)
{
unsigned int i;
- for ( i = 0 ; i <= 3 ; i++ )
+ for ( i = 0 ; i < IRQ_KMALLOC_ENTRIES ; i++ )
if ( ptr == &malloc_cache[i] )
{
cache_bitmask &= ~(1<<i);
@@ -124,15 +117,17 @@ void irq_kfree(void *ptr)
kfree(ptr);
}
-#ifndef CONFIG_8xx
-int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
-#else
+#ifdef CONFIG_8xx
/* Name change so we can catch standard drivers that potentially mess up
* the internal interrupt controller on 8xx and 82xx. Just bear with me,
* I don't like this either and I am searching a better solution. For
* now, this is what I need. -- Dan
*/
int request_8xxirq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+#elif defined(CONFIG_APUS)
+int sys_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
+#else
+int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
#endif
unsigned long irqflags, const char * devname, void *dev_id)
{
@@ -191,6 +186,12 @@ int request_8xxirq(unsigned int irq, void (*handler)(int, void *, struct pt_regs
return 0;
}
+#ifdef CONFIG_APUS
+void sys_free_irq(unsigned int irq, void *dev_id)
+{
+ sys_request_irq(irq, NULL, 0, NULL, dev_id);
+}
+#else
void free_irq(unsigned int irq, void *dev_id)
{
#ifndef CONFIG_8xx
@@ -199,6 +200,7 @@ void free_irq(unsigned int irq, void *dev_id)
request_8xxirq(irq, NULL, 0, NULL, dev_id);
#endif
}
+#endif
/* XXX should implement irq disable depth like on intel */
void disable_irq_nosync(unsigned int irq_nr)
@@ -219,6 +221,9 @@ void enable_irq(unsigned int irq_nr)
int get_irq_list(char *buf)
{
+#ifdef CONFIG_APUS
+ return apus_get_irq_list (buf);
+#else
int i, len = 0, j;
struct irqaction * action;
@@ -255,6 +260,7 @@ int get_irq_list(char *buf)
#endif
len += sprintf(buf+len, "BAD: %10u\n", ppc_spurious_interrupts);
return len;
+#endif /* CONFIG_APUS */
}
/*
@@ -266,7 +272,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
int status;
struct irqaction *action;
int cpu = smp_processor_id();
-
+
mask_and_ack_irq(irq);
status = 0;
action = irq_desc[irq].action;
diff --git a/arch/ppc/kernel/mk_defs.c b/arch/ppc/kernel/mk_defs.c
index 38f38ca92..849e268fe 100644
--- a/arch/ppc/kernel/mk_defs.c
+++ b/arch/ppc/kernel/mk_defs.c
@@ -48,6 +48,9 @@ main(void)
DEFINE(NEED_RESCHED, offsetof(struct task_struct, need_resched));
DEFINE(THREAD_FPR0, offsetof(struct thread_struct, fpr[0]));
DEFINE(THREAD_FPSCR, offsetof(struct thread_struct, fpscr));
+ DEFINE(THREAD_VRF, offsetof(struct thread_struct, vrf));
+ DEFINE(THREAD_VSCR, offsetof(struct thread_struct, vscr));
+ DEFINE(THREAD_VRSAVE, offsetof(struct thread_struct, vrsave));
/* Interrupt register frame */
DEFINE(TASK_UNION_SIZE, sizeof(union task_union));
DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c
index 0a23c4473..4c3e9a790 100644
--- a/arch/ppc/kernel/pmac_setup.c
+++ b/arch/ppc/kernel/pmac_setup.c
@@ -39,7 +39,6 @@
#include <linux/ioport.h>
#include <linux/major.h>
#include <linux/blk.h>
-#include <linux/ide.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <linux/ide.h>
@@ -96,6 +95,7 @@ unsigned char drive_info;
int ppc_override_l2cr = 0;
int ppc_override_l2cr_value;
+int has_l2cache = 0;
extern char saved_command_line[];
@@ -147,6 +147,7 @@ pmac_get_cpuinfo(char *buffer)
unsigned int *dc = (unsigned int *)
get_property(np, "d-cache-size", NULL);
len += sprintf(buffer+len, "L2 cache\t:");
+ has_l2cache = 1;
if (get_property(np, "cache-unified", NULL) != 0 && dc) {
len += sprintf(buffer+len, " %dK unified", *dc / 1024);
} else {
@@ -359,7 +360,8 @@ static void __init ohare_init(void)
sysctrl_regs[4] |= 0x04000020;
else
sysctrl_regs[4] |= 0x04000000;
- printk(KERN_INFO "Level 2 cache enabled\n");
+ if(has_l2cache)
+ printk(KERN_INFO "Level 2 cache enabled\n");
}
}
}
diff --git a/arch/ppc/kernel/pmac_support.c b/arch/ppc/kernel/pmac_support.c
index abbec2ee0..cf3d1711a 100644
--- a/arch/ppc/kernel/pmac_support.c
+++ b/arch/ppc/kernel/pmac_support.c
@@ -60,6 +60,7 @@ unsigned char nvram_read_byte(int addr)
struct adb_request req;
switch (nvram_naddrs) {
+#ifdef CONFIG_ADB_PMU
case -1:
if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM,
(addr >> 8) & 0xff, addr & 0xff))
@@ -67,6 +68,7 @@ unsigned char nvram_read_byte(int addr)
while (!req.complete)
pmu_poll();
return req.reply[1];
+#endif
case 1:
return nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult];
case 2:
@@ -82,6 +84,7 @@ void nvram_write_byte(unsigned char val, int addr)
struct adb_request req;
switch (nvram_naddrs) {
+#ifdef CONFIG_ADB_PMU
case -1:
if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM,
(addr >> 8) & 0xff, addr & 0xff, val))
@@ -89,6 +92,7 @@ void nvram_write_byte(unsigned char val, int addr)
while (!req.complete)
pmu_poll();
break;
+#endif
case 1:
nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult] = val;
break;
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 399b99052..7bd21c277 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -209,8 +209,10 @@ EXPORT_SYMBOL(adb_request);
EXPORT_SYMBOL(adb_register);
EXPORT_SYMBOL(cuda_request);
EXPORT_SYMBOL(cuda_poll);
+#ifdef CONFIG_ADB_PMU
EXPORT_SYMBOL(pmu_request);
EXPORT_SYMBOL(pmu_poll);
+#endif /* CONFIG_ADB_PMU */
#endif /* CONFIG_ADB */
#ifdef CONFIG_PMAC_PBOOK
EXPORT_SYMBOL(pmu_register_sleep_notifier);
@@ -266,3 +268,4 @@ EXPORT_SYMBOL(irq_desc);
void ppc_irq_dispatch_handler(struct pt_regs *, int);
EXPORT_SYMBOL(ppc_irq_dispatch_handler);
EXPORT_SYMBOL(decrementer_count);
+EXPORT_SYMBOL(get_wchan);
diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c
index fe7043206..1bfc63c63 100644
--- a/arch/ppc/kernel/prep_setup.c
+++ b/arch/ppc/kernel/prep_setup.c
@@ -210,7 +210,7 @@ no_l2:
}
void __init
-prep_setup_arch()
+prep_setup_arch(void)
{
extern char cmd_line[];
unsigned char reg;
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index d71029b25..adeeefe33 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -45,6 +45,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs);
extern unsigned long _get_SP(void);
struct task_struct *last_task_used_math = NULL;
+struct task_struct *last_task_used_altivec = NULL;
static struct vm_area_struct init_mmap = INIT_MMAP;
static struct fs_struct init_fs = INIT_FS;
static struct files_struct init_files = INIT_FILES;
@@ -60,6 +61,7 @@ struct task_struct *current_set[NR_CPUS] = {&init_task, };
#undef SHOW_TASK_SWITCHES 1
#undef CHECK_STACK 1
+#if defined(CHECK_STACK)
unsigned long
kernel_stack_top(struct task_struct *tsk)
{
@@ -72,28 +74,6 @@ task_top(struct task_struct *tsk)
return ((unsigned long)tsk) + sizeof(struct task_struct);
}
-int
-dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
-{
- if (regs->msr & MSR_FP)
- giveup_fpu(current);
- memcpy(fpregs, &current->thread.fpr[0], sizeof(*fpregs));
- return 1;
-}
-
-void
-enable_kernel_fp(void)
-{
-#ifdef __SMP__
- if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
- giveup_fpu(current);
- else
- giveup_fpu(NULL); /* just enables FP for kernel */
-#else
- giveup_fpu(last_task_used_math);
-#endif /* __SMP__ */
-}
-
/* check to make sure the kernel stack is healthy */
int check_stack(struct task_struct *tsk)
{
@@ -156,6 +136,29 @@ int check_stack(struct task_struct *tsk)
}
return(ret);
}
+#endif /* defined(CHECK_STACK) */
+
+int
+dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs)
+{
+ if (regs->msr & MSR_FP)
+ giveup_fpu(current);
+ memcpy(fpregs, &current->thread.fpr[0], sizeof(*fpregs));
+ return 1;
+}
+
+void
+enable_kernel_fp(void)
+{
+#ifdef __SMP__
+ if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
+ giveup_fpu(current);
+ else
+ giveup_fpu(NULL); /* just enables FP for kernel */
+#else
+ giveup_fpu(last_task_used_math);
+#endif /* __SMP__ */
+}
void
_switch_to(struct task_struct *prev, struct task_struct *new,
@@ -187,12 +190,31 @@ _switch_to(struct task_struct *prev, struct task_struct *new,
* every switch, just a save.
* -- Cort
*/
- if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
+ if ( prev->thread.regs && (prev->thread.regs->msr & MSR_FP) )
giveup_fpu(prev);
-
+ /*
+ * If the previous thread 1) has some altivec regs it wants saved
+ * (has bits in vrsave set) and 2) used altivec in the last quantum
+ * (thus changing altivec regs) then save them.
+ *
+ * On SMP we always save/restore altivec regs just to avoid the
+ * complexity of changing processors.
+ * -- Cort
+ */
+ if ( (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) &&
+ prev->thread.vrsave )
+ giveup_altivec(prev);
+ if ( (new->last_processor != NO_PROC_ID) &&
+ (new->last_processor != new->processor) && new->mm )
+ flush_tlb_mm(new->mm);
prev->last_processor = prev->processor;
current_set[smp_processor_id()] = new;
#endif /* __SMP__ */
+ /* Avoid the trap. On smp this this never happens since
+ * we don't set last_task_used_altivec -- Cort
+ */
+ if ( last_task_used_altivec == new )
+ new->thread.regs->msr |= MSR_VEC;
new_thread = &new->thread;
old_thread = &current->thread;
*last = _switch(old_thread, new_thread);
@@ -213,7 +235,8 @@ void show_regs(struct pt_regs * regs)
printk("TASK = %p[%d] '%s' ",
current, current->pid, current->comm);
printk("Last syscall: %ld ", current->thread.last_syscall);
- printk("\nlast math %p", last_task_used_math);
+ printk("\nlast math %p last altivec %p", last_task_used_math,
+ last_task_used_altivec);
#ifdef __SMP__
printk(" CPU: %d last CPU: %d", current->processor,current->last_processor);
@@ -243,12 +266,16 @@ void exit_thread(void)
{
if (last_task_used_math == current)
last_task_used_math = NULL;
+ if (last_task_used_altivec == current)
+ last_task_used_altivec = NULL;
}
void flush_thread(void)
{
if (last_task_used_math == current)
last_task_used_math = NULL;
+ if (last_task_used_altivec == current)
+ last_task_used_altivec = NULL;
}
void
@@ -305,11 +332,18 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
*/
if (regs->msr & MSR_FP)
giveup_fpu(current);
-
memcpy(&p->thread.fpr, &current->thread.fpr, sizeof(p->thread.fpr));
p->thread.fpscr = current->thread.fpscr;
childregs->msr &= ~MSR_FP;
+ if (regs->msr & MSR_VEC)
+ giveup_altivec(current);
+ if ( p->thread.vrsave )
+ memcpy(&p->thread.vrf, &current->thread.vrf, sizeof(p->thread.vrf));
+ p->thread.vscr = current->thread.vscr;
+ p->thread.vrsave = current->thread.vrsave;
+ childregs->msr &= ~MSR_VEC;
+
#ifdef __SMP__
p->last_processor = NO_PROC_ID;
#endif /* __SMP__ */
@@ -367,6 +401,8 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
shove_aux_table(sp);
if (last_task_used_math == current)
last_task_used_math = 0;
+ if (last_task_used_altivec == current)
+ last_task_used_altivec = 0;
current->thread.fpscr = 0;
}
@@ -543,3 +579,32 @@ void __init ll_puts(const char *s)
orig_y = y;
}
#endif
+
+/*
+ * 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 ip, sp;
+ unsigned long stack_page = (unsigned long) p;
+ int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+ sp = p->thread.ksp;
+ do {
+ sp = *(unsigned long *)sp;
+ if (sp < stack_page || sp >= stack_page + 8188)
+ return 0;
+ if (count > 0) {
+ ip = *(unsigned long *)(sp + 4);
+ if (ip < first_sched || ip >= last_sched)
+ return ip;
+ }
+ } while (count++ < 16);
+ return 0;
+}
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 8863a9940..2cf9ee714 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -245,6 +245,9 @@ int get_cpuinfo(char *buffer)
case 10:
len += sprintf(len+buffer, "604ev5 (MachV)\n");
break;
+ case 12:
+ len += sprintf(len+buffer, "7400 (G4)\n");
+ break;
case 50:
len += sprintf(len+buffer, "821\n");
case 80:
@@ -386,12 +389,10 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
if ( have_of )
{
-#ifdef CONFIG_MACH_SPECIFIC
/* prom_init has already been called from __start */
if (boot_infos)
relocate_nodes();
finish_device_tree();
-#endif /* CONFIG_MACH_SPECIFIC */
/*
* If we were booted via quik, r3 points to the physical
* address of the command-line parameters.
@@ -447,7 +448,7 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
int_control.int_cli = __no_use_cli;
int_control.int_save_flags = __no_use_save_flags;
int_control.int_restore_flags = __no_use_restore_flags;
-
+
switch (_machine)
{
case _MACH_Pmac:
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 99a9c2bce..07e45db6b 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -129,6 +129,42 @@ MachineCheckException(struct pt_regs *regs)
}
void
+AltiVecUnavailable(struct pt_regs *regs)
+{
+ /*
+ * This should be changed so we don't take a trap if coming
+ * back when last_task_used_altivec == current. We should also
+ * allow the kernel to use the altivec regs on UP to store tasks
+ * regs during switch
+ * -- Cort
+ */
+ if ( regs->msr & MSR_VEC )
+ {
+ show_regs(regs);
+ panic("AltiVec trap with Altivec enabled!\n");
+ }
+
+ if ( !user_mode(regs) )
+ {
+ show_regs(regs);
+ panic("Kernel Used Altivec with MSR_VEC off!\n");
+ }
+
+ if ( last_task_used_altivec != current )
+ {
+ if ( last_task_used_altivec )
+ giveup_altivec(current);
+ load_up_altivec(current);
+ /* on SMP we always save/restore on switch */
+#ifndef __SMP__
+ last_task_used_altivec = current;
+#endif
+ }
+ /* enable altivec for the task on return */
+ regs->msr |= MSR_VEC;
+}
+
+void
UnknownException(struct pt_regs *regs)
{
printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
diff --git a/arch/ppc/lib/checksum.S b/arch/ppc/lib/checksum.S
index 66a2e3aae..5eb60537c 100644
--- a/arch/ppc/lib/checksum.S
+++ b/arch/ppc/lib/checksum.S
@@ -24,6 +24,8 @@
* len is in words and is always >= 5.
*/
_GLOBAL(ip_fast_csum)
+ cmpi 0,r4,0
+ beq 10f
lwz r0,0(r3)
lwzu r5,4(r3)
addi r4,r4,-2
@@ -38,6 +40,8 @@ _GLOBAL(ip_fast_csum)
not r3,r3
srwi r3,r3,16
blr
+10: li r3,0
+ blr
/*
* Compute checksum of TCP or UDP pseudo-header:
diff --git a/arch/ppc/mm/extable.c b/arch/ppc/mm/extable.c
index afcf705e1..dc57bf868 100644
--- a/arch/ppc/mm/extable.c
+++ b/arch/ppc/mm/extable.c
@@ -43,13 +43,18 @@ search_exception_table(unsigned long addr)
#else
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
+ read_lock(&modlist_lock);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (mp->ex_table_start == NULL)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr);
- if (ret) return ret;
+ if (ret) {
+ read_unlock(&modlist_lock);
+ return ret;
+ }
}
+ read_unlock(&modlist_lock);
#endif
return 0;
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 34a32fe8c..025145d71 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -348,7 +348,7 @@ void si_meminfo(struct sysinfo *val)
i = max_mapnr;
val->totalram = 0;
val->sharedram = 0;
- val->freeram = nr_free_pages << PAGE_SHIFT;
+ val->freeram = nr_free_pages();
val->bufferram = atomic_read(&buffermem_pages);
while (i-- > 0) {
if (PageReserved(mem_map+i))
@@ -1215,8 +1215,6 @@ void __init paging_init(void)
*/
empty_bad_page = alloc_bootmem_pages(PAGE_SIZE);
empty_bad_page_table = alloc_bootmem_pages(PAGE_SIZE);
-
- free_area_init(max_low_pfn);
}
void __init mem_init(void)
@@ -1381,7 +1379,7 @@ unsigned long __init *gemini_find_end_of_memory(void)
set_phys_avail();
return ret;
}
-#endif /* defined(CONFIG_GEMINI) || defined(CONFIG_ALL_PPC) */
+#endif /* defined(CONFIG_GEMINI) */
#ifdef CONFIG_APUS
#define HARDWARE_MAPPED_SIZE (512*1024)
diff --git a/arch/sh/Makefile b/arch/sh/Makefile
index ae76ea1eb..31fcf5d69 100644
--- a/arch/sh/Makefile
+++ b/arch/sh/Makefile
@@ -1,4 +1,4 @@
-# $Id$
+# $Id: Makefile,v 1.1 1999/09/18 16:55:51 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
diff --git a/arch/sh/config.in b/arch/sh/config.in
index 516dc3748..6471e7aa8 100644
--- a/arch/sh/config.in
+++ b/arch/sh/config.in
@@ -11,9 +11,22 @@ endmenu
mainmenu_option next_comment
comment 'Processor type and features'
-choice 'Processor family' \
- "SH-3 CONFIG_CPU_SH3 \
- SH-4 CONFIG_CPU_SH4" SH-3
+choice 'Processor type' \
+ "SH7708 CONFIG_CPU_SUBTYPE_SH7708 \
+ SH7709 CONFIG_CPU_SUBTYPE_SH7709 \
+ SH7750 CONFIG_CPU_SUBTYPE_SH7750" SH7708
+if [ "$CONFIG_CPU_SUBTYPE_SH7708" = "y" ]; then
+ define_bool CONFIG_CPU_SH3 y
+ define_bool CONFIG_CPU_SH4 n
+fi
+if [ "$CONFIG_CPU_SUBTYPE_SH7709" = "y" ]; then
+ define_bool CONFIG_CPU_SH3 y
+ define_bool CONFIG_CPU_SH4 n
+fi
+if [ "$CONFIG_CPU_SUBTYPE_SH7750" = "y" ]; then
+ define_bool CONFIG_CPU_SH3 n
+ define_bool CONFIG_CPU_SH4 y
+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
@@ -35,6 +48,12 @@ 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
@@ -61,6 +80,10 @@ endmenu
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
+ mainmenu_option next_comment
+ comment 'Network device drivers'
+ source drivers/net/Config.in
+ endmenu
fi
mainmenu_option next_comment
diff --git a/arch/sh/defconfig b/arch/sh/defconfig
index dcf006a15..6a65ad411 100644
--- a/arch/sh/defconfig
+++ b/arch/sh/defconfig
@@ -10,10 +10,14 @@
#
# Processor type and features
#
-# CONFIG_CPU_SH3 is not set
-CONFIG_CPU_SH4=y
+CONFIG_CPU_SUBTYPE_SH7708=y
+# CONFIG_CPU_SUBTYPE_SH7709 is not set
+# CONFIG_CPU_SUBTYPE_SH7750 is not set
+CONFIG_CPU_SH3=y
+# CONFIG_CPU_SH4 is not set
CONFIG_LITTLE_ENDIAN=y
-CONFIG_MEMORY_START=08000000
+CONFIG_MEMORY_START=0c000000
+CONFIG_SH_CPU_RTC=y
#
# Loadable module support
@@ -27,6 +31,8 @@ CONFIG_MEMORY_START=08000000
# CONFIG_SYSVIPC is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_SYSCTL is not set
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
@@ -35,8 +41,8 @@ CONFIG_BINFMT_ELF=y
#
# CONFIG_SERIAL is not set
CONFIG_SERIAL_CONSOLE=y
-# CONFIG_SH_SCI_SERIAL is not set
-CONFIG_SH_SCIF_SERIAL=y
+CONFIG_SH_SCI_SERIAL=y
+# CONFIG_SH_SCIF_SERIAL is not set
#
# Floppy, IDE, and other block devices
@@ -59,9 +65,6 @@ CONFIG_BLK_DEV_INITRD=y
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
# CONFIG_FAT_FS is not set
-# CONFIG_MSDOS_FS is not set
-# CONFIG_UMSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
# CONFIG_UDF_FS is not set
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index ac5a075c0..a3e5a918c 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: entry.S,v 1.19 1999/10/31 13:19:35 gniibe Exp gniibe $
*
* linux/arch/sh/entry.S
*
@@ -61,7 +61,11 @@ ENOSYS = 38
#if defined(__sh3__)
TRA = 0xffffffd0
EXPEVT = 0xffffffd4
+#ifdef CONFIG_CPU_SUBTYPE_SH7709
+INTEVT = 0xa4000000 ! INTEVTE2(0xa4000000)
+#else
INTEVT = 0xffffffd8
+#endif
MMU_TEA = 0xfffffffc ! TLB Exception Address Register
#elif defined(__SH4__)
TRA = 0xff000020
@@ -251,6 +255,11 @@ system_call:
mov.l 1f,r2
mov.l @r2,r8
!
+ ! DEBUG DEBUG
+ ! mov.l led,r1
+ ! mov r0,r2
+ ! mov.b r2,@r1
+ !
#ifdef CONFIG_DEBUG_KERNEL_WITH_GDB_STUB
mov #0x20,r1
extu.b r1,r1
@@ -320,6 +329,7 @@ system_call:
3: .long SYMBOL_NAME(syscall_trace)
2: .long 0xefffffff ! BL=0
1: .long TRA
+led: .long 0xa8000000 ! For my board -- gN
.section .fixup,"ax"
fixup_syscall_argerr:
@@ -571,6 +581,37 @@ ENTRY(interrupt_table)
.long SYMBOL_NAME(do_IRQ) ! rovi
.long SYMBOL_NAME(do_IRQ)
.long SYMBOL_NAME(do_IRQ)
+#if defined(CONFIG_CPU_SUBTYPE_SH7709)
+ .long SYMBOL_NAME(do_IRQ) ! 32 IRQ irq0
+ .long SYMBOL_NAME(do_IRQ) ! 33 irq1
+ .long SYMBOL_NAME(do_IRQ) ! 34 irq2
+ .long SYMBOL_NAME(do_IRQ) ! 35 irq3
+ .long SYMBOL_NAME(do_IRQ) ! 36 irq4
+ .long SYMBOL_NAME(do_IRQ) ! 37 irq5
+ .long SYMBOL_NAME(do_IRQ) ! 38
+ .long SYMBOL_NAME(do_IRQ) ! 39
+ .long SYMBOL_NAME(do_IRQ) ! 40 PINT pint0-7
+ .long SYMBOL_NAME(do_IRQ) ! 41 pint8-15
+ .long SYMBOL_NAME(do_IRQ) ! 42
+ .long SYMBOL_NAME(do_IRQ) ! 43
+ .long SYMBOL_NAME(do_IRQ) ! 44
+ .long SYMBOL_NAME(do_IRQ) ! 45
+ .long SYMBOL_NAME(do_IRQ) ! 46
+ .long SYMBOL_NAME(do_IRQ) ! 47
+ .long SYMBOL_NAME(do_IRQ) ! 48 DMAC dei0
+ .long SYMBOL_NAME(do_IRQ) ! 49 dei1
+ .long SYMBOL_NAME(do_IRQ) ! 50 dei2
+ .long SYMBOL_NAME(do_IRQ) ! 51 dei3
+ .long SYMBOL_NAME(do_IRQ) ! 52 IrDA eri1
+ .long SYMBOL_NAME(do_IRQ) ! 53 rxi1
+ .long SYMBOL_NAME(do_IRQ) ! 54 bri1
+ .long SYMBOL_NAME(do_IRQ) ! 55 txi1
+ .long SYMBOL_NAME(do_IRQ) ! 56 SCIF eri2
+ .long SYMBOL_NAME(do_IRQ) ! 57 rxi2
+ .long SYMBOL_NAME(do_IRQ) ! 58 bri2
+ .long SYMBOL_NAME(do_IRQ) ! 59 txi2
+ .long SYMBOL_NAME(do_IRQ) ! 60 ADC adi
+#elif defined(__SH4__)
.long SYMBOL_NAME(do_IRQ) ! Hitachi UDI
.long SYMBOL_NAME(do_IRQ) ! GPIO
.long SYMBOL_NAME(do_IRQ) ! DMAC dmte0
@@ -589,6 +630,7 @@ ENTRY(interrupt_table)
.long error
.long error ! fpu
.long error ! fpu
+#endif
ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/
@@ -608,7 +650,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_mknod)
.long SYMBOL_NAME(sys_chmod) /* 15 */
.long SYMBOL_NAME(sys_lchown)
- .long SYMBOL_NAME(sys_ni_syscall) /* old break syscall holder */
+ .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 */
@@ -622,8 +664,8 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_fstat)
.long SYMBOL_NAME(sys_pause)
.long SYMBOL_NAME(sys_utime) /* 30 */
- .long SYMBOL_NAME(sys_ni_syscall) /* old stty syscall holder */
- .long SYMBOL_NAME(sys_ni_syscall) /* old gtty syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old stty syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old gtty syscall holder */
.long SYMBOL_NAME(sys_access)
.long SYMBOL_NAME(sys_nice)
.long SYMBOL_NAME(sys_ni_syscall) /* 35 */ /* old ftime syscall holder */
@@ -635,7 +677,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_dup)
.long SYMBOL_NAME(sys_pipe)
.long SYMBOL_NAME(sys_times)
- .long SYMBOL_NAME(sys_ni_syscall) /* old prof syscall holder */
+ .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)
@@ -644,12 +686,12 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_getegid) /* 50 */
.long SYMBOL_NAME(sys_acct)
.long SYMBOL_NAME(sys_umount) /* recycled never used phys() */
- .long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */
.long SYMBOL_NAME(sys_ioctl)
.long SYMBOL_NAME(sys_fcntl) /* 55 */
- .long SYMBOL_NAME(sys_ni_syscall) /* old mpx syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old mpx syscall holder */
.long SYMBOL_NAME(sys_setpgid)
- .long SYMBOL_NAME(sys_ni_syscall) /* old ulimit syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old ulimit syscall holder */
.long SYMBOL_NAME(sys_ni_syscall) /* sys_olduname */
.long SYMBOL_NAME(sys_umask) /* 60 */
.long SYMBOL_NAME(sys_chroot)
@@ -689,7 +731,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_fchown) /* 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_ni_syscall) /* old profil syscall holder */
.long SYMBOL_NAME(sys_statfs)
.long SYMBOL_NAME(sys_fstatfs) /* 100 */
.long SYMBOL_NAME(sys_ni_syscall) /* ioperm */
diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S
index 17d019707..f6378927e 100644
--- a/arch/sh/kernel/head.S
+++ b/arch/sh/kernel/head.S
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: head.S,v 1.7 1999/10/27 09:41:42 gniibe Exp gniibe $
*
* arch/sh/kernel/head.S
*
@@ -18,9 +18,8 @@ ENTRY(empty_zero_page)
.long 0 /* RAMDISK_FLAGS */
.long 0x0200 /* ORIG_ROOT_DEV */
.long 1 /* LOADER_TYPE */
- .long 0x88400000 /* INITRD_START */
- .long 0x00400000 /* INITRD_SIZE */
- .long 0x89000000 /* MEMORY_END */
+ .long 0x00360000 /* INITRD_START */
+ .long 0x000a0000 /* INITRD_SIZE */
.long 0
.text
diff --git a/arch/sh/kernel/irq.c b/arch/sh/kernel/irq.c
index 580f4415c..e87972c73 100644
--- a/arch/sh/kernel/irq.c
+++ b/arch/sh/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: irq.c,v 1.4 1999/10/11 13:12:14 gniibe Exp $
*
* linux/arch/sh/kernel/irq.c
*
diff --git a/arch/sh/kernel/irq_onchip.c b/arch/sh/kernel/irq_onchip.c
index 0ed3400ef..f03456bfa 100644
--- a/arch/sh/kernel/irq_onchip.c
+++ b/arch/sh/kernel/irq_onchip.c
@@ -1,8 +1,8 @@
-/* $Id$
+/* $Id: irq_onchip.c,v 1.5 1999/10/28 02:18:33 gniibe Exp $
*
* linux/arch/sh/kernel/irq_onchip.c
*
- * Copyright (C) 1999 Niibe Yutaka
+ * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi
*
* Interrupt handling for on-chip supporting modules (TMU, RTC, etc.).
*
@@ -135,6 +135,109 @@ static void end_onChip_irq(unsigned int irq)
enable_onChip_irq(irq);
}
+
+#ifdef CONFIG_CPU_SUBTYPE_SH7709
+/*
+ * SH7707/SH7709/SH7709A/SH7729 Extended on-chip I/O
+ */
+
+#define INTC_IRR0 0xa4000004UL
+#define INTC_IPRC 0xa4000016UL
+
+#define IRQ0_IRQ 32
+#define IRQ1_IRQ 33
+#define IRQ2_IRQ 34
+#define IRQ3_IRQ 35
+#define IRQ4_IRQ 36
+#define IRQ5_IRQ 37
+
+#define IRQ0_IRP_OFFSET 32
+#define IRQ1_IRP_OFFSET 36
+#define IRQ2_IRP_OFFSET 40
+#define IRQ3_IRP_OFFSET 44
+#define IRQ4_IRP_OFFSET 48
+#define IRQ5_IRP_OFFSET 52
+
+#define IRQ0_PRIORITY 1
+#define IRQ1_PRIORITY 1
+#define IRQ2_PRIORITY 1
+#define IRQ3_PRIORITY 1
+#define IRQ4_PRIORITY 1
+#define IRQ5_PRIORITY 1
+
+static void enable_onChip2_irq(unsigned int irq);
+void disable_onChip2_irq(unsigned int irq);
+
+/* shutdown is same as "disable" */
+#define shutdown_onChip2_irq disable_onChip2_irq
+
+static void mask_and_ack_onChip2(unsigned int);
+static void end_onChip2_irq(unsigned int irq);
+
+static unsigned int startup_onChip2_irq(unsigned int irq)
+{
+ enable_onChip2_irq(irq);
+ return 0; /* never anything pending */
+}
+
+static struct hw_interrupt_type onChip2_irq_type = {
+ "SH7709 Extended On-Chip Supporting Module",
+ startup_onChip2_irq,
+ shutdown_onChip2_irq,
+ enable_onChip2_irq,
+ disable_onChip2_irq,
+ mask_and_ack_onChip2,
+ end_onChip2_irq
+};
+
+void disable_onChip2_irq(unsigned int irq)
+{
+ unsigned long val, flags;
+ /* Set priority in IPR to 0 */
+ int offset = ipr_data[irq-TIMER_IRQ].offset - 32;
+ unsigned long intc_ipr_address = INTC_IPRC + (offset/16*INTC_SIZE);
+ unsigned short mask = 0xffff ^ (0xf << (offset%16));
+
+ save_and_cli(flags);
+ val = ctrl_inw(intc_ipr_address);
+ val &= mask;
+ ctrl_outw(val, intc_ipr_address);
+ restore_flags(flags);
+}
+
+static void enable_onChip2_irq(unsigned int irq)
+{
+ unsigned long val, flags;
+ /* Set priority in IPR back to original value */
+ int offset = ipr_data[irq-TIMER_IRQ].offset - 32;
+ int priority = ipr_data[irq-TIMER_IRQ].priority;
+ unsigned long intc_ipr_address = INTC_IPRC + (offset/16*INTC_SIZE);
+ unsigned short value = (priority << (offset%16));
+
+ save_and_cli(flags);
+ val = ctrl_inw(intc_ipr_address);
+ val |= value;
+ ctrl_outw(val, intc_ipr_address);
+ restore_flags(flags);
+}
+
+static void mask_and_ack_onChip2(unsigned int irq)
+{
+ disable_onChip2_irq(irq);
+ if (IRQ0_IRQ <= irq && irq <= IRQ5_IRQ) {
+ /* Clear external interrupt request */
+ int a = ctrl_inb(INTC_IRR0);
+ a &= ~(1 << (irq - IRQ0_IRQ));
+ ctrl_outb(a, INTC_IRR0);
+ }
+}
+
+static void end_onChip2_irq(unsigned int irq)
+{
+ enable_onChip2_irq(irq);
+}
+#endif /* CONFIG_CPU_SUBTYPE_SH7709 */
+
void __init init_IRQ(void)
{
int i;
@@ -142,4 +245,25 @@ void __init init_IRQ(void)
for (i = TIMER_IRQ; i < NR_IRQS; i++) {
irq_desc[i].handler = &onChip_irq_type;
}
+
+#ifdef CONFIG_CPU_SUBTYPE_SH7709
+ for (i = IRQ0_IRQ; i < NR_IRQS; i++) {
+ irq_desc[i].handler = &onChip2_irq_type;
+ }
+
+ /*
+ * Enable external irq(INTC IRQ mode).
+ * You should set corresponding bits of PFC to "00"
+ * to enable these interrupts.
+ */
+ set_ipr_data(IRQ0_IRQ, IRQ0_IRP_OFFSET, IRQ0_PRIORITY);
+ set_ipr_data(IRQ1_IRQ, IRQ1_IRP_OFFSET, IRQ1_PRIORITY);
+ set_ipr_data(IRQ2_IRQ, IRQ2_IRP_OFFSET, IRQ2_PRIORITY);
+ 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/process.c b/arch/sh/kernel/process.c
index 2e58ad830..5d2a5696c 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: process.c,v 1.8 1999/10/31 13:19:16 gniibe Exp $
*
* linux/arch/sh/kernel/process.c
*
@@ -249,8 +249,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
p->thread.sp = (unsigned long) childregs;
p->thread.pc = (unsigned long) ret_from_fork;
- if (p->mm)
- p->mm->context = NO_CONTEXT;
return 0;
}
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index deb532300..f97e66585 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: setup.c,v 1.7 1999/10/23 01:34:50 gniibe Exp gniibe $
*
* linux/arch/sh/kernel/setup.c
*
@@ -135,9 +135,9 @@ static inline void parse_mem_cmdline (char ** cmdline_p)
memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
- memory_start = (unsigned long)__va(0)+__MEMORY_START;
+ memory_start = (unsigned long)PAGE_OFFSET+__MEMORY_START;
/* Default is 4Mbyte. */
- memory_end = (unsigned long)__va(0x00400000)+__MEMORY_START;
+ memory_end = (unsigned long)PAGE_OFFSET+0x00400000+__MEMORY_START;
for (;;) {
/*
@@ -214,7 +214,7 @@ void __init setup_arch(char **cmdline_p)
/*
* Initialize the boot-time allocator (with low memory only):
*/
- bootmap_size = init_bootmem(start_pfn, max_low_pfn);
+ bootmap_size = init_bootmem(start_pfn, max_low_pfn, __MEMORY_START);
/*
* FIXME: what about high memory?
@@ -259,16 +259,18 @@ void __init setup_arch(char **cmdline_p)
#ifdef CONFIG_BLK_DEV_INITRD
if (LOADER_TYPE) {
- initrd_start = INITRD_START ? INITRD_START : 0;
- initrd_end = initrd_start+INITRD_SIZE;
- if (initrd_end > memory_end) {
+ 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;
+ } else {
printk("initrd extends beyond end of memory "
"(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- initrd_end,memory_end);
+ INITRD_START + INITRD_SIZE,
+ max_low_pfn << PAGE_SHIFT);
initrd_start = 0;
- } else
- reserve_bootmem(__pa(initrd_start)-__MEMORY_START,
- INITRD_SIZE);
+ }
}
#endif
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 6abc7952e..8583afff1 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: signal.c,v 1.10 1999/09/27 23:25:44 gniibe Exp $
*
* linux/arch/sh/kernel/signal.c
*
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c
index a485f10a3..8f480f764 100644
--- a/arch/sh/kernel/sys_sh.c
+++ b/arch/sh/kernel/sys_sh.c
@@ -44,9 +44,8 @@ asmlinkage int sys_pipe(unsigned long * fildes)
}
asmlinkage unsigned long
-sys_mmap(int fd, unsigned long addr,
- unsigned long len, unsigned long prot,
- unsigned long flags, unsigned long off)
+sys_mmap(unsigned long addr, unsigned long len, unsigned long prot,
+ unsigned long flags, int fd, unsigned long off)
{
int error = -EFAULT;
struct file *file = NULL;
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index efe436336..49a765f83 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: time.c,v 1.7 1999/11/06 02:00:37 gniibe Exp $
*
* linux/arch/sh/kernel/time.c
*
@@ -43,7 +43,10 @@
#define TMU0_TCNT 0xfffffe98 /* Long access */
#define TMU0_TCR 0xfffffe9c /* Word access */
-#define INTERVAL 37500 /* (1000000*CLOCK_MHZ/HZ/2) ??? */
+#define INTERVAL 37500 /* (1000000*CLOCK_MHZ/HZ/2) ??? for CqREEK */
+#if 0 /* Takeshi's board */
+#define INTERVAL 83333
+#endif
/* SH-3 RTC */
#define R64CNT 0xfffffec0
@@ -195,6 +198,13 @@ static inline void do_timer_interrupt(int irq, void *dev_id, struct pt_regs *reg
{
do_timer(regs);
+#ifdef TAKESHI
+ {
+ unsigned long what_is_this=0xa4000124;
+
+ ctrl_outb(ctrl_inb(what_is_this)+1,what_is_this);
+ }
+#endif
#if 0
if (!user_mode(regs))
sh_do_profile(regs->pc);
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index 353281518..8a9b3e1f9 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: traps.c,v 1.3 1999/09/21 14:37:19 gniibe Exp $
*
* linux/arch/sh/traps.c
*
diff --git a/arch/sh/lib/checksum.S b/arch/sh/lib/checksum.S
index e0727df75..3471084b9 100644
--- a/arch/sh/lib/checksum.S
+++ b/arch/sh/lib/checksum.S
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: checksum.S,v 1.2 1999/10/29 13:06:55 gniibe Exp $
*
* INET An implementation of the TCP/IP protocol suite for the LINUX
* operating system. INET is implemented using the BSD Socket
@@ -192,7 +192,7 @@ DST( mov.w r0,@r5 )
mov #-5,r0
shld r0,r6
tst r6,r6
- bf/s 2f
+ bt/s 2f
clrt
SRC(1: mov.l @r4+,r0 )
SRC( mov.l @r4+,r1 )
diff --git a/arch/sh/lib/memcpy.S b/arch/sh/lib/memcpy.S
index 2da59276e..6f3121662 100644
--- a/arch/sh/lib/memcpy.S
+++ b/arch/sh/lib/memcpy.S
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: memcpy.S,v 1.3 1999/09/28 11:32:48 gniibe Exp $
*
* "memcpy" implementation of SuperH
*
diff --git a/arch/sh/lib/memmove.S b/arch/sh/lib/memmove.S
index 9e5c2fad3..61b97b7c2 100644
--- a/arch/sh/lib/memmove.S
+++ b/arch/sh/lib/memmove.S
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: memmove.S,v 1.2 1999/09/21 12:55:49 gniibe Exp $
*
* "memmove" implementation of SuperH
*
diff --git a/arch/sh/lib/memset.S b/arch/sh/lib/memset.S
index 40505631d..312d605e4 100644
--- a/arch/sh/lib/memset.S
+++ b/arch/sh/lib/memset.S
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: memset.S,v 1.1 1999/09/18 16:57:09 gniibe Exp $
*
* "memset" implementation of SuperH
*
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index 129aba7cc..d15c62385 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: cache.c,v 1.7 1999/09/23 11:43:07 gniibe Exp $
*
* linux/arch/sh/mm/cache.c
*
diff --git a/arch/sh/mm/extable.c b/arch/sh/mm/extable.c
index 72fcfee4a..dc77f57fe 100644
--- a/arch/sh/mm/extable.c
+++ b/arch/sh/mm/extable.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: extable.c,v 1.1 1999/09/18 16:57:37 gniibe Exp $
*
* linux/arch/sh/mm/extable.c
* Taken from:
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 93c352679..7f3610a3b 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: fault.c,v 1.5 1999/10/31 13:17:31 gniibe Exp $
*
* linux/arch/sh/mm/fault.c
* Copyright (C) 1999 Niibe Yutaka
@@ -81,6 +81,34 @@ bad_area:
return 0;
}
+static void handle_vmalloc_fault(struct task_struct *tsk, unsigned long address)
+{
+ pgd_t *dir;
+ pmd_t *pmd;
+ pte_t *pte;
+ pte_t entry;
+
+ dir = pgd_offset_k(address);
+ pmd = pmd_offset(dir, address);
+ if (pmd_none(*pmd)) {
+ printk(KERN_ERR "vmalloced area %08lx bad\n", address);
+ return;
+ }
+ if (pmd_bad(*pmd)) {
+ pmd_ERROR(*pmd);
+ pmd_clear(pmd);
+ return;
+ }
+ pte = pte_offset(pmd, address);
+ entry = *pte;
+ if (pte_none(entry) || !pte_present(entry) || !pte_write(entry)) {
+ printk(KERN_ERR "vmalloced area %08lx bad\n", address);
+ return;
+ }
+
+ update_mmu_cache(NULL, address, entry);
+}
+
/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
@@ -98,6 +126,11 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
tsk = current;
mm = tsk->mm;
+ if (address >= VMALLOC_START && address < VMALLOC_END) {
+ handle_vmalloc_fault(tsk, address);
+ return;
+ }
+
/*
* If we're in an interrupt or have no user
* context, we must not take the fault..
@@ -222,23 +255,13 @@ void update_mmu_cache(struct vm_area_struct * vma,
unsigned long address, pte_t pte)
{
unsigned long flags;
- unsigned long asid;
unsigned long pteval;
- asid = get_asid();
-
- address &= PAGE_MASK;
-#if 0/*defined(__SH4__)*//* SH-4 has separate I/D caches: XXX really needed? */
- if ((vma->vm_flags & VM_EXEC) != 0)
-/* &&
- ((pte_val(pte) & (_PAGE_PRESENT | _PAGE_DIRTY)) ==
- (_PAGE_PRESENT | _PAGE_DIRTY))) */
- flush_icache_range(address,address+PAGE_SIZE);
-#endif
save_and_cli(flags);
- /* Set PTEH register */
- ctrl_outl((address|asid), MMU_PTEH);
-
+ /*
+ * We don't need to set PTEH register.
+ * It's automatically set by the hardware.
+ */
pteval = pte_val(pte);
pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
pteval |= _PAGE_FLAGS_HARDWARE_DEFAULT; /* add default flags */
@@ -246,18 +269,31 @@ void update_mmu_cache(struct vm_area_struct * vma,
ctrl_outl(pteval, MMU_PTEL);
/* Load the TLB */
- asm volatile ("ldtlb" : /* no output */ : /* no input */
- : "memory");
+ asm volatile("ldtlb": /* no output */ : /* no input */ : "memory");
restore_flags(flags);
}
-static __inline__ void __flush_tlb_page(unsigned long asid, unsigned long page)
+static void __flush_tlb_page(struct mm_struct *mm, unsigned long page)
{
- unsigned long addr, data;
+ unsigned long addr, data, asid;
+ unsigned long saved_asid = MMU_NO_ASID;
+
+ if (mm->context == NO_CONTEXT)
+ return;
+
+ asid = mm->context & MMU_CONTEXT_ASID_MASK;
+ if (mm != current->mm) {
+ saved_asid = get_asid();
+ /*
+ * We need to set ASID of the target entry to flush,
+ * because TLB is indexed by (ASID and PAGE).
+ */
+ set_asid(asid);
+ }
#if defined(__sh3__)
- addr = MMU_TLB_ADDRESS_ARRAY | (page & 0x1F000) | MMU_PAGE_ASSOC_BIT;
- data = page | asid; /* VALID bit is off */
+ addr = MMU_TLB_ADDRESS_ARRAY |(page & 0x1F000)| MMU_PAGE_ASSOC_BIT;
+ data = (page & 0xfffe0000) | asid; /* VALID bit is off */
ctrl_outl(data, addr);
#elif defined(__SH4__)
int i;
@@ -276,19 +312,18 @@ static __inline__ void __flush_tlb_page(unsigned long asid, unsigned long page)
}
}
#endif
+ if (saved_asid != MMU_NO_ASID)
+ set_asid(saved_asid);
}
void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
{
- unsigned long asid;
-
- if (vma->vm_mm->context != NO_CONTEXT) {
- unsigned long flags;
+ unsigned long flags;
+ if (vma->vm_mm) {
page &= PAGE_MASK;
- asid = vma->vm_mm->context & MMU_CONTEXT_ASID_MASK;
save_and_cli(flags);
- __flush_tlb_page (asid, page);
+ __flush_tlb_page(vma->vm_mm, page);
restore_flags(flags);
}
}
@@ -303,18 +338,15 @@ void flush_tlb_range(struct mm_struct *mm, unsigned long start,
save_and_cli(flags);
size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
if (size > (MMU_NTLB_ENTRIES/4)) { /* Too many TLB to flush */
- get_new_mmu_context(mm);
+ mm->context = NO_CONTEXT;
if (mm == current->mm)
- set_asid(mm->context & MMU_CONTEXT_ASID_MASK);
+ activate_context(mm);
} else {
- unsigned long asid;
-
- asid = mm->context & MMU_CONTEXT_ASID_MASK;
start &= PAGE_MASK;
end += (PAGE_SIZE - 1);
end &= PAGE_MASK;
while (start < end) {
- __flush_tlb_page (asid, start);
+ __flush_tlb_page(mm, start);
start += PAGE_SIZE;
}
}
@@ -325,14 +357,14 @@ void flush_tlb_range(struct mm_struct *mm, unsigned long start,
void flush_tlb_mm(struct mm_struct *mm)
{
/* Invalidate all TLB of this process. */
- /* Instead of flush TLBs, we get new MMU context. */
+ /* Instead of invalidating each TLB, we get new MMU context. */
if (mm->context != NO_CONTEXT) {
unsigned long flags;
save_and_cli(flags);
- get_new_mmu_context(mm);
+ mm->context = NO_CONTEXT;
if (mm == current->mm)
- set_asid(mm->context & MMU_CONTEXT_ASID_MASK);
+ activate_context(mm);
restore_flags(flags);
}
}
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 2dc194a77..83e2f3e9e 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: init.c,v 1.4 1999/10/23 01:37:02 gniibe Exp gniibe $
*
* linux/arch/sh/mm/init.c
*
@@ -193,13 +193,14 @@ pgd_t swapper_pg_dir[1024];
*/
void __init paging_init(void)
{
+ int i;
pgd_t * pg_dir;
/* We don't need kernel mapping as hardware support that. */
pg_dir = swapper_pg_dir;
- /* Unmap the original low memory mappings to detect NULL reference */
- pgd_val(pg_dir[0]) = 0;
+ for (i=0; i < USER_PTRS_PER_PGD*2; i++)
+ pgd_val(pg_dir[i]) = 0;
/* Enable MMU */
ctrl_outl(MMU_CONTROL_INIT, MMUCR);
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c
index d86d29279..90fd190ef 100644
--- a/arch/sh/mm/ioremap.c
+++ b/arch/sh/mm/ioremap.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: ioremap.c,v 1.1 1999/09/18 16:57:48 gniibe Exp $
*
* arch/sh/mm/ioremap.c
*
diff --git a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S
index 374cb4ad7..688c4c9c4 100644
--- a/arch/sh/vmlinux.lds.S
+++ b/arch/sh/vmlinux.lds.S
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: vmlinux.lds.S,v 1.3 1999/10/05 12:33:48 gniibe Exp $
* ld script to make SuperH Linux kernel
* Written by Niibe Yutaka
*/
diff --git a/arch/sparc/config.in b/arch/sparc/config.in
index 6776cdeed..81fc41f5d 100644
--- a/arch/sparc/config.in
+++ b/arch/sparc/config.in
@@ -10,66 +10,64 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
- bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
- bool 'Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
-mainmenu_option next_comment
comment 'General setup'
define_bool CONFIG_VT y
define_bool CONFIG_VT_CONSOLE y
-bool 'Support for AP1000 multicomputer' CONFIG_AP1000
bool 'Symmetric multi-processing support (does not work on sun4/sun4c)' CONFIG_SMP
+bool 'Support for AP1000 multicomputer' CONFIG_AP1000
if [ "$CONFIG_AP1000" = "y" ]; then
- define_bool CONFIG_NO_KEYBOARD y
- define_bool CONFIG_FDDI y
- define_bool CONFIG_APFDDI y
- define_bool CONFIG_APBLOCK y
- define_bool CONFIG_APBIF y
- tristate 'OPIU DDV Driver' CONFIG_DDV
+ define_bool CONFIG_NO_KEYBOARD y
+ define_bool CONFIG_FDDI y
+ define_bool CONFIG_APFDDI y
+ define_bool CONFIG_APBLOCK y
+ define_bool CONFIG_APBIF y
+ tristate ' OPIU DDV Driver' CONFIG_DDV
else
- bool 'Support for SUN4 machines (disables SUN4[CDM] support)' CONFIG_SUN4
- if [ "$CONFIG_SUN4" != "y" ]; then
- bool 'Support for PCI and PS/2 keyboard/mouse' CONFIG_PCI
- fi
-
- mainmenu_option next_comment
- comment 'Console drivers'
- bool 'PROM console' CONFIG_PROM_CONSOLE
- bool 'Support Frame buffer devices' CONFIG_FB
- source drivers/video/Config.in
- endmenu
-
- # Global things across all Sun machines.
- define_bool CONFIG_SBUS y
- define_bool CONFIG_SBUSCHAR y
- define_bool CONFIG_BUSMOUSE y
- define_bool CONFIG_SUN_MOUSE y
- define_bool CONFIG_SERIAL y
- define_bool CONFIG_SUN_SERIAL y
- define_bool CONFIG_SERIAL_CONSOLE y
- define_bool CONFIG_SUN_KEYBOARD y
- define_bool CONFIG_SUN_CONSOLE y
- define_bool CONFIG_SUN_AUXIO y
- define_bool CONFIG_SUN_IO y
- if [ "$CONFIG_SUN4" != "y" ]; then
- source drivers/sbus/char/Config.in
- source drivers/sbus/audio/Config.in
- fi
+ bool 'Support for SUN4 machines (disables SUN4[CDM] support)' CONFIG_SUN4
+ if [ "$CONFIG_SUN4" != "y" ]; then
+ bool ' Support for PCI and PS/2 keyboard/mouse' CONFIG_PCI
+ fi
+
+ mainmenu_option next_comment
+ comment 'Console drivers'
+ bool 'PROM console' CONFIG_PROM_CONSOLE
+ bool 'Support Frame buffer devices' CONFIG_FB
+ source drivers/video/Config.in
+ endmenu
+
+ # Global things across all Sun machines.
+ define_bool CONFIG_SBUS y
+ define_bool CONFIG_SBUSCHAR y
+ define_bool CONFIG_BUSMOUSE y
+ define_bool CONFIG_SUN_MOUSE y
+ define_bool CONFIG_SERIAL y
+ define_bool CONFIG_SUN_SERIAL y
+ define_bool CONFIG_SERIAL_CONSOLE y
+ define_bool CONFIG_SUN_KEYBOARD y
+ define_bool CONFIG_SUN_CONSOLE y
+ define_bool CONFIG_SUN_AUXIO y
+ define_bool CONFIG_SUN_IO y
+ if [ "$CONFIG_SUN4" != "y" ]; then
+ source drivers/sbus/char/Config.in
+ source drivers/sbus/audio/Config.in
+ fi
fi
-tristate 'Openprom tree appears in /proc/openprom (EXPERIMENTAL)' CONFIG_SUN_OPENPROMFS
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ tristate 'Openprom tree appears in /proc/openprom (EXPERIMENTAL)' CONFIG_SUN_OPENPROMFS
+fi
bool 'Networking support' CONFIG_NET
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 a.out binaries' CONFIG_BINFMT_AOUT
tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
@@ -78,21 +76,30 @@ dep_tristate ' Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
endmenu
mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS
+ bool ' Kernel module loader' CONFIG_KMOD
+fi
+endmenu
+
+mainmenu_option next_comment
comment 'Floppy, IDE, and other block devices'
bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD
bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD
if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then
- tristate ' Linear (append) mode' CONFIG_MD_LINEAR
- tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED
- tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
- tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5
+ tristate ' Linear (append) mode' CONFIG_MD_LINEAR
+ tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED
+ tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
+ tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5
fi
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
+ bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
fi
tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
@@ -101,7 +108,7 @@ tristate 'Network block device support' CONFIG_BLK_DEV_NBD
endmenu
if [ "$CONFIG_NET" = "y" ]; then
- source net/Config.in
+ source net/Config.in
fi
mainmenu_option next_comment
@@ -109,7 +116,7 @@ comment 'ISDN subsystem'
tristate 'ISDN support' CONFIG_ISDN
if [ "$CONFIG_ISDN" != "n" ]; then
- source drivers/isdn/Config.in
+ source drivers/isdn/Config.in
fi
endmenu
@@ -119,65 +126,65 @@ comment 'SCSI support'
tristate 'SCSI support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then
- comment 'SCSI support type (disk, tape, CDrom)'
+ comment 'SCSI support type (disk, tape, CDrom)'
- dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
- dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
- dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
- if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
- bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
- fi
- dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
+ dep_tristate ' SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
+ dep_tristate ' SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
+ dep_tristate ' SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
+ if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
+ bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
+ fi
+ dep_tristate ' SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
- comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
+ comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
- bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
+ bool ' Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
- bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
+ bool ' Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
- mainmenu_option next_comment
- comment 'SCSI low-level drivers'
+ mainmenu_option next_comment
+ comment 'SCSI low-level drivers'
- bool 'Sparc ESP Scsi Driver' CONFIG_SCSI_SUNESP $CONFIG_SCSI
- tristate 'PTI Qlogic,ISP Driver' CONFIG_SCSI_QLOGICPTI $CONFIG_SCSI
- endmenu
+ bool 'Sparc ESP Scsi Driver' CONFIG_SCSI_SUNESP $CONFIG_SCSI
+ tristate 'PTI Qlogic,ISP Driver' CONFIG_SCSI_QLOGICPTI $CONFIG_SCSI
+ endmenu
fi
endmenu
source drivers/fc4/Config.in
if [ "$CONFIG_NET" = "y" ]; then
- mainmenu_option next_comment
- comment 'Network device support'
-
- bool 'Network device support' CONFIG_NETDEVICES
- if [ "$CONFIG_NETDEVICES" = "y" ]; then
- tristate 'Dummy net driver support' CONFIG_DUMMY
- tristate 'PPP (point-to-point) support' CONFIG_PPP
- if [ ! "$CONFIG_PPP" = "n" ]; then
- comment 'CCP compressors for PPP are only built as modules.'
- fi
- tristate 'SLIP (serial line) support' CONFIG_SLIP
- if [ "$CONFIG_SLIP" != "n" ]; then
- bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
- bool ' Keepalive and linefill' CONFIG_SLIP_SMART
- bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6
- fi
- tristate 'Sun LANCE support' CONFIG_SUNLANCE
- tristate 'Sun Happy Meal 10/100baseT support' CONFIG_HAPPYMEAL
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'Sun BigMAC 10/100baseT support' CONFIG_SUNBMAC
- fi
- tristate 'Sun QuadEthernet support' CONFIG_SUNQE
- tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS
-# bool 'FDDI driver support' CONFIG_FDDI
-# if [ "$CONFIG_FDDI" = "y" ]; then
-# fi
- if [ "$CONFIG_ATM" = "y" ]; then
- source drivers/atm/Config.in
- fi
- fi
- endmenu
+ mainmenu_option next_comment
+ comment 'Network device support'
+
+ bool 'Network device support' CONFIG_NETDEVICES
+ if [ "$CONFIG_NETDEVICES" = "y" ]; then
+ tristate ' Dummy net driver support' CONFIG_DUMMY
+ tristate ' PPP (point-to-point) support' CONFIG_PPP
+ if [ ! "$CONFIG_PPP" = "n" ]; then
+ comment 'CCP compressors for PPP are only built as modules.'
+ fi
+ tristate ' SLIP (serial line) support' CONFIG_SLIP
+ if [ "$CONFIG_SLIP" != "n" ]; then
+ bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
+ bool ' Keepalive and linefill' CONFIG_SLIP_SMART
+ bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6
+ fi
+ tristate ' Sun LANCE support' CONFIG_SUNLANCE
+ tristate ' Sun Happy Meal 10/100baseT support' CONFIG_HAPPYMEAL
+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ tristate ' Sun BigMAC 10/100baseT support (EXPERIMENTAL)' CONFIG_SUNBMAC
+ fi
+ tristate ' Sun QuadEthernet support' CONFIG_SUNQE
+ tristate ' MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS
+# bool ' FDDI driver support' CONFIG_FDDI
+# if [ "$CONFIG_FDDI" = "y" ]; then
+# fi
+ if [ "$CONFIG_ATM" = "y" ]; then
+ source drivers/atm/Config.in
+ fi
+ fi
+ endmenu
fi
# This one must be before the filesystem configs. -DaveM
@@ -185,7 +192,7 @@ mainmenu_option next_comment
comment 'Unix98 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
+ int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
fi
endmenu
@@ -202,4 +209,3 @@ comment 'Kernel hacking'
bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ
endmenu
-
diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig
index ba3db5e7f..98d1431a5 100644
--- a/arch/sparc/defconfig
+++ b/arch/sparc/defconfig
@@ -78,6 +78,8 @@ CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_MISC=m
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index 0f89687a3..88db458e0 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -702,3 +702,37 @@ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
"g1", "g2", "g3", "o0", "o1", "memory", "cc");
return retval;
}
+
+/*
+ * 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 pc, fp, bias = 0;
+ unsigned long task_base = (unsigned long) p;
+ struct reg_window *rw;
+ int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+
+ fp = p->thread.ksp + bias;
+ do {
+ /* Bogus frame pointer? */
+ if (fp < (task_base + sizeof(struct task_struct)) ||
+ fp >= (task_base + (2 * PAGE_SIZE)))
+ break;
+ rw = (struct reg_window *) fp;
+ pc = rw->ins[7];
+ if (pc < first_sched || pc >= last_sched)
+ return pc;
+ fp = rw->ins[6] + bias;
+ } while (++count < 16);
+ return 0;
+}
+#undef last_sched
+#undef first_sched
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index a6f21c57c..7fb43e354 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -1050,7 +1050,7 @@ static inline void read_maps (void)
ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_file->f_dentry, buffer, PAGE_SIZE);
}
- printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_offset,
+ printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
kdevname(dev), ino);
if (map->vm_file != NULL)
printk("%s\n", line);
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index 490e8e0af..95c5e37be 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -279,3 +279,5 @@ EXPORT_SYMBOL_DOT(mul);
EXPORT_SYMBOL_DOT(umul);
EXPORT_SYMBOL_DOT(div);
EXPORT_SYMBOL_DOT(udiv);
+
+EXPORT_SYMBOL(get_wchan);
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index ee4d1bb99..86e942597 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -10,15 +10,6 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
endmenu
mainmenu_option next_comment
-comment 'Loadable module support'
-bool 'Enable loadable module support' CONFIG_MODULES
-if [ "$CONFIG_MODULES" = "y" ]; then
- bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS
- bool 'Kernel module loader' CONFIG_KMOD
-fi
-endmenu
-
-mainmenu_option next_comment
comment 'General setup'
define_bool CONFIG_VT y
@@ -49,25 +40,41 @@ bool 'PCI support' CONFIG_PCI
source drivers/sbus/char/Config.in
source drivers/sbus/audio/Config.in
-tristate 'Openprom tree appears in /proc/openprom (EXPERIMENTAL)' CONFIG_SUN_OPENPROMFS
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ tristate 'Openprom tree appears in /proc/openprom (EXPERIMENTAL)' CONFIG_SUN_OPENPROMFS
+fi
bool 'Networking support' CONFIG_NET
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
bool 'Kernel support for Linux/Sparc 32bit binary compatibility' CONFIG_SPARC32_COMPAT
-tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF
if [ "$CONFIG_SPARC32_COMPAT" != "n" ]; then
- tristate 'Kernel support for 32-bit ELF binaries' CONFIG_BINFMT_ELF32
- bool 'Kernel support for 32-bit (ie. SunOS) a.out binaries' CONFIG_BINFMT_AOUT32
+ tristate ' Kernel support for 32-bit ELF binaries' CONFIG_BINFMT_ELF32
+ bool ' Kernel support for 32-bit (ie. SunOS) a.out binaries' CONFIG_BINFMT_AOUT32
fi
+tristate 'Kernel support for 64-bit ELF binaries' CONFIG_BINFMT_ELF
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'Solaris binary emulation' CONFIG_SOLARIS_EMUL
+ tristate 'Solaris binary emulation (EXPERIMENTAL)' CONFIG_SOLARIS_EMUL
fi
source drivers/parport/Config.in
dep_tristate ' Parallel printer support' CONFIG_PRINTER $CONFIG_PARPORT
if [ "$CONFIG_PCI" = "y" ]; then
- tristate 'SUNW,envctrl support' CONFIG_ENVCTRL
+ tristate 'SUNW, envctrl support' CONFIG_ENVCTRL
+fi
+endmenu
+
+mainmenu_option next_comment
+comment 'Loadable module support'
+bool 'Enable loadable module support' CONFIG_MODULES
+if [ "$CONFIG_MODULES" = "y" ]; then
+ bool ' Set version information on all symbols for modules' CONFIG_MODVERSIONS
+ bool ' Kernel module loader' CONFIG_KMOD
fi
endmenu
@@ -78,41 +85,41 @@ bool 'Normal floppy disk support' CONFIG_BLK_DEV_FD
bool 'Multiple devices driver support' CONFIG_BLK_DEV_MD
if [ "$CONFIG_BLK_DEV_MD" = "y" ]; then
- tristate ' Linear (append) mode' CONFIG_MD_LINEAR
- tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED
- tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
- tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5
+ tristate ' Linear (append) mode' CONFIG_MD_LINEAR
+ tristate ' RAID-0 (striping) mode' CONFIG_MD_STRIPED
+ tristate ' RAID-1 (mirroring) mode' CONFIG_MD_MIRRORING
+ tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5
fi
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
+ bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD
fi
tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP
tristate 'Network block device support' CONFIG_BLK_DEV_NBD
if [ "$CONFIG_PCI" = "y" ]; then
- tristate 'Ultra/PCI IDE disk/cdrom/tape/floppy support' CONFIG_BLK_DEV_IDE
- if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
- dep_tristate ' Include IDE/ATA-2 DISK support' CONFIG_BLK_DEV_IDEDISK $CONFIG_BLK_DEV_IDE
- dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE
- dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE
- dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE
- dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE
- define_bool CONFIG_BLK_DEV_IDEPCI y
- define_bool CONFIG_BLK_DEV_IDEDMA y
- define_bool CONFIG_IDEDMA_AUTO y
- define_bool IDEDMA_NEW_DRIVE_LISTINGS y
- define_bool CONFIG_BLK_DEV_NS87415 y
- define_bool CONFIG_BLK_DEV_CMD646 y
- fi
+ tristate 'Ultra/PCI IDE disk/cdrom/tape/floppy support' CONFIG_BLK_DEV_IDE
+ if [ "$CONFIG_BLK_DEV_IDE" != "n" ]; then
+ dep_tristate ' Include IDE/ATA-2 DISK support' CONFIG_BLK_DEV_IDEDISK $CONFIG_BLK_DEV_IDE
+ dep_tristate ' Include IDE/ATAPI CDROM support' CONFIG_BLK_DEV_IDECD $CONFIG_BLK_DEV_IDE
+ dep_tristate ' Include IDE/ATAPI TAPE support' CONFIG_BLK_DEV_IDETAPE $CONFIG_BLK_DEV_IDE
+ dep_tristate ' Include IDE/ATAPI FLOPPY support' CONFIG_BLK_DEV_IDEFLOPPY $CONFIG_BLK_DEV_IDE
+ dep_tristate ' SCSI emulation support' CONFIG_BLK_DEV_IDESCSI $CONFIG_BLK_DEV_IDE
+ define_bool CONFIG_BLK_DEV_IDEPCI y
+ define_bool CONFIG_BLK_DEV_IDEDMA y
+ define_bool CONFIG_IDEDMA_AUTO y
+ define_bool CONFIG_IDEDMA_NEW_DRIVE_LISTINGS y
+ define_bool CONFIG_BLK_DEV_NS87415 y
+ define_bool CONFIG_BLK_DEV_CMD646 y
+ fi
fi
endmenu
if [ "$CONFIG_NET" = "y" ]; then
- source net/Config.in
+ source net/Config.in
fi
mainmenu_option next_comment
@@ -121,95 +128,95 @@ comment 'SCSI support'
tristate 'SCSI support' CONFIG_SCSI
if [ "$CONFIG_SCSI" != "n" ]; then
- comment 'SCSI support type (disk, tape, CDrom)'
-
- dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
- dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
- dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
- if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
- bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
- fi
- dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
-
- comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
-
- bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
-
- bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
-
- mainmenu_option next_comment
- comment 'SCSI low-level drivers'
-
- bool 'Sparc ESP Scsi Driver' CONFIG_SCSI_SUNESP $CONFIG_SCSI
- tristate 'PTI Qlogic,ISP Driver' CONFIG_SCSI_QLOGICPTI $CONFIG_SCSI
-
- if [ "$CONFIG_PCI" != "n" ]; then
- dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
- if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then
- bool ' Enable Tagged Command Queueing (TCQ) by default' CONFIG_AIC7XXX_TCQ_ON_BY_DEFAULT
- int ' Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8
- bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS N
- int ' Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5
- fi
- dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI
- if [ "$CONFIG_SCSI_NCR53C8XX" != "n" ]; then
- int ' default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8
- int ' maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32
- int ' synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 10
- bool ' enable profiling' CONFIG_SCSI_NCR53C8XX_PROFILE
- if [ "$CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS" = "0" ]; then
- bool ' not allow targets to disconnect' CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
- fi
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- bool ' assume boards are SYMBIOS compatible' CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT
- fi
- fi
- dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI
- fi
-
- endmenu
+ comment 'SCSI support type (disk, tape, CDrom)'
+
+ dep_tristate ' SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI
+ dep_tristate ' SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI
+ dep_tristate ' SCSI CDROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI
+ if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then
+ bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR
+ fi
+ dep_tristate ' SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI
+
+ comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
+
+ bool ' Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN
+
+ bool ' Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS
+
+ mainmenu_option next_comment
+ comment 'SCSI low-level drivers'
+
+ bool 'Sparc ESP Scsi Driver' CONFIG_SCSI_SUNESP $CONFIG_SCSI
+ tristate 'PTI Qlogic, ISP Driver' CONFIG_SCSI_QLOGICPTI $CONFIG_SCSI
+
+ if [ "$CONFIG_PCI" != "n" ]; then
+ dep_tristate 'Adaptec AIC7xxx support' CONFIG_SCSI_AIC7XXX $CONFIG_SCSI
+ if [ "$CONFIG_SCSI_AIC7XXX" != "n" ]; then
+ bool ' Enable tagged command queueing (TCQ) by default' CONFIG_AIC7XXX_TAGGED_QUEUEING Y
+ int ' Maximum number of TCQ commands per device' CONFIG_AIC7XXX_CMDS_PER_DEVICE 8
+ bool ' Collect statistics to report in /proc' CONFIG_AIC7XXX_PROC_STATS N
+ int ' Delay in seconds after SCSI bus reset' CONFIG_AIC7XXX_RESET_DELAY 5
+ fi
+ dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI
+ if [ "$CONFIG_SCSI_NCR53C8XX" != "n" ]; then
+ int 'default tagged command queue depth' CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS 8
+ int 'maximum number of queued commands' CONFIG_SCSI_NCR53C8XX_MAX_TAGS 32
+ int 'synchronous transfers frequency in MHz' CONFIG_SCSI_NCR53C8XX_SYNC 10
+ bool ' enable profiling' CONFIG_SCSI_NCR53C8XX_PROFILE
+ if [ "$CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS" = "0" ]; then
+ bool ' not allow targets to disconnect' CONFIG_SCSI_NCR53C8XX_NO_DISCONNECT
+ fi
+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ bool ' assume boards are SYMBIOS compatible (EXPERIMENTAL)' CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT
+ fi
+ fi
+ dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI
+ fi
+
+ endmenu
fi
endmenu
source drivers/fc4/Config.in
if [ "$CONFIG_NET" = "y" ]; then
- mainmenu_option next_comment
- comment 'Network device support'
-
- bool 'Network device support' CONFIG_NETDEVICES
- if [ "$CONFIG_NETDEVICES" = "y" ]; then
- tristate 'Dummy net driver support' CONFIG_DUMMY
- tristate 'PPP (point-to-point) support' CONFIG_PPP
- if [ ! "$CONFIG_PPP" = "n" ]; then
- comment 'CCP compressors for PPP are only built as modules.'
- fi
- tristate 'SLIP (serial line) support' CONFIG_SLIP
- if [ "$CONFIG_SLIP" != "n" ]; then
- bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
- bool ' Keepalive and linefill' CONFIG_SLIP_SMART
- bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6
- fi
- bool 'Sun LANCE support' CONFIG_SUNLANCE
- tristate 'Sun Happy Meal 10/100baseT support' CONFIG_HAPPYMEAL
- if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'Sun BigMAC 10/100baseT support' CONFIG_SUNBMAC
- fi
- tristate 'Sun QuadEthernet support' CONFIG_SUNQE
- tristate 'MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS
- if [ "$CONFIG_PCI" = "y" ]; then
- tristate 'Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5
- tristate '3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX
- tristate 'RealTek 8129/8139 (not 8019/8029!) support' CONFIG_RTL8139
- tristate 'PCI NE2000 support' CONFIG_NE2K_PCI
- tristate 'EtherExpressPro/100 support' CONFIG_EEXPRESS_PRO100
- tristate 'Adaptec Starfire support' CONFIG_ADAPTEC_STARFIRE
- fi
-# bool 'FDDI driver support' CONFIG_FDDI
-# if [ "$CONFIG_FDDI" = "y" ]; then
-# fi
- fi
- endmenu
+ mainmenu_option next_comment
+ comment 'Network device support'
+
+ bool 'Network device support' CONFIG_NETDEVICES
+ if [ "$CONFIG_NETDEVICES" = "y" ]; then
+ tristate ' Dummy net driver support' CONFIG_DUMMY
+ tristate ' PPP (point-to-point) support' CONFIG_PPP
+ if [ ! "$CONFIG_PPP" = "n" ]; then
+ comment ' CCP compressors for PPP are only built as modules.'
+ fi
+ tristate ' SLIP (serial line) support' CONFIG_SLIP
+ if [ "$CONFIG_SLIP" != "n" ]; then
+ bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED
+ bool ' Keepalive and linefill' CONFIG_SLIP_SMART
+ bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6
+ fi
+ bool ' Sun LANCE support' CONFIG_SUNLANCE
+ tristate ' Sun Happy Meal 10/100baseT support' CONFIG_HAPPYMEAL
+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ tristate ' Sun BigMAC 10/100baseT support (EXPERIMENTAL)' CONFIG_SUNBMAC
+ fi
+ tristate ' Sun QuadEthernet support' CONFIG_SUNQE
+ tristate ' MyriCOM Gigabit Ethernet support' CONFIG_MYRI_SBUS
+ if [ "$CONFIG_PCI" = "y" ]; then
+ tristate ' Generic DECchip & DIGITAL EtherWORKS PCI/EISA' CONFIG_DE4X5
+ tristate ' 3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX
+ tristate ' RealTek 8129/8139 (not 8019/8029!) support' CONFIG_RTL8139
+ tristate ' PCI NE2000 support' CONFIG_NE2K_PCI
+ tristate ' EtherExpressPro/100 support' CONFIG_EEXPRESS_PRO100
+ tristate ' Adaptec Starfire support' CONFIG_ADAPTEC_STARFIRE
+ fi
+# bool ' FDDI driver support' CONFIG_FDDI
+# if [ "$CONFIG_FDDI" = "y" ]; then
+# fi
+ fi
+endmenu
fi
# This one must be before the filesystem configs. -DaveM
@@ -217,7 +224,7 @@ mainmenu_option next_comment
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
+ int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256
fi
endmenu
@@ -225,9 +232,9 @@ mainmenu_option next_comment
comment 'Video For Linux'
tristate 'Video For Linux' CONFIG_VIDEO_DEV
if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
- if [ "$CONFIG_PCI" != "n" ]; then
- dep_tristate 'BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV
- fi
+ if [ "$CONFIG_PCI" != "n" ]; then
+ dep_tristate ' BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV
+ fi
fi
endmenu
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 10d9ccd81..59ab0b543 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -88,6 +88,8 @@ CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
CONFIG_SPARC32_COMPAT=y
CONFIG_BINFMT_ELF=y
CONFIG_BINFMT_ELF32=y
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 0e0f540b7..20a5534cb 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -802,3 +802,35 @@ 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 pc, fp, bias = 0;
+ unsigned long task_base = (unsigned long) p;
+ struct reg_window *rw;
+ int count = 0;
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+ bias = STACK_BIAS;
+ fp = p->thread.ksp + bias;
+ do {
+ /* Bogus frame pointer? */
+ if (fp < (task_base + sizeof(struct task_struct)) ||
+ fp >= (task_base + (2 * PAGE_SIZE)))
+ break;
+ rw = (struct reg_window *) fp;
+ pc = rw->ins[7];
+ if (pc < first_sched || pc >= last_sched)
+ return pc;
+ fp = rw->ins[6] + bias;
+ } while (++count < 16);
+ return 0;
+}
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index 672e83493..f784e3b9e 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -618,7 +618,7 @@ static inline void read_maps (void)
ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_file->f_dentry, buffer, PAGE_SIZE);
}
- printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_offset,
+ printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
kdevname(dev), ino);
if (map->vm_file != NULL)
printk("%s\n", line);
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index 59388286f..949017da3 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -1226,7 +1226,7 @@ static inline void read_maps (void)
ino = map->vm_file->f_dentry->d_inode->i_ino;
line = d_path(map->vm_file->f_dentry, buffer, PAGE_SIZE);
}
- printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_offset,
+ printk(MAPS_LINE_FORMAT, map->vm_start, map->vm_end, str, map->vm_pgoff << PAGE_SHIFT,
kdevname(dev), ino);
if (map->vm_file != NULL)
printk("%s\n", line);
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c
index e57b8d6f7..434f22bf8 100644
--- a/arch/sparc64/kernel/sparc64_ksyms.c
+++ b/arch/sparc64/kernel/sparc64_ksyms.c
@@ -311,3 +311,5 @@ EXPORT_SYMBOL_NOVERS(memcmp);
EXPORT_SYMBOL_NOVERS(memcpy);
EXPORT_SYMBOL_NOVERS(memset);
EXPORT_SYMBOL_NOVERS(memmove);
+
+EXPORT_SYMBOL(get_wchan);