summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/Makefile23
-rw-r--r--arch/alpha/boot/bootp.c8
-rw-r--r--arch/alpha/boot/main.c2
-rw-r--r--arch/alpha/config.in19
-rw-r--r--arch/alpha/defconfig2
-rw-r--r--arch/alpha/kernel/Makefile25
-rw-r--r--arch/alpha/kernel/alpha_ksyms.c5
-rw-r--r--arch/alpha/kernel/core_apecs.c4
-rw-r--r--arch/alpha/kernel/core_cia.c10
-rw-r--r--arch/alpha/kernel/core_irongate.c353
-rw-r--r--arch/alpha/kernel/core_lca.c4
-rw-r--r--arch/alpha/kernel/core_mcpcia.c146
-rw-r--r--arch/alpha/kernel/core_polaris.c6
-rw-r--r--arch/alpha/kernel/core_pyxis.c10
-rw-r--r--arch/alpha/kernel/core_t2.c4
-rw-r--r--arch/alpha/kernel/core_tsunami.c89
-rw-r--r--arch/alpha/kernel/irq.c128
-rw-r--r--arch/alpha/kernel/irq_impl.h49
-rw-r--r--arch/alpha/kernel/machvec_impl.h10
-rw-r--r--arch/alpha/kernel/pci.c209
-rw-r--r--arch/alpha/kernel/pci_impl.h5
-rw-r--r--arch/alpha/kernel/process.c73
-rw-r--r--arch/alpha/kernel/proto.h26
-rw-r--r--arch/alpha/kernel/ptrace.c6
-rw-r--r--arch/alpha/kernel/setup.c257
-rw-r--r--arch/alpha/kernel/signal.c1
-rw-r--r--arch/alpha/kernel/smp.c62
-rw-r--r--arch/alpha/kernel/sys_alcor.c6
-rw-r--r--arch/alpha/kernel/sys_cabriolet.c8
-rw-r--r--arch/alpha/kernel/sys_dp264.c73
-rw-r--r--arch/alpha/kernel/sys_eb64p.c5
-rw-r--r--arch/alpha/kernel/sys_eiger.c215
-rw-r--r--arch/alpha/kernel/sys_jensen.c4
-rw-r--r--arch/alpha/kernel/sys_miata.c5
-rw-r--r--arch/alpha/kernel/sys_mikasa.c5
-rw-r--r--arch/alpha/kernel/sys_nautilus.c535
-rw-r--r--arch/alpha/kernel/sys_noritake.c5
-rw-r--r--arch/alpha/kernel/sys_rawhide.c109
-rw-r--r--arch/alpha/kernel/sys_ruffian.c7
-rw-r--r--arch/alpha/kernel/sys_rx164.c4
-rw-r--r--arch/alpha/kernel/sys_sable.c5
-rw-r--r--arch/alpha/kernel/sys_sio.c20
-rw-r--r--arch/alpha/kernel/sys_sx164.c4
-rw-r--r--arch/alpha/kernel/sys_takara.c72
-rw-r--r--arch/alpha/kernel/time.c23
-rw-r--r--arch/alpha/kernel/traps.c2
-rw-r--r--arch/alpha/lib/Makefile2
-rw-r--r--arch/alpha/lib/fpreg.c (renamed from arch/alpha/kernel/fpreg.c)95
-rw-r--r--arch/alpha/lib/io.c28
-rw-r--r--arch/alpha/math-emu/Makefile10
-rw-r--r--arch/alpha/math-emu/fp-emul.c354
-rw-r--r--arch/alpha/math-emu/fp-emul.h10
-rw-r--r--arch/alpha/math-emu/ieee-math.c1382
-rw-r--r--arch/alpha/math-emu/ieee-math.h54
-rw-r--r--arch/alpha/math-emu/math.c447
-rw-r--r--arch/alpha/math-emu/sfp-util.h40
-rw-r--r--arch/alpha/mm/fault.c2
-rw-r--r--arch/alpha/mm/init.c196
-rw-r--r--arch/arm/Makefile4
-rw-r--r--arch/arm/boot/compressed/head-netwinder.S1
-rw-r--r--arch/arm/config.in1
-rw-r--r--arch/arm/def-configs/brutus3
-rw-r--r--arch/arm/def-configs/footbridge21
-rw-r--r--arch/arm/defconfig3
-rw-r--r--arch/arm/kernel/armksyms.c2
-rw-r--r--arch/arm/kernel/bios32.c27
-rw-r--r--arch/arm/kernel/bios32.h9
-rw-r--r--arch/arm/kernel/dec21285.c14
-rw-r--r--arch/arm/kernel/ecard.c6
-rw-r--r--arch/arm/kernel/entry-armv.S226
-rw-r--r--arch/arm/kernel/fiq.c2
-rw-r--r--arch/arm/kernel/head-armv.S1
-rw-r--r--arch/arm/kernel/hw-footbridge.c10
-rw-r--r--arch/arm/kernel/ioport.c1
-rw-r--r--arch/arm/kernel/process.c93
-rw-r--r--arch/arm/kernel/setup.c594
-rw-r--r--arch/arm/kernel/signal.c3
-rw-r--r--arch/arm/kernel/sys_arm.c201
-rw-r--r--arch/arm/kernel/traps.c13
-rw-r--r--arch/arm/lib/backtrace.S22
-rw-r--r--arch/arm/mm/init.c85
-rw-r--r--arch/arm/mm/ioremap.c4
-rw-r--r--arch/arm/mm/map.h1
-rw-r--r--arch/arm/mm/mm-armo.c16
-rw-r--r--arch/arm/mm/mm-armv.c96
-rw-r--r--arch/arm/mm/proc-arm2,3.S6
-rw-r--r--arch/arm/mm/proc-arm6,7.S8
-rw-r--r--arch/arm/mm/proc-sa110.S4
-rw-r--r--arch/arm/mm/small_page.c6
-rw-r--r--arch/i386/boot/Makefile2
-rw-r--r--arch/i386/boot/bootsect.S5
-rw-r--r--arch/i386/boot/compressed/misc.c4
-rw-r--r--arch/i386/boot/setup.S7
-rw-r--r--arch/i386/boot/video.S4
-rw-r--r--arch/i386/config.in6
-rw-r--r--arch/i386/defconfig33
-rw-r--r--arch/i386/kernel/apm.c6
-rw-r--r--arch/i386/kernel/entry.S6
-rw-r--r--arch/i386/kernel/i386_ksyms.c7
-rw-r--r--arch/i386/kernel/io_apic.c30
-rw-r--r--arch/i386/kernel/irq.c13
-rw-r--r--arch/i386/kernel/mca.c2
-rw-r--r--arch/i386/kernel/mtrr.c41
-rw-r--r--arch/i386/kernel/pci-i386.c6
-rw-r--r--arch/i386/kernel/pci-pc.c26
-rw-r--r--arch/i386/kernel/pci-visws.c2
-rw-r--r--arch/i386/kernel/process.c10
-rw-r--r--arch/i386/kernel/semaphore.c233
-rw-r--r--arch/i386/kernel/setup.c72
-rw-r--r--arch/i386/kernel/signal.c1
-rw-r--r--arch/i386/kernel/smp.c91
-rw-r--r--arch/i386/kernel/smpboot.c55
-rw-r--r--arch/i386/kernel/sys_i386.c63
-rw-r--r--arch/i386/kernel/time.c3
-rw-r--r--arch/i386/kernel/traps.c5
-rw-r--r--arch/i386/kernel/visws_apic.c2
-rw-r--r--arch/i386/kernel/vm86.c2
-rw-r--r--arch/i386/lib/usercopy.c1
-rw-r--r--arch/i386/mm/fault.c2
-rw-r--r--arch/i386/mm/init.c113
-rw-r--r--arch/i386/mm/ioremap.c17
-rw-r--r--arch/m68k/atari/stram.c17
-rw-r--r--arch/m68k/config.in1
-rw-r--r--arch/m68k/kernel/signal.c1
-rw-r--r--arch/m68k/kernel/sun3-head.S1
-rw-r--r--arch/m68k/kernel/sys_m68k.c82
-rw-r--r--arch/m68k/mac/iop.c10
-rw-r--r--arch/m68k/mac/macints.c1
-rw-r--r--arch/m68k/mac/psc.c1
-rw-r--r--arch/m68k/math-emu/fp_entry.S1
-rw-r--r--arch/m68k/math-emu/fp_util.S1
-rw-r--r--arch/m68k/mm/kmap.c2
-rw-r--r--arch/m68k/sun3/prom/console.c1
-rw-r--r--arch/m68k/sun3/prom/misc.c1
-rw-r--r--arch/m68k/sun3/sun3ints.c1
-rw-r--r--arch/mips/baget/irq.c6
-rw-r--r--arch/mips/config.in8
-rw-r--r--arch/mips/dec/irq.c6
-rw-r--r--arch/mips/defconfig31
-rw-r--r--arch/mips/kernel/irixelf.c4
-rw-r--r--arch/mips/kernel/irq.c10
-rw-r--r--arch/mips/kernel/mips_ksyms.c4
-rw-r--r--arch/mips/kernel/signal.c4
-rw-r--r--arch/mips/kernel/syscall.c40
-rw-r--r--arch/mips/kernel/syscalls.h10
-rw-r--r--arch/mips/kernel/sysirix.c45
-rw-r--r--arch/mips/mm/fault.c4
-rw-r--r--arch/mips/mm/init.c33
-rw-r--r--arch/mips/mm/umap.c2
-rw-r--r--arch/mips/sgi/kernel/indy_int.c18
-rw-r--r--arch/mips/sgi/kernel/indy_timer.c6
-rw-r--r--arch/mips64/config.in8
-rw-r--r--arch/mips64/defconfig33
-rw-r--r--arch/mips64/defconfig-ip2240
-rw-r--r--arch/mips64/defconfig-ip2733
-rw-r--r--arch/mips64/kernel/mips64_ksyms.c4
-rw-r--r--arch/mips64/kernel/scall_o32.S5
-rw-r--r--arch/mips64/kernel/setup.c3
-rw-r--r--arch/mips64/kernel/signal.c6
-rw-r--r--arch/mips64/kernel/syscall.c4
-rw-r--r--arch/mips64/mm/fault.c4
-rw-r--r--arch/mips64/mm/init.c32
-rw-r--r--arch/mips64/mm/umap.c4
-rw-r--r--arch/mips64/sgi-ip22/ip22-int.c18
-rw-r--r--arch/mips64/sgi-ip22/ip22-timer.c6
-rw-r--r--arch/mips64/sgi-ip27/ip27-irq.c6
-rw-r--r--arch/mips64/sgi-ip27/ip27-pci.c4
-rw-r--r--arch/ppc/8xx_io/commproc.c1
-rw-r--r--arch/ppc/8xx_io/commproc.h1
-rw-r--r--arch/ppc/8xx_io/enet.c1
-rw-r--r--arch/ppc/8xx_io/fec.c1
-rw-r--r--arch/ppc/Makefile74
-rw-r--r--arch/ppc/amiga/ints.c1
-rw-r--r--arch/ppc/boot/Makefile2
-rw-r--r--arch/ppc/boot/head.S8
-rw-r--r--arch/ppc/boot/misc.c39
-rw-r--r--arch/ppc/chrpboot/main.c28
-rw-r--r--arch/ppc/chrpboot/string.S206
-rw-r--r--arch/ppc/coffboot/Makefile67
-rw-r--r--arch/ppc/coffboot/chrpmain.c241
-rw-r--r--arch/ppc/coffboot/coffcrt0.S24
-rw-r--r--arch/ppc/coffboot/coffmain.c189
-rw-r--r--arch/ppc/coffboot/crt0.S4
-rw-r--r--arch/ppc/coffboot/main.c33
-rw-r--r--arch/ppc/coffboot/misc.S35
-rw-r--r--arch/ppc/coffboot/mknote.c43
-rw-r--r--arch/ppc/coffboot/no_initrd.c2
-rw-r--r--arch/ppc/coffboot/piggyback.c65
-rw-r--r--arch/ppc/coffboot/start.c56
-rw-r--r--arch/ppc/config.in82
-rw-r--r--arch/ppc/configs/apus_defconfig (renamed from arch/ppc/apus_defconfig)0
-rw-r--r--arch/ppc/configs/chrp_defconfig (renamed from arch/ppc/chrp_defconfig)0
-rw-r--r--arch/ppc/configs/common_defconfig (renamed from arch/ppc/common_defconfig)108
-rw-r--r--arch/ppc/configs/gemini_defconfig (renamed from arch/ppc/gemini_defconfig)91
-rw-r--r--arch/ppc/configs/mbx_defconfig (renamed from arch/ppc/mbx_defconfig)0
-rw-r--r--arch/ppc/configs/oak_defconfig293
-rw-r--r--arch/ppc/configs/pmac_defconfig (renamed from arch/ppc/pmac_defconfig)0
-rw-r--r--arch/ppc/configs/prep_defconfig (renamed from arch/ppc/prep_defconfig)0
-rw-r--r--arch/ppc/configs/walnut_defconfig293
-rw-r--r--arch/ppc/defconfig108
-rw-r--r--arch/ppc/kernel/Makefile72
-rw-r--r--arch/ppc/kernel/align.c52
-rw-r--r--arch/ppc/kernel/entry.S6
-rw-r--r--arch/ppc/kernel/gemini_prom.S1
-rw-r--r--arch/ppc/kernel/gemini_setup.c58
-rw-r--r--arch/ppc/kernel/head.S83
-rw-r--r--arch/ppc/kernel/head_4xx.S600
-rw-r--r--arch/ppc/kernel/misc.S49
-rw-r--r--arch/ppc/kernel/mk_defs.c10
-rw-r--r--arch/ppc/kernel/oak_setup.c84
-rw-r--r--arch/ppc/kernel/oak_setup.h32
-rw-r--r--arch/ppc/kernel/open_pic.c18
-rw-r--r--arch/ppc/kernel/open_pic.h1
-rw-r--r--arch/ppc/kernel/pci.c46
-rw-r--r--arch/ppc/kernel/pmac_nvram.c (renamed from arch/ppc/kernel/pmac_support.c)7
-rw-r--r--arch/ppc/kernel/pmac_pci.c25
-rw-r--r--arch/ppc/kernel/ppc8xx_pic.c2
-rw-r--r--arch/ppc/kernel/ppc8xx_pic.h2
-rw-r--r--arch/ppc/kernel/ppc_asm.h23
-rw-r--r--arch/ppc/kernel/ppc_asm.tmpl18
-rw-r--r--arch/ppc/kernel/ppc_htab.c19
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c16
-rw-r--r--arch/ppc/kernel/prep_setup.c16
-rw-r--r--arch/ppc/kernel/process.c10
-rw-r--r--arch/ppc/kernel/prom.c5
-rw-r--r--arch/ppc/kernel/qspan_pci.c1
-rw-r--r--arch/ppc/kernel/setup.c176
-rw-r--r--arch/ppc/kernel/signal.c1
-rw-r--r--arch/ppc/kernel/smp.c8
-rw-r--r--arch/ppc/kernel/traps.c17
-rw-r--r--arch/ppc/lib/checksum.S7
-rw-r--r--arch/ppc/mm/Makefile6
-rw-r--r--arch/ppc/mm/fault.c34
-rw-r--r--arch/ppc/mm/init.c337
-rw-r--r--arch/ppc/mm/mem_pieces.c224
-rw-r--r--arch/ppc/mm/mem_pieces.h61
-rw-r--r--arch/ppc/treeboot/Makefile62
-rw-r--r--arch/ppc/treeboot/crt0.S70
-rw-r--r--arch/ppc/treeboot/elf.pl33
-rw-r--r--arch/ppc/treeboot/irSect.c36
-rw-r--r--arch/ppc/treeboot/irSect.h32
-rw-r--r--arch/ppc/treeboot/ld.script68
-rw-r--r--arch/ppc/treeboot/main.c209
-rw-r--r--arch/ppc/treeboot/misc.S28
-rw-r--r--arch/ppc/treeboot/mkevimg437
-rw-r--r--arch/ppc/treeboot/mkirimg367
-rw-r--r--arch/ppc/xmon/ppc-opc.c3
-rw-r--r--arch/ppc/xmon/privinst.h9
-rw-r--r--arch/ppc/xmon/start.c4
-rw-r--r--arch/ppc/xmon/xmon.c29
-rw-r--r--arch/sh/defconfig3
-rw-r--r--arch/sh/kernel/irq_onchip.c1
-rw-r--r--arch/sh/kernel/signal.c1
-rw-r--r--arch/sh/mm/ioremap.c2
-rw-r--r--arch/sparc/config.in1
-rw-r--r--arch/sparc/defconfig1
-rw-r--r--arch/sparc/kernel/signal.c3
-rw-r--r--arch/sparc/math-emu/math.c8
-rw-r--r--arch/sparc/math-emu/sfp-machine.h205
-rw-r--r--arch/sparc/mm/generic.c2
-rw-r--r--arch/sparc64/config.in1
-rw-r--r--arch/sparc64/defconfig4
-rw-r--r--arch/sparc64/kernel/signal.c3
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c16
-rw-r--r--arch/sparc64/kernel/trampoline.S2
-rw-r--r--arch/sparc64/math-emu/math.c8
-rw-r--r--arch/sparc64/math-emu/sfp-machine.h91
-rw-r--r--arch/sparc64/mm/generic.c2
-rw-r--r--arch/sparc64/mm/ultra.S2
269 files changed, 9216 insertions, 4928 deletions
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile
index 90013b3fb..28ba0dd51 100644
--- a/arch/alpha/Makefile
+++ b/arch/alpha/Makefile
@@ -59,27 +59,14 @@ ifeq ($(have_mcpu),y)
endif
# For TSUNAMI, we must have the assembler not emulate our instructions.
-# The same is true for POLARIS, and now PYXIS.
+# The same is true for IRONGATE, POLARIS, PYXIS.
# BWX is most important, but we don't really want any emulation ever.
+
ifeq ($(old_gas),y)
- ifneq ($(CONFIG_ALPHA_GENERIC)$(CONFIG_ALPHA_TSUNAMI)$(CONFIG_ALPHA_POLARIS)$(CONFIG_ALPHA_PYXIS),)
- # How do we do #error in make?
- CFLAGS := --error-please-upgrade-your-assembler
- endif
-else
- ifeq ($(CONFIG_ALPHA_GENERIC),y)
- CFLAGS := $(CFLAGS) -Wa,-mev6
- endif
- ifeq ($(CONFIG_ALPHA_PYXIS),y)
- CFLAGS := $(CFLAGS) -Wa,-m21164a
- endif
- ifeq ($(CONFIG_ALPHA_POLARIS),y)
- CFLAGS := $(CFLAGS) -Wa,-m21164pc
- endif
- ifeq ($(CONFIG_ALPHA_TSUNAMI),y)
- CFLAGS := $(CFLAGS) -Wa,-mev6
- endif
+ # How do we do #error in make?
+ CFLAGS := --error-please-upgrade-your-assembler
endif
+CFLAGS := $(CFLAGS) -Wa,-mev6
HEAD := arch/alpha/kernel/head.o
diff --git a/arch/alpha/boot/bootp.c b/arch/alpha/boot/bootp.c
index 90fccb766..bb892ba3c 100644
--- a/arch/alpha/boot/bootp.c
+++ b/arch/alpha/boot/bootp.c
@@ -200,11 +200,11 @@ start_kernel(void)
load(START_ADDR+(4*KERNEL_SIZE), KERNEL_ORIGIN, KERNEL_SIZE);
load(START_ADDR, START_ADDR+(4*KERNEL_SIZE), KERNEL_SIZE);
- memset((char*)ZERO_PAGE(0), 0, PAGE_SIZE);
- strcpy((char*)ZERO_PAGE(0), envval);
+ memset((char*)ZERO_PGE, 0, PAGE_SIZE);
+ strcpy((char*)ZERO_PGE, envval);
#ifdef INITRD_SIZE
- ((long *)(ZERO_PAGE(0)+256))[0] = initrd_start;
- ((long *)(ZERO_PAGE(0)+256))[1] = INITRD_SIZE;
+ ((long *)(ZERO_PGE+256))[0] = initrd_start;
+ ((long *)(ZERO_PGE+256))[1] = INITRD_SIZE;
#endif
runkernel();
diff --git a/arch/alpha/boot/main.c b/arch/alpha/boot/main.c
index c97896e8b..07913d899 100644
--- a/arch/alpha/boot/main.c
+++ b/arch/alpha/boot/main.c
@@ -182,7 +182,7 @@ void start_kernel(void)
nbytes = 0;
}
envval[nbytes] = '\0';
- strcpy((char*)ZERO_PAGE(0), envval);
+ strcpy((char*)ZERO_PGE, envval);
srm_printk(" Ok\nNow booting the kernel\n");
runkernel();
diff --git a/arch/alpha/config.in b/arch/alpha/config.in
index f6dc93f61..35e9edeb0 100644
--- a/arch/alpha/config.in
+++ b/arch/alpha/config.in
@@ -33,10 +33,12 @@ choice 'Alpha system type' \
EB64+ CONFIG_ALPHA_EB64P \
EB66 CONFIG_ALPHA_EB66 \
EB66+ CONFIG_ALPHA_EB66P \
+ Eiger CONFIG_ALPHA_EIGER \
Jensen CONFIG_ALPHA_JENSEN \
LX164 CONFIG_ALPHA_LX164 \
Miata CONFIG_ALPHA_MIATA \
Mikasa CONFIG_ALPHA_MIKASA \
+ Nautilus CONFIG_ALPHA_NAUTILUS \
Noname CONFIG_ALPHA_NONAME \
Noritake CONFIG_ALPHA_NORITAKE \
PC164 CONFIG_ALPHA_PC164 \
@@ -54,6 +56,7 @@ unset CONFIG_PCI CONFIG_ALPHA_EISA
unset CONFIG_ALPHA_LCA CONFIG_ALPHA_APECS CONFIG_ALPHA_CIA
unset CONFIG_ALPHA_T2 CONFIG_ALPHA_PYXIS CONFIG_ALPHA_POLARIS
unset CONFIG_ALPHA_TSUNAMI CONFIG_ALPHA_MCPCIA
+unset CONFIG_ALPHA_IRONGATE
if [ "$CONFIG_ALPHA_GENERIC" = "y" ]
then
@@ -117,7 +120,7 @@ then
define_bool CONFIG_ALPHA_EV5 y
define_bool CONFIG_ALPHA_PYXIS y
fi
-if [ "$CONFIG_ALPHA_DP264" = "y" ]
+if [ "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_EIGER" = "y" ]
then
define_bool CONFIG_PCI y
define_bool CONFIG_ALPHA_EV6 y
@@ -139,6 +142,12 @@ if [ "$CONFIG_ALPHA_JENSEN" = "y" ]
then
define_bool CONFIG_ALPHA_EV4 y
fi
+if [ "$CONFIG_ALPHA_NAUTILUS" = "y" ]
+then
+ define_bool CONFIG_PCI y
+ define_bool CONFIG_ALPHA_EV6 y
+ define_bool CONFIG_ALPHA_IRONGATE y
+fi
if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \
-o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_JENSEN" = "y" \
@@ -147,7 +156,8 @@ if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \
-o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_MIATA" = "y" \
-o "$CONFIG_ALPHA_NORITAKE" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
-o "$CONFIG_ALPHA_LX164" = "y" -o "$CONFIG_ALPHA_SX164" = "y" \
- -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" ]
+ -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \
+ -o "$CONFIG_ALPHA_EIGER" = "y" ]
then
bool 'Use SRM as bootloader' CONFIG_ALPHA_SRM
fi
@@ -168,6 +178,8 @@ then
bool 'Symmetric multi-processing support' CONFIG_SMP
fi
+source drivers/pci/Config.in
+
bool 'Networking support' CONFIG_NET
bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
@@ -244,11 +256,10 @@ if [ "$CONFIG_VT" = "y" ]; then
mainmenu_option next_comment
comment 'Console drivers'
bool 'VGA text console' CONFIG_VGA_CONSOLE
- bool 'Support for frame buffer devices' CONFIG_FB
+ source drivers/video/Config.in
if [ "$CONFIG_FB" = "y" ]; then
define_bool CONFIG_PCI_CONSOLE y
fi
- source drivers/video/Config.in
endmenu
fi
diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig
index 54a05ea5a..ba6f0070b 100644
--- a/arch/alpha/defconfig
+++ b/arch/alpha/defconfig
@@ -32,6 +32,7 @@ CONFIG_ALPHA_GENERIC=y
# CONFIG_ALPHA_LX164 is not set
# CONFIG_ALPHA_MIATA is not set
# CONFIG_ALPHA_MIKASA is not set
+# CONFIG_ALPHA_NAUTILUS is not set
# CONFIG_ALPHA_NONAME is not set
# CONFIG_ALPHA_NORITAKE is not set
# CONFIG_ALPHA_PC164 is not set
@@ -43,6 +44,7 @@ CONFIG_ALPHA_GENERIC=y
# CONFIG_ALPHA_SABLE is not set
# CONFIG_ALPHA_TAKARA is not set
CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
# CONFIG_SMP is not set
CONFIG_NET=y
CONFIG_SYSVIPC=y
diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile
index 282147e72..9210ae57c 100644
--- a/arch/alpha/kernel/Makefile
+++ b/arch/alpha/kernel/Makefile
@@ -12,22 +12,20 @@
.S.o:
$(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $<
-all: kernel.o head.o
-
O_TARGET := kernel.o
O_OBJS := entry.o traps.o process.o osf_sys.o irq.o signal.o setup.o \
- ptrace.o time.o fpreg.o semaphore.o
+ ptrace.o time.o semaphore.o
OX_OBJS := alpha_ksyms.o
ifdef CONFIG_ALPHA_GENERIC
-O_OBJS += core_apecs.o core_cia.o core_lca.o core_mcpcia.o core_pyxis.o \
- core_t2.o core_tsunami.o core_polaris.o \
- sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o \
- sys_jensen.o sys_miata.o sys_mikasa.o sys_noritake.o \
- sys_rawhide.o sys_ruffian.o sys_sable.o sys_sio.o \
- sys_sx164.o sys_takara.o sys_rx164.o \
+O_OBJS += core_apecs.o core_cia.o core_irongate.o core_lca.o core_mcpcia.o \
+ core_polaris.o core_pyxis.o core_t2.o core_tsunami.o \
+ sys_alcor.o sys_cabriolet.o sys_dp264.o sys_eb64p.o sys_eiger.o \
+ sys_jensen.o sys_miata.o sys_mikasa.o sys_nautilus.o \
+ sys_noritake.o sys_rawhide.o sys_ruffian.o sys_rx164.o \
+ sys_sable.o sys_sio.o sys_sx164.o sys_takara.o sys_rx164.o \
es1888.o smc37c669.o smc37c93x.o ns87312.o pci.o
else
@@ -42,6 +40,9 @@ endif
ifdef CONFIG_ALPHA_CIA
O_OBJS += core_cia.o
endif
+ifdef CONFIG_ALPHA_IRONGATE
+O_OBJS += core_irongate.o
+endif
ifdef CONFIG_ALPHA_LCA
O_OBJS += core_lca.o
endif
@@ -74,6 +75,9 @@ endif
ifneq ($(CONFIG_ALPHA_EB64P)$(CONFIG_ALPHA_EB66),)
O_OBJS += sys_eb64p.o
endif
+ifdef CONFIG_ALPHA_EIGER
+O_OBJS += sys_eiger.o
+endif
ifdef CONFIG_ALPHA_JENSEN
O_OBJS += sys_jensen.o
endif
@@ -83,6 +87,9 @@ endif
ifdef CONFIG_ALPHA_MIKASA
O_OBJS += sys_mikasa.o
endif
+ifdef CONFIG_ALPHA_NAUTILUS
+O_OBJS += sys_nautilus.o
+endif
ifdef CONFIG_ALPHA_NORITAKE
O_OBJS += sys_noritake.o
endif
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c
index ffd93ca9d..ef8be067c 100644
--- a/arch/alpha/kernel/alpha_ksyms.c
+++ b/arch/alpha/kernel/alpha_ksyms.c
@@ -27,7 +27,7 @@
#include <asm/fpu.h>
#include <asm/irq.h>
#include <asm/machvec.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/semaphore.h>
#define __KERNEL_SYSCALLS__
@@ -103,7 +103,9 @@ EXPORT_SYMBOL(hwrpb);
EXPORT_SYMBOL(wrusp);
EXPORT_SYMBOL(start_thread);
EXPORT_SYMBOL(alpha_read_fp_reg);
+EXPORT_SYMBOL(alpha_read_fp_reg_s);
EXPORT_SYMBOL(alpha_write_fp_reg);
+EXPORT_SYMBOL(alpha_write_fp_reg_s);
/* In-kernel system calls. */
EXPORT_SYMBOL(kernel_thread);
@@ -123,6 +125,7 @@ EXPORT_SYMBOL(csum_tcpudp_magic);
EXPORT_SYMBOL(ip_compute_csum);
EXPORT_SYMBOL(ip_fast_csum);
EXPORT_SYMBOL(csum_partial_copy);
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
EXPORT_SYMBOL(csum_partial_copy_from_user);
EXPORT_SYMBOL(csum_ipv6_magic);
diff --git a/arch/alpha/kernel/core_apecs.c b/arch/alpha/kernel/core_apecs.c
index 6a402a3e1..04e556f2e 100644
--- a/arch/alpha/kernel/core_apecs.c
+++ b/arch/alpha/kernel/core_apecs.c
@@ -357,7 +357,7 @@ struct pci_ops apecs_pci_ops =
};
void __init
-apecs_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+apecs_init_arch(void)
{
struct pci_controler *hose;
@@ -386,7 +386,7 @@ apecs_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = APECS_CONF;
diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
index 4e773862b..9f628bff6 100644
--- a/arch/alpha/kernel/core_cia.c
+++ b/arch/alpha/kernel/core_cia.c
@@ -315,7 +315,7 @@ struct pci_ops cia_pci_ops =
};
void __init
-cia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+cia_init_arch(void)
{
struct pci_controler *hose;
struct resource *hae_mem;
@@ -424,8 +424,8 @@ cia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
- hae_mem = alloc_resource(mem_start);
+ hose = alloc_pci_controler();
+ hae_mem = alloc_resource();
hose->io_space = &ioport_resource;
hose->mem_space = hae_mem;
@@ -435,8 +435,10 @@ cia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
hae_mem->start = 0;
hae_mem->end = CIA_MEM_R1_MASK;
hae_mem->name = pci_hae0_name;
+ hae_mem->flags = IORESOURCE_MEM;
- request_resource(&iomem_resource, hae_mem);
+ if (request_resource(&iomem_resource, hae_mem) < 0)
+ printk(KERN_ERR "Failed to request HAE_MEM\n");
}
static inline void
diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c
new file mode 100644
index 000000000..ef686277c
--- /dev/null
+++ b/arch/alpha/kernel/core_irongate.c
@@ -0,0 +1,353 @@
+/*
+ * linux/arch/alpha/kernel/core_irongate.c
+ *
+ * Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com).
+ *
+ * Copyright (C) 1999 Alpha Processor, Inc.,
+ * (David Daniel, Stig Telfer, Soohoon Lee)
+ *
+ * Code common to all IRONGATE core logic chips.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/pci.h>
+#include <asm/hwrpb.h>
+
+#define __EXTERN_INLINE inline
+#include <asm/io.h>
+#include <asm/core_irongate.h>
+#undef __EXTERN_INLINE
+
+#include "proto.h"
+#include "pci_impl.h"
+
+
+/*
+ * NOTE: Herein lie back-to-back mb instructions. They are magic.
+ * One plausible explanation is that the I/O controller does not properly
+ * handle the system transaction. Another involves timing. Ho hum.
+ */
+
+/*
+ * BIOS32-style PCI interface:
+ */
+
+#define DEBUG_CONFIG 0
+
+#if DEBUG_CONFIG
+# define DBG_CFG(args) printk args
+#else
+# define DBG_CFG(args)
+#endif
+
+
+/*
+ * Given a bus, device, and function number, compute resulting
+ * configuration space address accordingly. It is therefore not safe
+ * to have concurrent invocations to configuration space access
+ * routines, but there really shouldn't be any need for this.
+ *
+ * addr[31:24] reserved
+ * addr[23:16] bus number (8 bits = 128 possible buses)
+ * addr[15:11] Device number (5 bits)
+ * addr[10: 8] function number
+ * addr[ 7: 2] register number
+ *
+ * For IRONGATE:
+ * if (bus = addr[23:16]) == 0
+ * then
+ * type 0 config cycle:
+ * addr_on_pci[31:11] = id selection for device = addr[15:11]
+ * addr_on_pci[10: 2] = addr[10: 2] ???
+ * addr_on_pci[ 1: 0] = 00
+ * else
+ * type 1 config cycle (pass on with no decoding):
+ * addr_on_pci[31:24] = 0
+ * addr_on_pci[23: 2] = addr[23: 2]
+ * addr_on_pci[ 1: 0] = 01
+ * fi
+ *
+ * Notes:
+ * The function number selects which function of a multi-function device
+ * (e.g., SCSI and Ethernet).
+ *
+ * The register selects a DWORD (32 bit) register offset. Hence it
+ * doesn't get shifted by 2 bits as we want to "drop" the bottom two
+ * bits.
+ */
+
+static int
+mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
+ unsigned char *type1)
+{
+ unsigned long addr;
+ u8 bus = dev->bus->number;
+ u8 device_fn = dev->devfn;
+
+ DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
+ "pci_addr=0x%p, type1=0x%p)\n",
+ bus, device_fn, where, pci_addr, type1));
+
+ *type1 = (bus != 0);
+
+ addr = (bus << 16) | (device_fn << 8) | where;
+ addr |= IRONGATE_CONF;
+
+ *pci_addr = addr;
+ DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+ return 0;
+}
+
+static int
+irongate_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = __kernel_ldbu(*(vucp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = __kernel_ldwu(*(vusp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *value = *(vuip)addr;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ __kernel_stb(value, *(vucp)addr);
+ mb();
+ __kernel_ldbu(*(vucp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ __kernel_stw(value, *(vusp)addr);
+ mb();
+ __kernel_ldwu(*(vusp)addr);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+irongate_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ unsigned long addr;
+ unsigned char type1;
+
+ if (mk_conf_addr(dev, where, &addr, &type1))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ *(vuip)addr = value;
+ mb();
+ *(vuip)addr;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+struct pci_ops irongate_pci_ops =
+{
+ read_byte: irongate_read_config_byte,
+ read_word: irongate_read_config_word,
+ read_dword: irongate_read_config_dword,
+ write_byte: irongate_write_config_byte,
+ write_word: irongate_write_config_word,
+ write_dword: irongate_write_config_dword
+};
+
+#if 0
+static void
+irongate_register_dump(const char *function_name)
+{
+ printk("%s: Irongate registers:\n"
+ "\tdev_vendor\t0x%08x\n"
+ "\tstat_cmd\t0x%08x\n"
+ "\tclass\t\t0x%08x\n"
+ "\tlatency\t\t0x%08x\n"
+ "\tbar0\t\t0x%08x\n"
+ "\tbar1\t\t0x%08x\n"
+ "\tbar2\t\t0x%08x\n"
+ "\trsrvd0[0]\t0x%08x\n"
+ "\trsrvd0[1]\t0x%08x\n"
+ "\trsrvd0[2]\t0x%08x\n"
+ "\trsrvd0[3]\t0x%08x\n"
+ "\trsrvd0[4]\t0x%08x\n"
+ "\trsrvd0[5]\t0x%08x\n"
+ "\tcapptr\t\t0x%08x\n"
+ "\trsrvd1[0]\t0x%08x\n"
+ "\trsrvd1[1]\t0x%08x\n"
+ "\tbacsr10\t\t0x%08x\n"
+ "\tbacsr32\t\t0x%08x\n"
+ "\tbacsr54\t\t0x%08x\n"
+ "\trsrvd2[0]\t0x%08x\n"
+ "\tdrammap\t\t0x%08x\n"
+ "\tdramtm\t\t0x%08x\n"
+ "\tdramms\t\t0x%08x\n"
+ "\trsrvd3[0]\t0x%08x\n"
+ "\tbiu0\t\t0x%08x\n"
+ "\tbiusip\t\t0x%08x\n"
+ "\trsrvd4[0]\t0x%08x\n"
+ "\trsrvd4[1]\t0x%08x\n"
+ "\tmro\t\t0x%08x\n"
+ "\trsrvd5[0]\t0x%08x\n"
+ "\trsrvd5[1]\t0x%08x\n"
+ "\trsrvd5[2]\t0x%08x\n"
+ "\twhami\t\t0x%08x\n"
+ "\tpciarb\t\t0x%08x\n"
+ "\tpcicfg\t\t0x%08x\n"
+ "\trsrvd6[0]\t0x%08x\n"
+ "\trsrvd6[1]\t0x%08x\n"
+ "\trsrvd6[2]\t0x%08x\n"
+ "\trsrvd6[3]\t0x%08x\n"
+ "\trsrvd6[4]\t0x%08x\n"
+ "\tagpcap\t\t0x%08x\n"
+ "\tagpstat\t\t0x%08x\n"
+ "\tagpcmd\t\t0x%08x\n"
+ "\tagpva\t\t0x%08x\n"
+ "\tagpmode\t\t0x%08x\n",
+ function_name,
+ IRONGATE0->dev_vendor,
+ IRONGATE0->stat_cmd,
+ IRONGATE0->class,
+ IRONGATE0->latency,
+ IRONGATE0->bar0,
+ IRONGATE0->bar1,
+ IRONGATE0->bar2,
+ IRONGATE0->rsrvd0[0],
+ IRONGATE0->rsrvd0[1],
+ IRONGATE0->rsrvd0[2],
+ IRONGATE0->rsrvd0[3],
+ IRONGATE0->rsrvd0[4],
+ IRONGATE0->rsrvd0[5],
+ IRONGATE0->capptr,
+ IRONGATE0->rsrvd1[0],
+ IRONGATE0->rsrvd1[1],
+ IRONGATE0->bacsr10,
+ IRONGATE0->bacsr32,
+ IRONGATE0->bacsr54,
+ IRONGATE0->rsrvd2[0],
+ IRONGATE0->drammap,
+ IRONGATE0->dramtm,
+ IRONGATE0->dramms,
+ IRONGATE0->rsrvd3[0],
+ IRONGATE0->biu0,
+ IRONGATE0->biusip,
+ IRONGATE0->rsrvd4[0],
+ IRONGATE0->rsrvd4[1],
+ IRONGATE0->mro,
+ IRONGATE0->rsrvd5[0],
+ IRONGATE0->rsrvd5[1],
+ IRONGATE0->rsrvd5[2],
+ IRONGATE0->whami,
+ IRONGATE0->pciarb,
+ IRONGATE0->pcicfg,
+ IRONGATE0->rsrvd6[0],
+ IRONGATE0->rsrvd6[1],
+ IRONGATE0->rsrvd6[2],
+ IRONGATE0->rsrvd6[3],
+ IRONGATE0->rsrvd6[4],
+ IRONGATE0->agpcap,
+ IRONGATE0->agpstat,
+ IRONGATE0->agpcmd,
+ IRONGATE0->agpva,
+ IRONGATE0->agpmode);
+}
+#else
+#define irongate_register_dump(x)
+#endif
+
+int
+irongate_pci_clr_err(void)
+{
+ unsigned int nmi_ctl=0;
+ unsigned int IRONGATE_jd;
+
+again:
+ IRONGATE_jd = IRONGATE0->stat_cmd;
+ printk("Iron stat_cmd %x\n", IRONGATE_jd);
+ IRONGATE0->stat_cmd = IRONGATE_jd; /* write again clears error bits */
+ mb();
+ IRONGATE_jd = IRONGATE0->stat_cmd; /* re-read to force write */
+
+ IRONGATE_jd = IRONGATE0->dramms;
+ printk("Iron dramms %x\n", IRONGATE_jd);
+ IRONGATE0->dramms = IRONGATE_jd; /* write again clears error bits */
+ mb();
+ IRONGATE_jd = IRONGATE0->dramms; /* re-read to force write */
+
+ /* Clear ALI NMI */
+ nmi_ctl = inb(0x61);
+ nmi_ctl |= 0x0c;
+ outb(nmi_ctl, 0x61);
+ nmi_ctl &= ~0x0c;
+ outb(nmi_ctl, 0x61);
+
+ IRONGATE_jd = IRONGATE0->dramms;
+ if (IRONGATE_jd & 0x300) goto again;
+
+ return 0;
+}
+
+void __init
+irongate_init_arch(void)
+{
+ struct pci_controler *hose;
+
+ irongate_pci_clr_err();
+ irongate_register_dump(__FUNCTION__);
+
+ /*
+ * Create our single hose.
+ */
+
+ hose = alloc_pci_controler();
+ hose->io_space = &ioport_resource;
+ hose->mem_space = &iomem_resource;
+ hose->config_space = IRONGATE_CONF;
+ hose->index = 0;
+}
diff --git a/arch/alpha/kernel/core_lca.c b/arch/alpha/kernel/core_lca.c
index 8b87f8afa..266023f77 100644
--- a/arch/alpha/kernel/core_lca.c
+++ b/arch/alpha/kernel/core_lca.c
@@ -279,7 +279,7 @@ struct pci_ops lca_pci_ops =
};
void __init
-lca_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+lca_init_arch(void)
{
struct pci_controler *hose;
@@ -307,7 +307,7 @@ lca_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = LCA_CONF;
diff --git a/arch/alpha/kernel/core_mcpcia.c b/arch/alpha/kernel/core_mcpcia.c
index 1222556d3..b4fe28849 100644
--- a/arch/alpha/kernel/core_mcpcia.c
+++ b/arch/alpha/kernel/core_mcpcia.c
@@ -43,7 +43,7 @@
# define DBG_CFG(args)
#endif
-#define MCPCIA_MAX_HOSES 2
+#define MCPCIA_MAX_HOSES 4
/* Dodge has PCI0 and PCI1 at MID 4 and 5 respectively. Durango adds
PCI2 and PCI3 at MID 6 and 7 respectively. */
@@ -205,7 +205,7 @@ mk_conf_addr(struct pci_dev *dev, int where, struct pci_controler *hose,
static int
mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr, w;
unsigned char type1;
@@ -221,7 +221,7 @@ mcpcia_read_config_byte(struct pci_dev *dev, int where, u8 *value)
static int
mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr, w;
unsigned char type1;
@@ -237,7 +237,7 @@ mcpcia_read_config_word(struct pci_dev *dev, int where, u16 *value)
static int
mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr;
unsigned char type1;
@@ -252,7 +252,7 @@ mcpcia_read_config_dword(struct pci_dev *dev, int where, u32 *value)
static int
mcpcia_write_config(struct pci_dev *dev, int where, u32 value, long mask)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr;
unsigned char type1;
@@ -305,6 +305,7 @@ mcpcia_probe_hose(int h)
mb();
mb();
draina();
+ wrmces(7);
mcheck_expected(cpu) = 1;
mcheck_taken(cpu) = 0;
mcheck_extra(cpu) = mid;
@@ -327,16 +328,16 @@ mcpcia_probe_hose(int h)
}
static void __init
-mcpcia_new_hose(unsigned long *mem_start, int h)
+mcpcia_new_hose(int h)
{
struct pci_controler *hose;
struct resource *io, *mem, *hae_mem;
int mid = hose2mid(h);
- hose = alloc_pci_controler(mem_start);
- io = alloc_resource(mem_start);
- mem = alloc_resource(mem_start);
- hae_mem = alloc_resource(mem_start);
+ hose = alloc_pci_controler();
+ io = alloc_resource();
+ mem = alloc_resource();
+ hae_mem = alloc_resource();
hose->io_space = io;
hose->mem_space = hae_mem;
@@ -346,18 +347,33 @@ mcpcia_new_hose(unsigned long *mem_start, int h)
io->start = MCPCIA_IO(mid) - MCPCIA_IO_BIAS;
io->end = io->start + 0xffff;
io->name = pci_io_names[h];
+ io->flags = IORESOURCE_IO;
mem->start = MCPCIA_DENSE(mid) - MCPCIA_MEM_BIAS;
mem->end = mem->start + 0xffffffff;
mem->name = pci_mem_names[h];
+ mem->flags = IORESOURCE_MEM;
hae_mem->start = mem->start;
hae_mem->end = mem->start + MCPCIA_MEM_MASK;
hae_mem->name = pci_hae0_name;
+ hae_mem->flags = IORESOURCE_MEM;
+
+ if (request_resource(&ioport_resource, io) < 0)
+ printk(KERN_ERR "Failed to request IO on hose %d\n", h);
+ if (request_resource(&iomem_resource, mem) < 0)
+ printk(KERN_ERR "Failed to request MEM on hose %d\n", h);
+ if (request_resource(mem, hae_mem) < 0)
+ printk(KERN_ERR "Failed to request HAE_MEM on hose %d\n", h);
+}
- request_resource(&ioport_resource, io);
- request_resource(&iomem_resource, mem);
- request_resource(mem, hae_mem);
+static void
+mcpcia_pci_clr_err(int mid)
+{
+ *(vuip)MCPCIA_CAP_ERR(mid);
+ *(vuip)MCPCIA_CAP_ERR(mid) = 0xffffffff; /* Clear them all. */
+ mb();
+ *(vuip)MCPCIA_CAP_ERR(mid); /* Re-read for force write. */
}
static void __init
@@ -366,19 +382,13 @@ mcpcia_startup_hose(struct pci_controler *hose)
int mid = hose2mid(hose->index);
unsigned int tmp;
+ mcpcia_pci_clr_err(mid);
+
/*
- * Set up error reporting. Make sure CPU_PE is OFF in the mask.
+ * Set up error reporting.
*/
-#if 0
- tmp = *(vuip)MCPCIA_ERR_MASK(mid);
- tmp &= ~4;
- *(vuip)MCPCIA_ERR_MASK(mid) = tmp;
- mb();
- tmp = *(vuip)MCPCIA_ERR_MASK(mid);
-#endif
-
tmp = *(vuip)MCPCIA_CAP_ERR(mid);
- tmp |= 0x0006; /* master/target abort */
+ tmp |= 0x0006; /* master/target abort */
*(vuip)MCPCIA_CAP_ERR(mid) = tmp;
mb();
tmp = *(vuip)MCPCIA_CAP_ERR(mid);
@@ -420,29 +430,39 @@ mcpcia_startup_hose(struct pci_controler *hose)
}
void __init
-mcpcia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+mcpcia_init_arch(void)
{
- extern asmlinkage void entInt(void);
- struct pci_controler *hose;
- int h, hose_count = 0;
-
- /* Ho hum.. init_arch is called before init_IRQ, but we need to be
- able to handle machine checks. So install the handler now. */
- wrent(entInt, 0);
-
/* With multiple PCI busses, we play with I/O as physical addrs. */
ioport_resource.end = ~0UL;
iomem_resource.end = ~0UL;
+ /* Allocate hose 0. That's the one that all the ISA junk hangs
+ off of, from which we'll be registering stuff here in a bit.
+ Other hose detection is done in mcpcia_init_hoses, which is
+ called from init_IRQ. */
+
+ mcpcia_new_hose(0);
+}
+
+/* This is called from init_IRQ, since we cannot take interrupts
+ before then. Which means we cannot do this in init_arch. */
+
+void __init
+mcpcia_init_hoses(void)
+{
+ struct pci_controler *hose;
+ int h, hose_count = 0;
+
/* First, find how many hoses we have. */
for (h = 0; h < MCPCIA_MAX_HOSES; ++h) {
if (mcpcia_probe_hose(h)) {
- mcpcia_new_hose(mem_start, h);
+ if (h != 0)
+ mcpcia_new_hose(h);
hose_count++;
}
}
- printk("mcpcia_init_arch: found %d hoses\n", hose_count);
+ printk("mcpcia_init_hoses: found %d hoses\n", hose_count);
/* Now do init for each hose. */
for (hose = hose_head; hose; hose = hose->next)
@@ -450,15 +470,6 @@ mcpcia_init_arch(unsigned long *mem_start, unsigned long *mem_end)
}
static void
-mcpcia_pci_clr_err(int mid)
-{
- *(vuip)MCPCIA_CAP_ERR(mid);
- *(vuip)MCPCIA_CAP_ERR(mid) = 0xffffffff; /* Clear them all. */
- mb();
- *(vuip)MCPCIA_CAP_ERR(mid); /* Re-read for force write. */
-}
-
-static void
mcpcia_print_uncorrectable(struct el_MCPCIA_uncorrected_frame_mcheck *logout)
{
struct el_common_EV5_uncorrectable_mcheck *frame;
@@ -468,65 +479,65 @@ mcpcia_print_uncorrectable(struct el_MCPCIA_uncorrected_frame_mcheck *logout)
/* Print PAL fields */
for (i = 0; i < 24; i += 2) {
- printk("\tpal temp[%d-%d]\t\t= %16lx %16lx\n\r",
+ printk(" paltmp[%d-%d] = %16lx %16lx\n",
i, i+1, frame->paltemp[i], frame->paltemp[i+1]);
}
for (i = 0; i < 8; i += 2) {
- printk("\tshadow[%d-%d]\t\t= %16lx %16lx\n\r",
+ printk(" shadow[%d-%d] = %16lx %16lx\n",
i, i+1, frame->shadow[i],
frame->shadow[i+1]);
}
- printk("\tAddr of excepting instruction\t= %16lx\n\r",
+ printk(" Addr of excepting instruction = %16lx\n",
frame->exc_addr);
- printk("\tSummary of arithmetic traps\t= %16lx\n\r",
+ printk(" Summary of arithmetic traps = %16lx\n",
frame->exc_sum);
- printk("\tException mask\t\t\t= %16lx\n\r",
+ printk(" Exception mask = %16lx\n",
frame->exc_mask);
- printk("\tBase address for PALcode\t= %16lx\n\r",
+ printk(" Base address for PALcode = %16lx\n",
frame->pal_base);
- printk("\tInterrupt Status Reg\t\t= %16lx\n\r",
+ printk(" Interrupt Status Reg = %16lx\n",
frame->isr);
- printk("\tCURRENT SETUP OF EV5 IBOX\t= %16lx\n\r",
+ printk(" CURRENT SETUP OF EV5 IBOX = %16lx\n",
frame->icsr);
- printk("\tI-CACHE Reg %s parity error\t= %16lx\n\r",
+ printk(" I-CACHE Reg %s parity error = %16lx\n",
(frame->ic_perr_stat & 0x800L) ?
"Data" : "Tag",
frame->ic_perr_stat);
- printk("\tD-CACHE error Reg\t\t= %16lx\n\r",
+ printk(" D-CACHE error Reg = %16lx\n",
frame->dc_perr_stat);
if (frame->dc_perr_stat & 0x2) {
switch (frame->dc_perr_stat & 0x03c) {
case 8:
- printk("\t\tData error in bank 1\n\r");
+ printk(" Data error in bank 1\n");
break;
case 4:
- printk("\t\tData error in bank 0\n\r");
+ printk(" Data error in bank 0\n");
break;
case 20:
- printk("\t\tTag error in bank 1\n\r");
+ printk(" Tag error in bank 1\n");
break;
case 10:
- printk("\t\tTag error in bank 0\n\r");
+ printk(" Tag error in bank 0\n");
break;
}
}
- printk("\tEffective VA\t\t\t= %16lx\n\r",
+ printk(" Effective VA = %16lx\n",
frame->va);
- printk("\tReason for D-stream\t\t= %16lx\n\r",
+ printk(" Reason for D-stream = %16lx\n",
frame->mm_stat);
- printk("\tEV5 SCache address\t\t= %16lx\n\r",
+ printk(" EV5 SCache address = %16lx\n",
frame->sc_addr);
- printk("\tEV5 SCache TAG/Data parity\t= %16lx\n\r",
+ printk(" EV5 SCache TAG/Data parity = %16lx\n",
frame->sc_stat);
- printk("\tEV5 BC_TAG_ADDR\t\t\t= %16lx\n\r",
+ printk(" EV5 BC_TAG_ADDR = %16lx\n",
frame->bc_tag_addr);
- printk("\tEV5 EI_ADDR: Phys addr of Xfer\t= %16lx\n\r",
+ printk(" EV5 EI_ADDR: Phys addr of Xfer = %16lx\n",
frame->ei_addr);
- printk("\tFill Syndrome\t\t\t= %16lx\n\r",
+ printk(" Fill Syndrome = %16lx\n",
frame->fill_syndrome);
- printk("\tEI_STAT reg\t\t\t= %16lx\n\r",
+ printk(" EI_STAT reg = %16lx\n",
frame->ei_stat);
- printk("\tLD_LOCK\t\t\t\t= %16lx\n\r",
+ printk(" LD_LOCK = %16lx\n",
frame->ld_lock);
}
@@ -547,7 +558,8 @@ mcpcia_machine_check(unsigned long vector, unsigned long la_ptr,
if (mcheck_expected(cpu)) {
mcpcia_pci_clr_err(mcheck_extra(cpu));
} else {
- /* FIXME: how do we figure out which hose the error was on? */
+ /* FIXME: how do we figure out which hose the
+ error was on? */
struct pci_controler *hose;
for (hose = hose_head; hose; hose = hose->next)
mcpcia_pci_clr_err(hose2mid(hose->index));
diff --git a/arch/alpha/kernel/core_polaris.c b/arch/alpha/kernel/core_polaris.c
index a6b1a70c7..972e707cb 100644
--- a/arch/alpha/kernel/core_polaris.c
+++ b/arch/alpha/kernel/core_polaris.c
@@ -146,7 +146,7 @@ polaris_write_config_word(struct pci_dev *dev, int where, u16 value)
__kernel_stw(value, *(vusp)pci_addr);
mb();
- __kernel_ldbu(*(vusp)pci_addr);
+ __kernel_ldwu(*(vusp)pci_addr);
return PCIBIOS_SUCCESSFUL;
}
@@ -176,7 +176,7 @@ struct pci_ops polaris_pci_ops =
};
void __init
-polaris_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+polaris_init_arch(void)
{
struct pci_controler *hose;
@@ -192,7 +192,7 @@ polaris_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = POLARIS_DENSE_CONFIG_BASE;
diff --git a/arch/alpha/kernel/core_pyxis.c b/arch/alpha/kernel/core_pyxis.c
index 4f9dd9a81..ee18e1472 100644
--- a/arch/alpha/kernel/core_pyxis.c
+++ b/arch/alpha/kernel/core_pyxis.c
@@ -285,7 +285,7 @@ struct pci_ops pyxis_pci_ops =
};
void __init
-pyxis_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+pyxis_init_arch(void)
{
struct pci_controler *hose;
unsigned int temp;
@@ -379,7 +379,7 @@ pyxis_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = PYXIS_CONF;
@@ -389,8 +389,10 @@ pyxis_init_arch(unsigned long *mem_start, unsigned long *mem_end)
static inline void
pyxis_pci_clr_err(void)
{
- *(vuip)PYXIS_ERR;
- *(vuip)PYXIS_ERR = 0x0180;
+ unsigned int tmp;
+
+ tmp = *(vuip)PYXIS_ERR;
+ *(vuip)PYXIS_ERR = tmp;
mb();
*(vuip)PYXIS_ERR; /* re-read to force write */
}
diff --git a/arch/alpha/kernel/core_t2.c b/arch/alpha/kernel/core_t2.c
index 6028e4e58..079ad445c 100644
--- a/arch/alpha/kernel/core_t2.c
+++ b/arch/alpha/kernel/core_t2.c
@@ -322,7 +322,7 @@ struct pci_ops t2_pci_ops =
};
void __init
-t2_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+t2_init_arch(void)
{
struct pci_controler *hose;
unsigned int i;
@@ -384,7 +384,7 @@ t2_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = T2_CONF;
diff --git a/arch/alpha/kernel/core_tsunami.c b/arch/alpha/kernel/core_tsunami.c
index b27298bd5..dab4e1733 100644
--- a/arch/alpha/kernel/core_tsunami.c
+++ b/arch/alpha/kernel/core_tsunami.c
@@ -26,6 +26,13 @@
int TSUNAMI_bootcpu;
+static struct
+{
+ unsigned long wsba[4];
+ unsigned long wsm[4];
+ unsigned long tba[4];
+} saved_pchip[2];
+
/*
* NOTE: Herein lie back-to-back mb instructions. They are magic.
* One plausible explanation is that the I/O controller does not properly
@@ -84,7 +91,7 @@ static int
mk_conf_addr(struct pci_dev *dev, int where, unsigned long *pci_addr,
unsigned char *type1)
{
- struct pci_controler *hose = dev->sysdata ? : probing_hose;
+ struct pci_controler *hose = dev->sysdata;
unsigned long addr;
u8 bus = dev->bus->number;
u8 device_fn = dev->devfn;
@@ -154,6 +161,8 @@ tsunami_write_config_byte(struct pci_dev *dev, int where, u8 value)
return PCIBIOS_DEVICE_NOT_FOUND;
__kernel_stb(value, *(vucp)addr);
+ mb();
+ __kernel_ldbu(*(vucp)addr);
return PCIBIOS_SUCCESSFUL;
}
@@ -167,6 +176,8 @@ tsunami_write_config_word(struct pci_dev *dev, int where, u16 value)
return PCIBIOS_DEVICE_NOT_FOUND;
__kernel_stw(value, *(vusp)addr);
+ mb();
+ __kernel_ldwu(*(vusp)addr);
return PCIBIOS_SUCCESSFUL;
}
@@ -180,6 +191,8 @@ tsunami_write_config_dword(struct pci_dev *dev, int where, u32 value)
return PCIBIOS_DEVICE_NOT_FOUND;
*(vuip)addr = value;
+ mb();
+ *(vuip)addr;
return PCIBIOS_SUCCESSFUL;
}
@@ -243,31 +256,55 @@ tsunami_probe_write(volatile unsigned long *vaddr)
#define FN __FUNCTION__
static void __init
-tsunami_init_one_pchip(tsunami_pchip *pchip, int index,
- unsigned long *mem_start)
+tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
{
struct pci_controler *hose;
if (tsunami_probe_read(&pchip->pctl.csr) == 0)
return;
- hose = alloc_pci_controler(mem_start);
- hose->io_space = alloc_resource(mem_start);
- hose->mem_space = alloc_resource(mem_start);
+ hose = alloc_pci_controler();
+ hose->io_space = alloc_resource();
+ hose->mem_space = alloc_resource();
hose->config_space = TSUNAMI_CONF(index);
hose->index = index;
hose->io_space->start = TSUNAMI_IO(index) - TSUNAMI_IO_BIAS;
- hose->io_space->end = hose->io_space->start + 0xffff;
+ hose->io_space->end = hose->io_space->start + TSUNAMI_IO_SPACE - 1;
hose->io_space->name = pci_io_names[index];
+ hose->io_space->flags = IORESOURCE_IO;
hose->mem_space->start = TSUNAMI_MEM(index) - TSUNAMI_MEM_BIAS;
hose->mem_space->end = hose->mem_space->start + 0xffffffff;
hose->mem_space->name = pci_mem_names[index];
+ hose->mem_space->flags = IORESOURCE_MEM;
+
+ if (request_resource(&ioport_resource, hose->io_space) < 0)
+ printk(KERN_ERR "Failed to request IO on hose %d\n", index);
+ if (request_resource(&iomem_resource, hose->mem_space) < 0)
+ printk(KERN_ERR "Failed to request MEM on hose %d\n", index);
+
+ /*
+ * Save the existing PCI window translations. SRM will
+ * need them when we go to reboot.
+ */
+
+ saved_pchip[index].wsba[0] = pchip->wsba[0].csr;
+ saved_pchip[index].wsm[0] = pchip->wsm[0].csr;
+ saved_pchip[index].tba[0] = pchip->tba[0].csr;
+
+ saved_pchip[index].wsba[1] = pchip->wsba[1].csr;
+ saved_pchip[index].wsm[1] = pchip->wsm[1].csr;
+ saved_pchip[index].tba[1] = pchip->tba[1].csr;
+
+ saved_pchip[index].wsba[2] = pchip->wsba[2].csr;
+ saved_pchip[index].wsm[2] = pchip->wsm[2].csr;
+ saved_pchip[index].tba[2] = pchip->tba[2].csr;
- request_resource(&ioport_resource, hose->io_space);
- request_resource(&iomem_resource, hose->mem_space);
+ saved_pchip[index].wsba[3] = pchip->wsba[3].csr;
+ saved_pchip[index].wsm[3] = pchip->wsm[3].csr;
+ saved_pchip[index].tba[3] = pchip->tba[3].csr;
/*
* Set up the PCI->physical memory translation windows.
@@ -294,7 +331,7 @@ tsunami_init_one_pchip(tsunami_pchip *pchip, int index,
}
void __init
-tsunami_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+tsunami_init_arch(void)
{
#ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
extern asmlinkage void entInt(void);
@@ -338,9 +375,37 @@ tsunami_init_arch(unsigned long *mem_start, unsigned long *mem_end)
/* Find how many hoses we have, and initialize them. TSUNAMI
and TYPHOON can have 2, but might only have 1 (DS10). */
- tsunami_init_one_pchip(TSUNAMI_pchip0, 0, mem_start);
+ tsunami_init_one_pchip(TSUNAMI_pchip0, 0);
+ if (TSUNAMI_cchip->csc.csr & 1L<<14)
+ tsunami_init_one_pchip(TSUNAMI_pchip1, 1);
+}
+
+static void
+tsunami_kill_one_pchip(tsunami_pchip *pchip, int index)
+{
+ pchip->wsba[0].csr = saved_pchip[index].wsba[0];
+ pchip->wsm[0].csr = saved_pchip[index].wsm[0];
+ pchip->tba[0].csr = saved_pchip[index].tba[0];
+
+ pchip->wsba[1].csr = saved_pchip[index].wsba[1];
+ pchip->wsm[1].csr = saved_pchip[index].wsm[1];
+ pchip->tba[1].csr = saved_pchip[index].tba[1];
+
+ pchip->wsba[2].csr = saved_pchip[index].wsba[2];
+ pchip->wsm[2].csr = saved_pchip[index].wsm[2];
+ pchip->tba[2].csr = saved_pchip[index].tba[2];
+
+ pchip->wsba[3].csr = saved_pchip[index].wsba[3];
+ pchip->wsm[3].csr = saved_pchip[index].wsm[3];
+ pchip->tba[3].csr = saved_pchip[index].tba[3];
+}
+
+void
+tsunami_kill_arch(int mode)
+{
+ tsunami_kill_one_pchip(TSUNAMI_pchip0, 0);
if (TSUNAMI_cchip->csc.csr & 1L<<14)
- tsunami_init_one_pchip(TSUNAMI_pchip1, 1, mem_start);
+ tsunami_kill_one_pchip(TSUNAMI_pchip1, 1);
}
static inline void
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 43da6affd..d6d6e0611 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -22,15 +22,14 @@
#include <linux/random.h>
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/irq.h>
#include <asm/system.h>
#include <asm/io.h>
-#include <asm/irq.h>
#include <asm/bitops.h>
#include <asm/machvec.h>
#include "proto.h"
-#include "irq_impl.h"
#define vulp volatile unsigned long *
#define vuip volatile unsigned int *
@@ -42,8 +41,8 @@ int __local_irq_count;
int __local_bh_count;
#endif
-#if NR_IRQS > 64
-# error Unable to handle more than 64 irq levels.
+#if NR_IRQS > 128
+# error Unable to handle more than 128 irq levels.
#endif
#ifdef CONFIG_ALPHA_GENERIC
@@ -60,7 +59,8 @@ int __local_bh_count;
/*
* Shadow-copy of masked interrupts.
*/
-unsigned long alpha_irq_mask = ~0UL;
+
+unsigned long _alpha_irq_masks[2] = { ~0UL, ~0UL };
/*
* The ack_irq routine used by 80% of the systems.
@@ -110,6 +110,8 @@ void (*perf_irq)(unsigned long, struct pt_regs *) = dummy_perf;
# define IACK_SC TSUNAMI_IACK_SC
#elif defined(CONFIG_ALPHA_POLARIS)
# define IACK_SC POLARIS_IACK_SC
+#elif defined(CONFIG_ALPHA_IRONGATE)
+# define IACK_SC IRONGATE_IACK_SC
#else
/* This is bogus but necessary to get it to compile on all platforms. */
# define IACK_SC 1L
@@ -179,19 +181,22 @@ srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
*/
static struct irqaction timer_irq = { NULL, 0, 0, NULL, NULL, NULL};
-static struct irqaction *irq_action[NR_IRQS];
+spinlock_t irq_controller_lock = SPIN_LOCK_UNLOCKED;
+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { [0 ... NR_IRQS-1] = {0,} };
static inline void
mask_irq(unsigned long irq)
{
- alpha_mv.update_irq_hw(irq, alpha_irq_mask |= 1UL << irq, 0);
+ set_bit(irq, _alpha_irq_masks);
+ alpha_mv.update_irq_hw(irq, alpha_irq_mask, 0);
}
static inline void
unmask_irq(unsigned long irq)
{
- alpha_mv.update_irq_hw(irq, alpha_irq_mask &= ~(1UL << irq), 1);
+ clear_bit(irq, _alpha_irq_masks);
+ alpha_mv.update_irq_hw(irq, alpha_irq_mask, 1);
}
void
@@ -225,12 +230,7 @@ enable_irq(unsigned int irq_nr)
int
check_irq(unsigned int irq)
{
- struct irqaction **p;
-
- p = irq_action + irq;
- if (*p == NULL)
- return 0;
- return -EBUSY;
+ return irq_desc[irq].action ? -EBUSY : 0;
}
int
@@ -248,7 +248,7 @@ request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *),
if (!handler)
return -EINVAL;
- p = irq_action + irq;
+ p = &irq_desc[irq].action;
action = *p;
if (action) {
/* Can't share interrupts unless both agree to */
@@ -309,14 +309,14 @@ free_irq(unsigned int irq, void *dev_id)
printk("Trying to free reserved IRQ %d\n", irq);
return;
}
- for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) {
+ for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) {
if (action->dev_id != dev_id)
continue;
/* Found it - now free it */
save_and_cli(flags);
*p = action->next;
- if (!irq[irq_action])
+ if (!irq_desc[irq].action)
mask_irq(irq);
restore_flags(flags);
kfree(action);
@@ -339,7 +339,7 @@ int get_irq_list(char *buf)
#endif
for (i = 0; i < NR_IRQS; i++) {
- action = irq_action[i];
+ action = irq_desc[i].action;
if (!action)
continue;
p += sprintf(p, "%3d: ",i);
@@ -387,8 +387,6 @@ static void *previous_irqholder = NULL;
static void show(char * str, void *where);
-#define SYNC_OTHER_CPUS(x) udelay((x)+1);
-
static inline void
wait_on_irq(int cpu, void *where)
{
@@ -409,7 +407,6 @@ wait_on_irq(int cpu, void *where)
/* Duh, we have to loop. Release the lock to avoid deadlocks */
spin_unlock(&global_irq_lock);
- mb();
for (;;) {
if (!--count) {
@@ -417,7 +414,7 @@ wait_on_irq(int cpu, void *where)
count = MAXCOUNT;
}
__sti();
- SYNC_OTHER_CPUS(cpu);
+ udelay(1); /* make sure to run pending irqs */
__cli();
if (atomic_read(&global_irq_count))
@@ -437,17 +434,13 @@ static inline void
get_irqlock(int cpu, void* where)
{
if (!spin_trylock(&global_irq_lock)) {
- /* do we already hold the lock? */
- if (cpu == global_irq_holder) {
-#if 0
- printk("get_irqlock: already held at %08lx\n",
- previous_irqholder);
-#endif
+ /* Do we already hold the lock? */
+ if (cpu == global_irq_holder)
return;
- }
- /* Uhhuh.. Somebody else got it. Wait.. */
+ /* Uhhuh.. Somebody else got it. Wait. */
spin_lock(&global_irq_lock);
}
+
/*
* Ok, we got the lock bit.
* But that's actually just the easy part.. Now
@@ -543,63 +536,6 @@ __global_restore_flags(unsigned long flags)
}
}
-#undef INIT_STUCK
-#define INIT_STUCK (1<<26)
-
-#undef STUCK
-#define STUCK \
- if (!--stuck) { \
- printk("irq_enter stuck (irq=%d, cpu=%d, global=%d)\n", \
- irq, cpu, global_irq_holder); \
- stuck = INIT_STUCK; \
- }
-
-#undef VERBOSE_IRQLOCK_DEBUGGING
-
-void
-irq_enter(int cpu, int irq)
-{
-#ifdef VERBOSE_IRQLOCK_DEBUGGING
- extern void smp_show_backtrace_all_cpus(void);
-#endif
- int stuck = INIT_STUCK;
-
- hardirq_enter(cpu, irq);
- barrier();
- while (spin_is_locked(&global_irq_lock)) {
- if (cpu == global_irq_holder) {
- int globl_locked = spin_is_locked(&global_irq_lock);
- int globl_icount = atomic_read(&global_irq_count);
- int local_count = local_irq_count(cpu);
-
- /* It is very important that we load the state
- variables before we do the first call to
- printk() as printk() could end up changing
- them... */
-
- printk("CPU[%d]: where [%p] glocked[%d] gicnt[%d]"
- " licnt[%d]\n",
- cpu, previous_irqholder, globl_locked,
- globl_icount, local_count);
-#ifdef VERBOSE_IRQLOCK_DEBUGGING
- printk("Performing backtrace on all CPUs,"
- " write this down!\n");
- smp_show_backtrace_all_cpus();
-#endif
- break;
- }
- STUCK;
- barrier();
- }
-}
-
-void
-irq_exit(int cpu, int irq)
-{
- hardirq_exit(cpu, irq);
- release_irqlock(cpu);
-}
-
static void
show(char * str, void *where)
{
@@ -700,12 +636,6 @@ synchronize_irq(void)
}
#endif
}
-
-#else /* !__SMP__ */
-
-#define irq_enter(cpu, irq) (++local_irq_count(cpu))
-#define irq_exit(cpu, irq) (--local_irq_count(cpu))
-
#endif /* __SMP__ */
static void
@@ -722,7 +652,7 @@ unexpected_irq(int irq, struct pt_regs * regs)
printk("PC = %016lx PS=%04lx\n", regs->pc, regs->ps);
printk("Expecting: ");
for (i = 0; i < ACTUAL_NR_IRQS; i++)
- if ((action = irq_action[i]))
+ if ((action = irq_desc[i].action))
while (action->handler) {
printk("[%s:%d] ", action->name, i);
action = action->next;
@@ -776,7 +706,7 @@ handle_irq(int irq, int ack, struct pt_regs * regs)
irq_enter(cpu, irq);
kstat.irqs[cpu][irq] += 1;
- action = irq_action[irq];
+ action = irq_desc[irq].action;
/*
* For normal interrupts, we mask it out, and then ACK it.
@@ -819,11 +749,13 @@ probe_irq_on(void)
unsigned long delay;
unsigned int i;
- for (i = ACTUAL_NR_IRQS - 1; i > 0; i--) {
+ /* Handle only the first 64 IRQs here. This is enough for
+ [E]ISA, which is the only thing that needs probing anyway. */
+ for (i = (ACTUAL_NR_IRQS - 1) & 63; i > 0; i--) {
if (!(PROBE_MASK & (1UL << i))) {
continue;
}
- action = irq_action[i];
+ action = irq_desc[i].action;
if (!action) {
enable_irq(i);
irqs |= (1UL << i);
@@ -852,6 +784,8 @@ probe_irq_off(unsigned long irqs)
{
int i;
+ /* Handle only the first 64 IRQs here. This is enough for
+ [E]ISA, which is the only thing that needs probing anyway. */
irqs &= alpha_irq_mask;
if (!irqs)
return 0;
diff --git a/arch/alpha/kernel/irq_impl.h b/arch/alpha/kernel/irq_impl.h
deleted file mode 100644
index bc8854212..000000000
--- a/arch/alpha/kernel/irq_impl.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * linux/arch/alpha/kernel/irq.h
- *
- * Copyright (C) 1995 Linus Torvalds
- * Copyright (C) 1998 Richard Henderson
- *
- * This file contains declarations and inline functions for interfacing
- * with the IRQ handling routines in irq.c.
- */
-
-#include <linux/config.h>
-
-#define STANDARD_INIT_IRQ_PROLOG \
- outb(0, DMA1_RESET_REG); \
- outb(0, DMA2_RESET_REG); \
- outb(0, DMA1_CLR_MASK_REG); \
- outb(0, DMA2_CLR_MASK_REG)
-
-extern unsigned long alpha_irq_mask;
-
-extern void common_ack_irq(unsigned long irq);
-extern void isa_device_interrupt(unsigned long vector, struct pt_regs * regs);
-extern void srm_device_interrupt(unsigned long vector, struct pt_regs * regs);
-
-extern void handle_irq(int irq, int ack, struct pt_regs * regs);
-
-#define RTC_IRQ 8
-#ifdef CONFIG_RTC
-#define TIMER_IRQ 0 /* timer is the pit */
-#else
-#define TIMER_IRQ RTC_IRQ /* timer is the rtc */
-#endif
-
-extern char _stext;
-static inline void alpha_do_profile (unsigned long pc)
-{
- if (prof_buffer && current->pid) {
- pc -= (unsigned long) &_stext;
- pc >>= prof_shift;
- /*
- * Don't ignore out-of-bounds PC values silently,
- * put them into the last histogram slot, so if
- * present, they will show up as a sharp peak.
- */
- if (pc > prof_len - 1)
- pc = prof_len - 1;
- atomic_inc((atomic_t *)&prof_buffer[pc]);
- }
-}
diff --git a/arch/alpha/kernel/machvec_impl.h b/arch/alpha/kernel/machvec_impl.h
index a0ff70dcc..fc0d0cc0c 100644
--- a/arch/alpha/kernel/machvec_impl.h
+++ b/arch/alpha/kernel/machvec_impl.h
@@ -7,12 +7,14 @@
*/
#include <linux/config.h>
+#include <asm/pgalloc.h>
-/* Whee. Both TSUNAMI and POLARIS don't have an HAE. Fix things up for
+/* Whee. IRONGATE, POLARIS and TSUNAMI don't have an HAE. Fix things up for
the GENERIC kernel by defining the HAE address to be that of the cache.
Now we can read and write it as we like. ;-) */
-#define TSUNAMI_HAE_ADDRESS (&alpha_mv.hae_cache)
+#define IRONGATE_HAE_ADDRESS (&alpha_mv.hae_cache)
#define POLARIS_HAE_ADDRESS (&alpha_mv.hae_cache)
+#define TSUNAMI_HAE_ADDRESS (&alpha_mv.hae_cache)
#if CIA_ONE_HAE_WINDOW
#define CIA_HAE_ADDRESS (&alpha_mv.hae_cache)
@@ -90,10 +92,11 @@
#define DO_APECS_IO IO(APECS,apecs)
#define DO_CIA_IO IO(CIA,cia)
+#define DO_IRONGATE_IO IO(IRONGATE,irongate)
#define DO_LCA_IO IO(LCA,lca)
#define DO_MCPCIA_IO IO(MCPCIA,mcpcia)
-#define DO_PYXIS_IO IO(PYXIS,pyxis)
#define DO_POLARIS_IO IO(POLARIS,polaris)
+#define DO_PYXIS_IO IO(PYXIS,pyxis)
#define DO_T2_IO IO(T2,t2)
#define DO_TSUNAMI_IO IO(TSUNAMI,tsunami)
@@ -103,6 +106,7 @@
#define DO_APECS_BUS BUS(apecs)
#define DO_CIA_BUS BUS(cia)
+#define DO_IRONGATE_BUS BUS(irongate)
#define DO_LCA_BUS BUS(lca)
#define DO_MCPCIA_BUS BUS(mcpcia)
#define DO_PYXIS_BUS BUS(pyxis)
diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index 39d6b759f..9a61a4e99 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -6,10 +6,14 @@
* David Mosberger (davidm@cs.arizona.edu)
*/
+/* 2.3.x PCI/resources, 1999 Andrea Arcangeli <andrea@suse.de> */
+
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/bootmem.h>
#include <asm/machvec.h>
#include "proto.h"
@@ -36,7 +40,6 @@ const char pci_hae0_name[] = "HAE0";
*/
struct pci_controler *hose_head, **hose_tail = &hose_head;
-struct pci_controler *probing_hose;
/*
* Quirks.
@@ -54,32 +57,122 @@ quirk_isa_bridge(struct pci_dev *dev)
dev->class = PCI_CLASS_BRIDGE_ISA;
}
+static void __init
+quirk_vga_enable_rom(struct pci_dev *dev)
+{
+ /* If it's a VGA, enable its BIOS ROM at C0000.
+ But if its a Cirrus 543x/544x DISABLE it, since
+ enabling ROM disables the memory... */
+ if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA &&
+ /* But if its a Cirrus 543x/544x DISABLE it */
+ (dev->vendor != PCI_VENDOR_ID_CIRRUS ||
+ (dev->device < 0x00a0) || (dev->device > 0x00ac)))
+ {
+ u32 reg;
+
+ pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+ reg |= PCI_ROM_ADDRESS_ENABLE;
+ pci_write_config_dword(dev, dev->rom_base_reg, reg);
+ dev->resource[PCI_ROM_RESOURCE].flags |= PCI_ROM_ADDRESS_ENABLE;
+ }
+}
+
struct pci_fixup pcibios_fixups[] __initdata = {
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375,
quirk_eisa_bridge },
{ PCI_FIXUP_HEADER, PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82378,
quirk_isa_bridge },
+ { PCI_FIXUP_FINAL, PCI_ANY_ID, PCI_ANY_ID, quirk_vga_enable_rom },
{ 0 }
};
+#define MAX(val1, val2) ((val1) > (val2) ? (val1) : (val2))
+#define ALIGN(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
+#define KB 1024
+#define MB (1024*KB)
+#define GB (1024*MB)
+
+void
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+ struct pci_dev * dev = data;
+ unsigned long alignto;
+ unsigned long start = res->start;
+
+ if (res->flags & IORESOURCE_IO) {
+ /*
+ * Aligning to 0x800 rather than the minimum base of
+ * 0x400 is an attempt to avoid having devices in
+ * any 0x?C?? range, which is where the de4x5 driver
+ * probes for EISA cards.
+ *
+ * Adaptecs, especially, resent such intrusions.
+ */
+ alignto = MAX(0x800, size);
+ start = ALIGN(start, alignto);
+ }
+ else if (res->flags & IORESOURCE_MEM) {
+ /*
+ * The following holds at least for the Low Cost
+ * Alpha implementation of the PCI interface:
+ *
+ * In sparse memory address space, the first
+ * octant (16MB) of every 128MB segment is
+ * aliased to the very first 16 MB of the
+ * address space (i.e., it aliases the ISA
+ * memory address space). Thus, we try to
+ * avoid allocating PCI devices in that range.
+ * Can be allocated in 2nd-7th octant only.
+ * Devices that need more than 112MB of
+ * address space must be accessed through
+ * dense memory space only!
+ */
+
+ /* Align to multiple of size of minimum base. */
+ alignto = MAX(0x1000, size);
+ start = ALIGN(start, alignto);
+ if (size > 7 * 16*MB) {
+ printk(KERN_WARNING "PCI: dev %s "
+ "requests %ld bytes of contiguous "
+ "address space---don't use sparse "
+ "memory accesses on this device!\n",
+ dev->name, size);
+ } else {
+ if (((start / (16*MB)) & 0x7) == 0) {
+ start &= ~(128*MB - 1);
+ start += 16*MB;
+ start = ALIGN(start, alignto);
+ }
+ if (start/(128*MB) != (start + size)/(128*MB)) {
+ start &= ~(128*MB - 1);
+ start += (128 + 16)*MB;
+ start = ALIGN(start, alignto);
+ }
+ }
+ }
+
+ res->start = start;
+}
+#undef MAX
+#undef ALIGN
+#undef KB
+#undef MB
+#undef GB
/*
* Pre-layout host-independant device initialization.
*/
static void __init
-pcibios_assign_special(void)
+pcibios_assign_special(struct pci_dev * dev)
{
- struct pci_dev *dev;
int i;
/* The first three resources of an IDE controler are often magic,
so leave them unchanged. This is true, for instance, of the
Contaq 82C693 as seen on SX164 and DP264. */
- for (dev = pci_devices; dev; dev = dev->next) {
- if (dev->class >> 8 != PCI_CLASS_STORAGE_IDE)
- continue;
+ if (dev->class >> 8 == PCI_CLASS_STORAGE_IDE) {
/* Resource 1 of IDE controller is the address of HD_CMD
register which actually occupies a single byte (0x3f6
for ide0) in reported 0x3f4-3f7 range. We have to fix
@@ -87,11 +180,20 @@ pcibios_assign_special(void)
controller. */
dev->resource[1].start += 2;
dev->resource[1].end = dev->resource[1].start;
- for (i = 0; i < PCI_NUM_RESOURCES; i++) {
- if (dev->resource[i].flags)
+ for (i = 0; i < PCI_NUM_RESOURCES; i++)
+ if (dev->resource[i].flags && dev->resource[i].start)
pci_claim_resource(dev, i);
- }
}
+ /*
+ * We don't have code that will init the CYPRESS bridge correctly
+ * so we do the next best thing, and depend on the previous
+ * console code to do the right thing, and ignore it here... :-\
+ */
+ else if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
+ dev->device == PCI_DEVICE_ID_CONTAQ_82C693)
+ for (i = 0; i < PCI_NUM_RESOURCES; i++)
+ if (dev->resource[i].flags && dev->resource[i].start)
+ pci_claim_resource(dev, i);
}
@@ -110,31 +212,65 @@ pcibios_setup(char *str)
}
void __init
+pcibios_fixup_resource(struct resource *res, struct resource *root)
+{
+ res->start += root->start;
+ res->end += root->start;
+}
+
+void __init
+pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
+{
+ /* Update device resources. */
+
+ int i;
+
+ for (i = 0; i < PCI_NUM_RESOURCES; i++) {
+ if (!dev->resource[i].start)
+ continue;
+ if (dev->resource[i].flags & IORESOURCE_IO)
+ pcibios_fixup_resource(&dev->resource[i],
+ bus->resource[0]);
+ else if (dev->resource[i].flags & IORESOURCE_MEM)
+ pcibios_fixup_resource(&dev->resource[i],
+ bus->resource[1]);
+ }
+ pcibios_assign_special(dev);
+}
+
+void __init
pcibios_fixup_bus(struct pci_bus *bus)
{
/* Propogate hose info into the subordinate devices. */
- struct pci_controler *hose = probing_hose;
+ struct pci_controler *hose = (struct pci_controler *) bus->sysdata;
struct pci_dev *dev;
bus->resource[0] = hose->io_space;
bus->resource[1] = hose->mem_space;
- for (dev = bus->devices; dev; dev = dev->sibling)
- dev->sysdata = hose;
+ for (dev = bus->devices; dev; dev = dev->sibling) {
+ if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI)
+ pcibios_fixup_device_resources(dev, bus);
+ }
}
void __init
pcibios_update_resource(struct pci_dev *dev, struct resource *root,
struct resource *res, int resource)
{
- unsigned long where, size;
- u32 reg;
-
- where = PCI_BASE_ADDRESS_0 + (resource * 4);
- size = res->end - res->start;
- pci_read_config_dword(dev, where, &reg);
- reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
- pci_write_config_dword(dev, where, reg);
+ int where;
+ u32 reg;
+
+ where = PCI_BASE_ADDRESS_0 + (resource * 4);
+ reg = (res->start - root->start) | (res->flags & 0xf);
+ pci_write_config_dword(dev, where, reg);
+ if ((res->flags & (PCI_BASE_ADDRESS_SPACE
+ | PCI_BASE_ADDRESS_MEM_TYPE_MASK))
+ == (PCI_BASE_ADDRESS_SPACE_MEMORY
+ | PCI_BASE_ADDRESS_MEM_TYPE_64)) {
+ pci_write_config_dword(dev, where+4, 0);
+ printk(KERN_WARNING "PCI: dev %s type 64-bit\n", dev->name);
+ }
/* ??? FIXME -- record old value for shutdown. */
}
@@ -170,6 +306,16 @@ common_swizzle(struct pci_dev *dev, u8 *pinp)
}
void __init
+pcibios_fixup_pbus_ranges(struct pci_bus * bus,
+ struct pbus_set_ranges_data * ranges)
+{
+ ranges->io_start -= bus->resource[0]->start;
+ ranges->io_end -= bus->resource[0]->start;
+ ranges->mem_start -= bus->resource[1]->start;
+ ranges->mem_end -= bus->resource[1]->start;
+}
+
+void __init
common_init_pci(void)
{
struct pci_controler *hose;
@@ -180,15 +326,12 @@ common_init_pci(void)
for (next_busno = 0, hose = hose_head; hose; hose = hose->next) {
hose->first_busno = next_busno;
hose->last_busno = 0xff;
- probing_hose = hose;
bus = pci_scan_bus(next_busno, alpha_mv.pci_ops, hose);
hose->bus = bus;
next_busno = hose->last_busno = bus->subordinate;
next_busno += 1;
}
- probing_hose = NULL;
- pcibios_assign_special();
pci_assign_unassigned_resources(alpha_mv.min_io_address,
alpha_mv.min_mem_address);
pci_fixup_irqs(alpha_mv.pci_swizzle, alpha_mv.pci_map_irq);
@@ -197,17 +340,11 @@ common_init_pci(void)
struct pci_controler * __init
-alloc_pci_controler(unsigned long *mem_start)
+alloc_pci_controler(void)
{
- unsigned long start = *mem_start;
struct pci_controler *hose;
- if (start & 31)
- start = (start | 31) + 1;
- hose = (void *) start;
- start = (unsigned long) (hose + 1);
- *mem_start = start;
- memset(hose, 0, sizeof(*hose));
+ hose = alloc_bootmem(sizeof(*hose));
*hose_tail = hose;
hose_tail = &hose->next;
@@ -216,17 +353,11 @@ alloc_pci_controler(unsigned long *mem_start)
}
struct resource * __init
-alloc_resource(unsigned long *mem_start)
+alloc_resource(void)
{
- unsigned long start = *mem_start;
struct resource *res;
- if (start & 31)
- start = (start | 31) + 1;
- res = (void *) start;
- start = (unsigned long) (res + 1);
- *mem_start = start;
- memset(res, 0, sizeof(*res));
+ res = alloc_bootmem(sizeof(*res));
return res;
}
diff --git a/arch/alpha/kernel/pci_impl.h b/arch/alpha/kernel/pci_impl.h
index c7c97f096..b46fb9980 100644
--- a/arch/alpha/kernel/pci_impl.h
+++ b/arch/alpha/kernel/pci_impl.h
@@ -125,12 +125,11 @@ static inline u8 bridge_swizzle(u8 pin, u8 slot)
/* The hose list. */
extern struct pci_controler *hose_head, **hose_tail;
-extern struct pci_controler *probing_hose;
extern void common_init_pci(void);
extern u8 common_swizzle(struct pci_dev *, u8 *);
-extern struct pci_controler *alloc_pci_controler(unsigned long *);
-extern struct resource *alloc_resource(unsigned long *);
+extern struct pci_controler *alloc_pci_controler(void);
+extern struct resource *alloc_resource(void);
extern const char *const pci_io_names[];
extern const char *const pci_mem_names[];
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 0390e3138..e80282155 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -94,8 +94,8 @@ cpu_idle(void)
}
}
-void
-common_kill_arch (int mode, char *restart_cmd)
+static void
+common_shutdown(int mode, char *restart_cmd)
{
/* The following currently only has any effect on SRM. We should
fix MILO to understand it. Should be pretty easy. Also we can
@@ -141,24 +141,12 @@ common_kill_arch (int mode, char *restart_cmd)
#ifdef CONFIG_RTC
/* Reset rtc to defaults. */
- {
- unsigned char control;
-
- cli();
-
- /* Reset periodic interrupt frequency. */
- CMOS_WRITE(0x26, RTC_FREQ_SELECT);
-
- /* Turn on periodic interrupts. */
- control = CMOS_READ(RTC_CONTROL);
- control |= RTC_PIE;
- CMOS_WRITE(control, RTC_CONTROL);
- CMOS_READ(RTC_INTR_FLAGS);
-
- sti();
- }
+ rtc_kill_pit();
#endif
+ if (alpha_mv.kill_arch)
+ alpha_mv.kill_arch(mode);
+
if (!alpha_using_srm && mode != LINUX_REBOOT_CMD_RESTART) {
/* Unfortunately, since MILO doesn't currently understand
the hwrpb bits above, we can't reliably halt the
@@ -175,21 +163,23 @@ common_kill_arch (int mode, char *restart_cmd)
void
machine_restart(char *restart_cmd)
{
- alpha_mv.kill_arch(LINUX_REBOOT_CMD_RESTART, restart_cmd);
+ common_shutdown(LINUX_REBOOT_CMD_RESTART, restart_cmd);
}
void
machine_halt(void)
{
- alpha_mv.kill_arch(LINUX_REBOOT_CMD_HALT, NULL);
+ common_shutdown(LINUX_REBOOT_CMD_HALT, NULL);
}
-void machine_power_off(void)
+void
+machine_power_off(void)
{
- alpha_mv.kill_arch(LINUX_REBOOT_CMD_POWER_OFF, NULL);
+ common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL);
}
-void show_regs(struct pt_regs * regs)
+void
+show_regs(struct pt_regs * regs)
{
printk("\nps: %04lx pc: [<%016lx>]\n", regs->ps, regs->pc);
printk("rp: [<%016lx>] sp: %p\n", regs->r26, regs+1);
@@ -210,7 +200,8 @@ void show_regs(struct pt_regs * regs)
/*
* Re-start a thread when doing execve()
*/
-void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
+void
+start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
{
set_fs(USER_DS);
regs->pc = pc;
@@ -221,11 +212,13 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp)
/*
* Free current thread data structures etc..
*/
-void exit_thread(void)
+void
+exit_thread(void)
{
}
-void flush_thread(void)
+void
+flush_thread(void)
{
/* Arrange for each exec'ed process to start off with a clean slate
with respect to the FPU. This is all exceptions disabled. Note
@@ -236,7 +229,8 @@ void flush_thread(void)
wrfpcr(FPCR_DYN_NORMAL | FPCR_INVD | FPCR_DZED | FPCR_OVFD | FPCR_INED);
}
-void release_thread(struct task_struct *dead_task)
+void
+release_thread(struct task_struct *dead_task)
{
}
@@ -249,15 +243,17 @@ void release_thread(struct task_struct *dead_task)
* Notice that "fork()" is implemented in terms of clone,
* with parameters (SIGCHLD, 0).
*/
-int alpha_clone(unsigned long clone_flags, unsigned long usp,
- struct switch_stack * swstack)
+int
+alpha_clone(unsigned long clone_flags, unsigned long usp,
+ struct switch_stack * swstack)
{
if (!usp)
usp = rdusp();
return do_fork(clone_flags, usp, (struct pt_regs *) (swstack+1));
}
-int alpha_vfork(struct switch_stack * swstack)
+int
+alpha_vfork(struct switch_stack * swstack)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(),
(struct pt_regs *) (swstack+1));
@@ -274,8 +270,9 @@ int alpha_vfork(struct switch_stack * swstack)
* for a kernel fork().
*/
-int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
- struct task_struct * p, struct pt_regs * regs)
+int
+copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ struct task_struct * p, struct pt_regs * regs)
{
extern void ret_from_sys_call(void);
extern void ret_from_smp_fork(void);
@@ -313,7 +310,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
/*
* fill in the user structure for a core dump..
*/
-void dump_thread(struct pt_regs * pt, struct user * dump)
+void
+dump_thread(struct pt_regs * pt, struct user * dump)
{
/* switch stack follows right below pt_regs: */
struct switch_stack * sw = ((struct switch_stack *) pt) - 1;
@@ -370,7 +368,8 @@ void dump_thread(struct pt_regs * pt, struct user * dump)
memcpy((char *)dump->regs + EF_SIZE, sw->fp, 32 * 8);
}
-int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
+int
+dump_fpu(struct pt_regs * regs, elf_fpregset_t *r)
{
/* switch stack follows right below pt_regs: */
struct switch_stack * sw = ((struct switch_stack *) regs) - 1;
@@ -388,7 +387,8 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t *r)
*
* Don't do this at home.
*/
-asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+asmlinkage int
+sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
unsigned long a3, unsigned long a4, unsigned long a5,
struct pt_regs regs)
{
@@ -415,7 +415,8 @@ 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
+get_wchan(struct task_struct *p)
{
unsigned long schedule_frame;
unsigned long pc;
diff --git a/arch/alpha/kernel/proto.h b/arch/alpha/kernel/proto.h
index 2a196efa1..3efbdda08 100644
--- a/arch/alpha/kernel/proto.h
+++ b/arch/alpha/kernel/proto.h
@@ -12,43 +12,51 @@ struct pci_dev;
/* core_apecs.c */
extern struct pci_ops apecs_pci_ops;
-extern void apecs_init_arch(unsigned long *, unsigned long *);
+extern void apecs_init_arch(void);
extern void apecs_pci_clr_err(void);
extern void apecs_machine_check(u64, u64, struct pt_regs *);
/* core_cia.c */
extern struct pci_ops cia_pci_ops;
-extern void cia_init_arch(unsigned long *, unsigned long *);
+extern void cia_init_arch(void);
extern void cia_machine_check(u64, u64, struct pt_regs *);
+/* core_irongate.c */
+extern struct pci_ops irongate_pci_ops;
+extern int irongate_pci_clr_err(void);
+extern void irongate_init_arch(void);
+extern void irongate_machine_check(u64, u64, struct pt_regs *);
+
/* core_lca.c */
extern struct pci_ops lca_pci_ops;
-extern void lca_init_arch(unsigned long *, unsigned long *);
+extern void lca_init_arch(void);
extern void lca_machine_check(u64, u64, struct pt_regs *);
/* core_mcpcia.c */
extern struct pci_ops mcpcia_pci_ops;
-extern void mcpcia_init_arch(unsigned long *, unsigned long *);
+extern void mcpcia_init_arch(void);
+extern void mcpcia_init_hoses(void);
extern void mcpcia_machine_check(u64, u64, struct pt_regs *);
/* core_polaris.c */
extern struct pci_ops polaris_pci_ops;
-extern void polaris_init_arch(unsigned long *, unsigned long *);
+extern void polaris_init_arch(void);
extern void polaris_machine_check(u64, u64, struct pt_regs *);
/* core_pyxis.c */
extern struct pci_ops pyxis_pci_ops;
-extern void pyxis_init_arch(unsigned long *, unsigned long *);
+extern void pyxis_init_arch(void);
extern void pyxis_machine_check(u64, u64, struct pt_regs *);
/* core_t2.c */
extern struct pci_ops t2_pci_ops;
-extern void t2_init_arch(unsigned long *, unsigned long *);
+extern void t2_init_arch(void);
extern void t2_machine_check(u64, u64, struct pt_regs *);
/* core_tsunami.c */
extern struct pci_ops tsunami_pci_ops;
-extern void tsunami_init_arch(unsigned long *, unsigned long *);
+extern void tsunami_init_arch(void);
+extern void tsunami_kill_arch(int);
extern void tsunami_machine_check(u64, u64, struct pt_regs *);
/* setup.c */
@@ -67,6 +75,7 @@ extern int smp_boot_cpuid;
/* time.c */
extern void timer_interrupt(int irq, void *dev, struct pt_regs * regs);
extern void rtc_init_pit(void);
+extern void rtc_kill_pit(void);
extern void common_init_pit(void);
extern unsigned long est_cycle_freq;
@@ -102,7 +111,6 @@ extern void entUna(void);
extern void entDbg(void);
/* process.c */
-extern void common_kill_arch (int mode, char *reboot_cmd);
extern void cpu_idle(void) __attribute__((noreturn));
/* ptrace.c */
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index 333bb63ec..b650de6b1 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -57,12 +57,6 @@ enum {
* | | v
* +================================+
*/
-#define PT_REG(reg) (PAGE_SIZE*2 - sizeof(struct pt_regs) \
- + (long)&((struct pt_regs *)0)->reg)
-
-#define SW_REG(reg) (PAGE_SIZE*2 - sizeof(struct pt_regs) \
- - sizeof(struct switch_stack) \
- + (long)&((struct switch_stack *)0)->reg)
/*
* The following table maps a register index into the stack offset at
diff --git a/arch/alpha/kernel/setup.c b/arch/alpha/kernel/setup.c
index 9bb21671c..3a1fb94a3 100644
--- a/arch/alpha/kernel/setup.c
+++ b/arch/alpha/kernel/setup.c
@@ -4,6 +4,8 @@
* Copyright (C) 1995 Linus Torvalds
*/
+/* 2.3.x bootmem, 1999 Andrea Arcangeli <andrea@suse.de> */
+
/*
* Bootup setup stuff.
*/
@@ -26,6 +28,7 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/ioport.h>
+#include <linux/bootmem.h>
#ifdef CONFIG_RTC
#include <linux/timex.h>
@@ -40,6 +43,8 @@
#include <asm/hwrpb.h>
#include <asm/dma.h>
#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/mmu_context.h>
#include "proto.h"
#include "pci_impl.h"
@@ -57,7 +62,6 @@ unsigned char aux_device_present = 0xaa;
#define N(a) (sizeof(a)/sizeof(a[0]))
-static unsigned long find_end_memory(void);
static struct alpha_machine_vector *get_sysvec(long, long, long);
static struct alpha_machine_vector *get_sysvec_byname(const char *);
static void get_sysnames(long, long, char **, char **);
@@ -68,7 +72,7 @@ static void get_sysnames(long, long, char **, char **);
* initialized, we need to copy things out into a more permanent
* place.
*/
-#define PARAM ZERO_PAGE(0)
+#define PARAM ZERO_PGE
#define COMMAND_LINE ((char*)(PARAM + 0x0000))
#define COMMAND_LINE_SIZE 256
#define INITRD_START (*(unsigned long *) (PARAM+0x100))
@@ -115,12 +119,14 @@ WEAK(eb164_mv);
WEAK(eb64p_mv);
WEAK(eb66_mv);
WEAK(eb66p_mv);
+WEAK(eiger_mv);
WEAK(jensen_mv);
WEAK(lx164_mv);
WEAK(miata_mv);
WEAK(mikasa_mv);
WEAK(mikasa_primo_mv);
WEAK(monet_mv);
+WEAK(nautilus_mv);
WEAK(noname_mv);
WEAK(noritake_mv);
WEAK(noritake_primo_mv);
@@ -181,17 +187,181 @@ reserve_std_resources(void)
request_resource(io, standard_io_resources+i);
}
-void __init
-setup_arch(char **cmdline_p, unsigned long * memory_start_p,
- unsigned long * memory_end_p)
+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
+#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
+#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
+#define PFN_MAX PFN_DOWN(0x80000000)
+#define for_each_mem_cluster(memdesc, cluster, i) \
+ for ((cluster) = (memdesc)->cluster, (i) = 0; \
+ (i) < (memdesc)->numclusters; (i)++, (cluster)++)
+
+static void __init
+setup_memory(void)
{
+ struct memclust_struct * cluster;
+ struct memdesc_struct * memdesc;
+ unsigned long start_pfn, bootmap_size, bootmap_pages, bootmap_start;
+ unsigned long start, end;
extern char _end[];
+ int i;
+
+ /* Find free clusters, and init and free the bootmem accordingly. */
+ memdesc = (struct memdesc_struct *)
+ (hwrpb->mddt_offset + (unsigned long) hwrpb);
+
+ for_each_mem_cluster(memdesc, cluster, i) {
+ printk("memcluster %d, usage %01lx, start %8lu, end %8lu\n",
+ i, cluster->usage, cluster->start_pfn,
+ cluster->start_pfn + cluster->numpages);
+
+ /* Bit 0 is console/PALcode reserved. Bit 1 is
+ non-volatile memory -- we might want to mark
+ this for later. */
+ if (cluster->usage & 3)
+ continue;
+
+ end = cluster->start_pfn + cluster->numpages;
+ if (end > max_low_pfn)
+ max_low_pfn = end;
+ }
+
+ /* Enforce maximum of 2GB even if there is more. Blah. */
+ if (max_low_pfn > PFN_MAX)
+ max_low_pfn = PFN_MAX;
+ printk("max_low_pfn %ld\n", max_low_pfn);
+
+ /* Find the end of the kernel memory. */
+ start_pfn = PFN_UP(virt_to_phys(_end));
+ printk("_end %p, start_pfn %ld\n", _end, start_pfn);
+
+ bootmap_start = -1;
+
+ try_again:
+ if (max_low_pfn <= start_pfn)
+ panic("not enough memory to boot");
+
+ /* We need to know how many physically contigous pages
+ we'll need for the bootmap. */
+ bootmap_pages = bootmem_bootmap_pages(max_low_pfn);
+ printk("bootmap size: %ld pages\n", bootmap_pages);
+
+ /* Now find a good region where to allocate the bootmap. */
+ for_each_mem_cluster(memdesc, cluster, i) {
+ if (cluster->usage & 3)
+ continue;
+
+ start = cluster->start_pfn;
+ end = start + cluster->numpages;
+ if (end <= start_pfn)
+ continue;
+ if (start >= max_low_pfn)
+ continue;
+ if (start < start_pfn)
+ start = start_pfn;
+ if (end > max_low_pfn)
+ end = max_low_pfn;
+ if (end - start >= bootmap_pages) {
+ printk("allocating bootmap in area %ld:%ld\n",
+ start, start+bootmap_pages);
+ bootmap_start = start;
+ break;
+ }
+ }
+
+ if (bootmap_start == -1) {
+ max_low_pfn >>= 1;
+ printk("bootmap area not found now trying with %ld pages\n",
+ max_low_pfn);
+ goto try_again;
+ }
+
+ /* Allocate the bootmap and mark the whole MM as reserved. */
+ bootmap_size = init_bootmem(bootmap_start, max_low_pfn);
+
+ /* Mark the free regions. */
+ for_each_mem_cluster(memdesc, cluster, i) {
+ if (cluster->usage & 3)
+ continue;
+
+ start = cluster->start_pfn;
+ if (start < start_pfn)
+ start = start_pfn;
+
+ end = cluster->start_pfn + cluster->numpages;
+ if (end > max_low_pfn)
+ end = max_low_pfn;
+
+ if (start >= end)
+ continue;
+
+ start = PFN_PHYS(start);
+ end = PFN_PHYS(end);
+
+ free_bootmem(start, end - start);
+ printk("freeing pages %ld:%ld\n",
+ PFN_UP(start), PFN_DOWN(end));
+ }
+
+ /* Reserve the bootmap memory. */
+ reserve_bootmem(PFN_PHYS(bootmap_start), bootmap_size);
+ printk("reserving bootmap %ld:%ld\n", bootmap_start,
+ bootmap_start + PFN_UP(bootmap_size));
+#ifdef CONFIG_BLK_DEV_INITRD
+ initrd_start = INITRD_START;
+ if (initrd_start) {
+ initrd_end = initrd_start+INITRD_SIZE;
+ printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
+ (void *) initrd_start, INITRD_SIZE);
+
+ if (initrd_end > phys_to_virt(PFN_PHYS(max_low_pfn))) {
+ printk("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
+ initrd_end,
+ phys_to_virt(PFN_PHYS(max_low_pfn)));
+ initrd_start = initrd_end = 0;
+ } else {
+ reserve_bootmem(virt_to_phys(initrd_start),
+ INITRD_SIZE);
+ }
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+}
+
+int __init page_is_ram(unsigned long pfn)
+{
+ struct memclust_struct * cluster;
+ struct memdesc_struct * memdesc;
+ int i;
+
+ memdesc = (struct memdesc_struct *) (hwrpb->mddt_offset + (unsigned long) hwrpb);
+ for_each_mem_cluster(memdesc, cluster, i)
+ {
+ if (pfn >= cluster->start_pfn &&
+ pfn < cluster->start_pfn + cluster->numpages)
+ {
+ if (cluster->usage & 3)
+ return 0;
+ else
+ return 1;
+ }
+ }
+
+ return 0;
+}
+#undef PFN_UP
+#undef PFN_DOWN
+#undef PFN_PHYS
+#undef PFN_MAX
+
+void __init
+setup_arch(char **cmdline_p)
+{
struct alpha_machine_vector *vec = NULL;
struct percpu_struct *cpu;
char *type_name, *var_name, *p;
- hwrpb = (struct hwrpb_struct*)(IDENT_ADDR + INIT_HWRPB->phys_addr);
+ hwrpb = (struct hwrpb_struct*) __va(INIT_HWRPB->phys_addr);
/*
* Locate the command line.
@@ -249,9 +419,10 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p,
type_name, (*var_name ? " variation " : ""), var_name,
hwrpb->sys_type, hwrpb->sys_variation);
}
- if (vec != &alpha_mv)
+ if (vec != &alpha_mv) {
alpha_mv = *vec;
-
+ }
+
#ifdef CONFIG_ALPHA_GENERIC
/* Assume that we've booted from SRM if we havn't booted from MILO.
Detect the later by looking for "MILO" in the system serial nr. */
@@ -281,29 +452,12 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p,
wrmces(0x7);
/* Find our memory. */
- *memory_end_p = find_end_memory();
- *memory_start_p = (unsigned long) _end;
-
-#ifdef CONFIG_BLK_DEV_INITRD
- initrd_start = INITRD_START;
- if (initrd_start) {
- initrd_end = initrd_start+INITRD_SIZE;
- printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
- (void *) initrd_start, INITRD_SIZE);
-
- if (initrd_end > *memory_end_p) {
- printk("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
- initrd_end, (unsigned long) memory_end_p);
- initrd_start = initrd_end = 0;
- }
- }
-#endif
+ setup_memory();
/* Initialize the machine. Usually has to do with setting up
DMA windows and the like. */
if (alpha_mv.init_arch)
- alpha_mv.init_arch(memory_start_p, memory_end_p);
+ alpha_mv.init_arch();
/* Reserve standard resources. */
reserve_std_resources();
@@ -353,35 +507,6 @@ setup_arch(char **cmdline_p, unsigned long * memory_start_p,
#endif
}
-static unsigned long __init
-find_end_memory(void)
-{
- int i;
- unsigned long high = 0;
- struct memclust_struct * cluster;
- struct memdesc_struct * memdesc;
-
- memdesc = (struct memdesc_struct *)
- (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
- cluster = memdesc->cluster;
-
- for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
- unsigned long tmp;
- tmp = (cluster->start_pfn + cluster->numpages) << PAGE_SHIFT;
- if (tmp > high)
- high = tmp;
- }
-
- /* Round it up to an even number of pages. */
- high = (high + PAGE_SIZE) & (PAGE_MASK*2);
-
- /* Enforce maximum of 2GB even if there is more. Blah. */
- if (high > 0x80000000UL)
- high = 0x80000000UL;
- return PAGE_OFFSET + high;
-}
-
-
static char sys_unknown[] = "Unknown";
static char systype_names[][16] = {
"0",
@@ -391,11 +516,13 @@ static char systype_names[][16] = {
"Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1",
"Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake",
"Cortex", "29", "Miata", "XXM", "Takara", "Yukon",
- "Tsunami", "Wildfire", "CUSCO"
+ "Tsunami", "Wildfire", "CUSCO", "Eiger"
};
static char unofficial_names[][8] = {"100", "Ruffian"};
+static char api_names[][16] = {"200", "Nautilus"};
+
static char eb164_names[][8] = {"EB164", "PC164", "LX164", "SX164", "RX164"};
static int eb164_indices[] = {0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3,4};
@@ -419,7 +546,6 @@ static char tsunami_names[][16] = {
};
static int tsunami_indices[] = {0,1,2,3,4,5,6,7,8};
-
static struct alpha_machine_vector * __init
get_sysvec(long type, long variation, long cpu)
{
@@ -462,6 +588,7 @@ get_sysvec(long type, long variation, long cpu)
NULL, /* Tsunami -- see variation. */
NULL, /* Wildfire */
NULL, /* CUSCO */
+ &eiger_mv, /* Eiger */
};
static struct alpha_machine_vector *unofficial_vecs[] __initlocaldata =
@@ -470,6 +597,12 @@ get_sysvec(long type, long variation, long cpu)
&ruffian_mv,
};
+ static struct alpha_machine_vector *api_vecs[] __initlocaldata =
+ {
+ NULL, /* 200 */
+ &nautilus_mv,
+ };
+
static struct alpha_machine_vector *alcor_vecs[] __initlocaldata =
{
&alcor_mv, &xlt_mv, &xlt_mv
@@ -518,6 +651,9 @@ get_sysvec(long type, long variation, long cpu)
vec = NULL;
if (type < N(systype_vecs)) {
vec = systype_vecs[type];
+ } else if ((type > ST_API_BIAS) &&
+ (type - ST_API_BIAS) < N(api_vecs)) {
+ vec = api_vecs[type - ST_API_BIAS];
} else if ((type > ST_UNOFFICIAL_BIAS) &&
(type - ST_UNOFFICIAL_BIAS) < N(unofficial_vecs)) {
vec = unofficial_vecs[type - ST_UNOFFICIAL_BIAS];
@@ -591,12 +727,14 @@ get_sysvec_byname(const char *name)
&eb64p_mv,
&eb66_mv,
&eb66p_mv,
+ &eiger_mv,
&jensen_mv,
&lx164_mv,
&miata_mv,
&mikasa_mv,
&mikasa_primo_mv,
&monet_mv,
+ &nautilus_mv,
&noname_mv,
&noritake_mv,
&noritake_primo_mv,
@@ -637,6 +775,9 @@ get_sysnames(long type, long variation,
else set type name to family */
if (type < N(systype_names)) {
*type_name = systype_names[type];
+ } else if ((type > ST_API_BIAS) &&
+ (type - ST_API_BIAS) < N(api_names)) {
+ *type_name = api_names[type - ST_API_BIAS];
} else if ((type > ST_UNOFFICIAL_BIAS) &&
(type - ST_UNOFFICIAL_BIAS) < N(unofficial_names)) {
*type_name = unofficial_names[type - ST_UNOFFICIAL_BIAS];
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index cd8f6e0ad..cc5d8b16b 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -688,6 +688,7 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index e35dd7c7e..3fbf11495 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
+#include <linux/irq.h>
#include <asm/hwrpb.h>
#include <asm/ptrace.h>
@@ -23,14 +24,15 @@
#include <asm/irq.h>
#include <asm/bitops.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/hardirq.h>
#include <asm/softirq.h>
+#include <asm/mmu_context.h>
#define __KERNEL_SYSCALLS__
#include <asm/unistd.h>
#include "proto.h"
-#include "irq_impl.h"
#define DEBUG_SMP 0
@@ -45,8 +47,8 @@ struct cpuinfo_alpha cpu_data[NR_CPUS];
/* A collection of single bit ipi messages. */
static struct {
- unsigned long bits __cacheline_aligned;
-} ipi_data[NR_CPUS];
+ unsigned long bits ____cacheline_aligned;
+} ipi_data[NR_CPUS] __cacheline_aligned;
enum ipi_message_type {
IPI_RESCHEDULE,
@@ -54,7 +56,7 @@ enum ipi_message_type {
IPI_CPU_STOP,
};
-spinlock_t kernel_flag __cacheline_aligned = SPIN_LOCK_UNLOCKED;
+spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
/* Set to a secondary's cpuid when it comes online. */
static unsigned long smp_secondary_alive;
@@ -394,6 +396,16 @@ started:
return 0;
}
+static int __init fork_by_hand(void)
+{
+ struct pt_regs regs;
+ /*
+ * don't care about the regs settings since
+ * we'll never reschedule the forked task.
+ */
+ return do_fork(CLONE_VM|CLONE_PID, 0, &regs);
+}
+
/*
* Bring one cpu online.
*/
@@ -407,18 +419,25 @@ smp_boot_one_cpu(int cpuid, int cpunum)
to kernel_thread is irrelevant -- it's going to start where
HWRPB.CPU_restart says to start. But this gets all the other
task-y sort of data structures set up like we wish. */
- kernel_thread((void *)__smp_callin, NULL, CLONE_PID|CLONE_VM);
+ /*
+ * We can't use kernel_thread since we must avoid to
+ * reschedule the child.
+ */
+ if (fork_by_hand() < 0)
+ panic("failed fork for CPU %d", cpuid);
idle = init_task.prev_task;
if (!idle)
- panic("No idle process for CPU %d", cpunum);
- del_from_runqueue(idle);
- init_tasks[cpunum] = idle;
- idle->processor = cpuid;
+ panic("No idle process for CPU %d", cpuid);
- /* Schedule the first task manually. */
- /* ??? Ingo, what is this? */
- idle->has_cpu = 1;
+ idle->processor = cpuid;
+ __cpu_logical_map[cpunum] = cpuid;
+ cpu_number_map[cpuid] = cpunum;
+ idle->has_cpu = 1; /* we schedule the first task manually */
+
+ del_from_runqueue(idle);
+ unhash_process(idle);
+ init_tasks[cpunum] = idle;
DBGS(("smp_boot_one_cpu: CPU %d state 0x%lx flags 0x%lx\n",
cpuid, idle->state, idle->flags));
@@ -440,13 +459,18 @@ smp_boot_one_cpu(int cpuid, int cpunum)
barrier();
}
+ /* we must invalidate our stuff as we failed to boot the CPU */
+ __cpu_logical_map[cpunum] = -1;
+ cpu_number_map[cpuid] = -1;
+
+ /* the idle task is local to us so free it as we don't use it */
+ free_task_struct(idle);
+
printk(KERN_ERR "SMP: Processor %d is stuck.\n", cpuid);
return -1;
alive:
/* Another "Red Snapper". */
- cpu_number_map[cpuid] = cpunum;
- __cpu_logical_map[cpunum] = cpuid;
return 0;
}
@@ -579,16 +603,6 @@ smp_commence(void)
mb();
}
-/*
- * Only broken Intel needs this, thus it should not even be
- * referenced globally.
- */
-
-void __init
-initialize_secondary(void)
-{
-}
-
extern void update_one_process(struct task_struct *p, unsigned long ticks,
unsigned long user, unsigned long system,
diff --git a/arch/alpha/kernel/sys_alcor.c b/arch/alpha/kernel/sys_alcor.c
index fbc1b99ba..2a27bac5b 100644
--- a/arch/alpha/kernel/sys_alcor.c
+++ b/arch/alpha/kernel/sys_alcor.c
@@ -27,7 +27,7 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -176,15 +176,13 @@ alcor_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
}
static void
-alcor_kill_arch(int mode, char *reboot_cmd)
+alcor_kill_arch(int mode)
{
/* Who said DEC engineer's have no sense of humor? ;-) */
if (alpha_using_srm) {
*(vuip) GRU_RESET = 0x0000dead;
mb();
}
-
- common_kill_arch(mode, reboot_cmd);
}
diff --git a/arch/alpha/kernel/sys_cabriolet.c b/arch/alpha/kernel/sys_cabriolet.c
index 244759d1f..bc4d2c2ba 100644
--- a/arch/alpha/kernel/sys_cabriolet.c
+++ b/arch/alpha/kernel/sys_cabriolet.c
@@ -31,7 +31,7 @@
#include <asm/core_pyxis.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -269,7 +269,7 @@ struct alpha_machine_vector cabriolet_mv __initmv = {
init_irq: cabriolet_init_irq,
init_pit: common_init_pit,
init_pci: cabriolet_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: cabriolet_map_irq,
pci_swizzle: common_swizzle,
};
@@ -298,7 +298,6 @@ struct alpha_machine_vector eb164_mv __initmv = {
init_irq: cabriolet_init_irq,
init_pit: common_init_pit,
init_pci: cabriolet_init_pci,
- kill_arch: common_kill_arch,
pci_map_irq: cabriolet_map_irq,
pci_swizzle: common_swizzle,
};
@@ -327,7 +326,6 @@ struct alpha_machine_vector eb66p_mv __initmv = {
init_irq: cabriolet_init_irq,
init_pit: common_init_pit,
init_pci: cabriolet_init_pci,
- kill_arch: common_kill_arch,
pci_map_irq: eb66p_map_irq,
pci_swizzle: common_swizzle,
};
@@ -356,7 +354,6 @@ struct alpha_machine_vector lx164_mv __initmv = {
init_irq: cabriolet_init_irq,
init_pit: common_init_pit,
init_pci: alphapc164_init_pci,
- kill_arch: common_kill_arch,
pci_map_irq: alphapc164_map_irq,
pci_swizzle: common_swizzle,
};
@@ -385,7 +382,6 @@ struct alpha_machine_vector pc164_mv __initmv = {
init_irq: cabriolet_init_irq,
init_pit: common_init_pit,
init_pci: alphapc164_init_pci,
- kill_arch: common_kill_arch,
pci_map_irq: alphapc164_map_irq,
pci_swizzle: common_swizzle,
};
diff --git a/arch/alpha/kernel/sys_dp264.c b/arch/alpha/kernel/sys_dp264.c
index 9959aad33..f0ef47183 100644
--- a/arch/alpha/kernel/sys_dp264.c
+++ b/arch/alpha/kernel/sys_dp264.c
@@ -27,7 +27,7 @@
#include <asm/hwrpb.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -39,28 +39,30 @@
static void
dp264_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
{
- if (irq >= 16) {
- volatile unsigned long *csr;
+ volatile unsigned long *csr;
- if (TSUNAMI_bootcpu < 2)
- if (!TSUNAMI_bootcpu)
- csr = &TSUNAMI_cchip->dim0.csr;
- else
- csr = &TSUNAMI_cchip->dim1.csr;
+ if (TSUNAMI_bootcpu < 2) {
+ if (!TSUNAMI_bootcpu)
+ csr = &TSUNAMI_cchip->dim0.csr;
else
- if (TSUNAMI_bootcpu == 2)
- csr = &TSUNAMI_cchip->dim2.csr;
- else
- csr = &TSUNAMI_cchip->dim3.csr;
-
- *csr = ~mask;
- mb();
- *csr;
+ csr = &TSUNAMI_cchip->dim1.csr;
+ } else {
+ if (TSUNAMI_bootcpu == 2)
+ csr = &TSUNAMI_cchip->dim2.csr;
+ else
+ csr = &TSUNAMI_cchip->dim3.csr;
+ }
+
+ *csr = ~mask;
+ mb();
+ *csr;
+
+ if (irq < 16) {
+ if (irq >= 8)
+ outb(mask >> 8, 0xA1); /* ISA PIC2 */
+ else
+ outb(mask, 0x21); /* ISA PIC1 */
}
- else if (irq >= 8)
- outb(mask >> 8, 0xA1); /* ISA PIC2 */
- else
- outb(mask, 0x21); /* ISA PIC1 */
}
static void
@@ -274,8 +276,19 @@ dp264_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
struct pci_controler *hose = dev->sysdata;
int irq = COMMON_TABLE_LOOKUP;
- if (irq > 0)
+ if (irq > 0) {
irq += 16 * hose->index;
+ } else {
+ /* ??? The Contaq IDE controler on the ISA bridge uses
+ "legacy" interrupts 14 and 15. I don't know if anything
+ can wind up at the same slot+pin on hose1, so we'll
+ just have to trust whatever value the console might
+ have assigned. */
+
+ u8 irq8;
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq8);
+ irq = irq8;
+ }
return irq;
}
@@ -418,7 +431,7 @@ struct alpha_machine_vector dp264_mv __initmv = {
min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 64,
- irq_probe_mask: _PROBE_MASK(64),
+ irq_probe_mask: TSUNAMI_PROBE_MASK,
update_irq_hw: dp264_update_irq_hw,
ack_irq: common_ack_irq,
device_interrupt: dp264_device_interrupt,
@@ -427,7 +440,7 @@ struct alpha_machine_vector dp264_mv __initmv = {
init_irq: dp264_init_irq,
init_pit: common_init_pit,
init_pci: dp264_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: tsunami_kill_arch,
pci_map_irq: dp264_map_irq,
pci_swizzle: common_swizzle,
};
@@ -445,7 +458,7 @@ struct alpha_machine_vector monet_mv __initmv = {
min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 64,
- irq_probe_mask: _PROBE_MASK(64),
+ irq_probe_mask: TSUNAMI_PROBE_MASK,
update_irq_hw: dp264_update_irq_hw,
ack_irq: common_ack_irq,
device_interrupt: dp264_device_interrupt,
@@ -454,7 +467,7 @@ struct alpha_machine_vector monet_mv __initmv = {
init_irq: dp264_init_irq,
init_pit: common_init_pit,
init_pci: monet_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: tsunami_kill_arch,
pci_map_irq: monet_map_irq,
pci_swizzle: monet_swizzle,
};
@@ -471,7 +484,7 @@ struct alpha_machine_vector webbrick_mv __initmv = {
min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 64,
- irq_probe_mask: _PROBE_MASK(64),
+ irq_probe_mask: TSUNAMI_PROBE_MASK,
update_irq_hw: dp264_update_irq_hw,
ack_irq: common_ack_irq,
device_interrupt: dp264_device_interrupt,
@@ -479,8 +492,8 @@ struct alpha_machine_vector webbrick_mv __initmv = {
init_arch: tsunami_init_arch,
init_irq: dp264_init_irq,
init_pit: common_init_pit,
- init_pci: dp264_init_pci,
- kill_arch: common_kill_arch,
+ init_pci: common_init_pci,
+ kill_arch: tsunami_kill_arch,
pci_map_irq: webbrick_map_irq,
pci_swizzle: common_swizzle,
};
@@ -497,7 +510,7 @@ struct alpha_machine_vector clipper_mv __initmv = {
min_mem_address: DEFAULT_MEM_BASE,
nr_irqs: 64,
- irq_probe_mask: _PROBE_MASK(64),
+ irq_probe_mask: TSUNAMI_PROBE_MASK,
update_irq_hw: clipper_update_irq_hw,
ack_irq: common_ack_irq,
device_interrupt: dp264_device_interrupt,
@@ -506,7 +519,7 @@ struct alpha_machine_vector clipper_mv __initmv = {
init_irq: clipper_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: tsunami_kill_arch,
pci_map_irq: clipper_map_irq,
pci_swizzle: common_swizzle,
};
diff --git a/arch/alpha/kernel/sys_eb64p.c b/arch/alpha/kernel/sys_eb64p.c
index 09e0b0def..e8e224715 100644
--- a/arch/alpha/kernel/sys_eb64p.c
+++ b/arch/alpha/kernel/sys_eb64p.c
@@ -28,7 +28,7 @@
#include <asm/core_lca.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -183,7 +183,7 @@ struct alpha_machine_vector eb64p_mv __initmv = {
init_irq: eb64p_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: eb64p_map_irq,
pci_swizzle: common_swizzle,
};
@@ -212,7 +212,6 @@ struct alpha_machine_vector eb66_mv __initmv = {
init_irq: eb64p_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
pci_map_irq: eb64p_map_irq,
pci_swizzle: common_swizzle,
};
diff --git a/arch/alpha/kernel/sys_eiger.c b/arch/alpha/kernel/sys_eiger.c
new file mode 100644
index 000000000..433abddfb
--- /dev/null
+++ b/arch/alpha/kernel/sys_eiger.c
@@ -0,0 +1,215 @@
+/*
+ * linux/arch/alpha/kernel/sys_eiger.c
+ *
+ * Copyright (C) 1995 David A Rusling
+ * Copyright (C) 1996, 1999 Jay A Estabrook
+ * Copyright (C) 1998, 1999 Richard Henderson
+ * Copyright (C) 1999 Iain Grant
+ *
+ * Code supporting the EIGER (EV6+TSUNAMI).
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/pgtable.h>
+#include <asm/core_tsunami.h>
+#include <asm/hwrpb.h>
+
+#include "proto.h"
+#include <asm/hw_irq.h>
+#include "pci_impl.h"
+#include "machvec_impl.h"
+
+
+/*
+ * HACK ALERT! only the boot cpu is used for interrupts.
+ */
+
+static void
+eiger_update_irq_hw(unsigned long irq, unsigned long unused, int unmask_p)
+{
+ unsigned int regaddr;
+ unsigned long mask;
+
+ if (irq <= 15) {
+ if (irq <= 7)
+ outb(alpha_irq_mask, 0x21); /* ISA PIC1 */
+ else
+ outb(alpha_irq_mask >> 8, 0xA1); /* ISA PIC2 */
+ } else {
+ if (irq > 63)
+ mask = _alpha_irq_masks[1] << 16;
+ else
+ mask = _alpha_irq_masks[0] >> ((irq - 16) & 0x30);
+
+ regaddr = 0x510 + (((irq - 16) >> 2) & 0x0c);
+
+ outl(mask & 0xffff0000UL, regaddr);
+ }
+}
+
+static void
+eiger_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+ unsigned intstatus;
+
+ /*
+ * The PALcode will have passed us vectors 0x800 or 0x810,
+ * which are fairly arbitrary values and serve only to tell
+ * us whether an interrupt has come in on IRQ0 or IRQ1. If
+ * it's IRQ1 it's a PCI interrupt; if it's IRQ0, it's
+ * probably ISA, but PCI interrupts can come through IRQ0
+ * as well if the interrupt controller isn't in accelerated
+ * mode.
+ *
+ * OTOH, the accelerator thing doesn't seem to be working
+ * overly well, so what we'll do instead is try directly
+ * examining the Master Interrupt Register to see if it's a
+ * PCI interrupt, and if _not_ then we'll pass it on to the
+ * ISA handler.
+ */
+
+ intstatus = inw(0x500) & 15;
+ if (intstatus) {
+ /*
+ * This is a PCI interrupt. Check each bit and
+ * despatch an interrupt if it's set.
+ */
+
+ if (intstatus & 8) handle_irq(16+3, 16+3, regs);
+ if (intstatus & 4) handle_irq(16+2, 16+2, regs);
+ if (intstatus & 2) handle_irq(16+1, 16+1, regs);
+ if (intstatus & 1) handle_irq(16+0, 16+0, regs);
+ } else {
+ isa_device_interrupt (vector, regs);
+ }
+}
+
+static void
+eiger_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
+{
+ int irq = (vector - 0x800) >> 4;
+ handle_irq(irq, irq, regs);
+}
+
+static void __init
+eiger_init_irq(void)
+{
+ outb(0, DMA1_RESET_REG);
+ outb(0, DMA2_RESET_REG);
+ outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
+ outb(0, DMA2_MASK_REG);
+
+ if (alpha_using_srm)
+ alpha_mv.device_interrupt = eiger_srm_device_interrupt;
+
+ eiger_update_irq_hw(16, alpha_irq_mask, 0);
+
+ enable_irq(2);
+}
+
+static int __init
+eiger_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ u8 irq_orig;
+
+ /* The SRM console has already calculated out the IRQ value's for
+ option cards. As this works lets just read in the value already
+ set and change it to a useable value by Linux.
+
+ All the IRQ values generated by the console are greater than 90,
+ so we subtract 80 because it is (90 - allocated ISA IRQ's). */
+
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq_orig);
+
+ return irq_orig - 0x80;
+}
+
+static u8 __init
+eiger_swizzle(struct pci_dev *dev, u8 *pinp)
+{
+ struct pci_controler *hose = dev->sysdata;
+ int slot, pin = *pinp;
+ int bridge_count = 0;
+
+ /* Find the number of backplane bridges. */
+ int backplane = inw(0x502) & 0x0f;
+
+ switch (backplane)
+ {
+ case 0x00: bridge_count = 0; break; /* No bridges */
+ case 0x01: bridge_count = 1; break; /* 1 */
+ case 0x03: bridge_count = 2; break; /* 2 */
+ case 0x07: bridge_count = 3; break; /* 3 */
+ case 0x0f: bridge_count = 4; break; /* 4 */
+ };
+
+ /* Check first for the built-in bridges on hose 0. */
+ if (hose->index == 0
+ && PCI_SLOT(dev->bus->self->devfn) > 20-bridge_count) {
+ slot = PCI_SLOT(dev->devfn);
+ } else {
+ /* Must be a card-based bridge. */
+ do {
+ /* Check for built-in bridges on hose 0. */
+ if (hose->index == 0
+ && (PCI_SLOT(dev->bus->self->devfn)
+ > 20 - bridge_count)) {
+ slot = PCI_SLOT(dev->devfn);
+ break;
+ }
+ pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
+
+ /* Move up the chain of bridges. */
+ dev = dev->bus->self;
+ /* Slot of the next bridge. */
+ slot = PCI_SLOT(dev->devfn);
+ } while (dev->bus->self);
+ }
+ *pinp = pin;
+ return slot;
+}
+
+/*
+ * The System Vectors
+ */
+
+struct alpha_machine_vector eiger_mv __initmv = {
+ vector_name: "Eiger",
+ DO_EV6_MMU,
+ DO_DEFAULT_RTC,
+ DO_TSUNAMI_IO,
+ DO_TSUNAMI_BUS,
+ machine_check: tsunami_machine_check,
+ max_dma_address: ALPHA_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
+
+ nr_irqs: 128,
+ irq_probe_mask: TSUNAMI_PROBE_MASK,
+ update_irq_hw: eiger_update_irq_hw,
+ ack_irq: common_ack_irq,
+ device_interrupt: eiger_device_interrupt,
+
+ init_arch: tsunami_init_arch,
+ init_irq: eiger_init_irq,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: tsunami_kill_arch,
+ pci_map_irq: eiger_map_irq,
+ pci_swizzle: eiger_swizzle,
+};
+ALIAS_MV(eiger)
diff --git a/arch/alpha/kernel/sys_jensen.c b/arch/alpha/kernel/sys_jensen.c
index 0380574a8..ad156c9f2 100644
--- a/arch/alpha/kernel/sys_jensen.c
+++ b/arch/alpha/kernel/sys_jensen.c
@@ -28,7 +28,7 @@
#include <asm/pgtable.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "machvec_impl.h"
@@ -140,6 +140,6 @@ struct alpha_machine_vector jensen_mv __initmv = {
init_irq: jensen_init_irq,
init_pit: common_init_pit,
init_pci: NULL,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
};
ALIAS_MV(jensen)
diff --git a/arch/alpha/kernel/sys_miata.c b/arch/alpha/kernel/sys_miata.c
index 0bea4e3dd..b2da23528 100644
--- a/arch/alpha/kernel/sys_miata.c
+++ b/arch/alpha/kernel/sys_miata.c
@@ -25,7 +25,7 @@
#include <asm/core_pyxis.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -274,14 +274,13 @@ miata_init_pci(void)
}
static void
-miata_kill_arch (int mode, char *reboot_cmd)
+miata_kill_arch(int mode)
{
/* Who said DEC engineers have no sense of humor? ;-) */
if (alpha_using_srm) {
*(vuip) PYXIS_RESET = 0x0000dead;
mb();
}
- common_kill_arch(mode, reboot_cmd);
}
diff --git a/arch/alpha/kernel/sys_mikasa.c b/arch/alpha/kernel/sys_mikasa.c
index 0c08d9fc0..ac55371a6 100644
--- a/arch/alpha/kernel/sys_mikasa.c
+++ b/arch/alpha/kernel/sys_mikasa.c
@@ -28,7 +28,7 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -194,7 +194,7 @@ struct alpha_machine_vector mikasa_mv __initmv = {
init_irq: mikasa_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: mikasa_map_irq,
pci_swizzle: common_swizzle,
};
@@ -223,7 +223,6 @@ struct alpha_machine_vector mikasa_primo_mv __initmv = {
init_irq: mikasa_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
pci_map_irq: mikasa_map_irq,
pci_swizzle: common_swizzle,
};
diff --git a/arch/alpha/kernel/sys_nautilus.c b/arch/alpha/kernel/sys_nautilus.c
new file mode 100644
index 000000000..b51eee671
--- /dev/null
+++ b/arch/alpha/kernel/sys_nautilus.c
@@ -0,0 +1,535 @@
+/*
+ * linux/arch/alpha/kernel/sys_nautilus.c
+ *
+ * Copyright (C) 1995 David A Rusling
+ * Copyright (C) 1998 Richard Henderson
+ * Copyright (C) 1999 Alpha Processor, Inc.,
+ * (David Daniel, Stig Telfer, Soohoon Lee)
+ *
+ * Code supporting NAUTILUS systems.
+ *
+ *
+ * NAUTILUS has the following I/O features:
+ *
+ * a) Driven by AMD 751 aka IRONGATE (northbridge):
+ * 4 PCI slots
+ * 1 AGP slot
+ *
+ * b) Driven by ALI M1543C (southbridge)
+ * 2 ISA slots
+ * 2 IDE connectors
+ * 1 dual drive capable FDD controller
+ * 2 serial ports
+ * 1 ECP/EPP/SP parallel port
+ * 2 USB ports
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/reboot.h>
+
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/dma.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/mmu_context.h>
+#include <asm/io.h>
+#include <asm/pci.h>
+#include <asm/pgtable.h>
+#include <asm/core_irongate.h>
+#include <asm/hwrpb.h>
+
+#include "proto.h"
+#include <asm/hw_irq.h>
+#include "pci_impl.h"
+#include "machvec_impl.h"
+
+#define dev2hose(d) (bus2hose[(d)->bus->number]->pci_hose_index)
+
+static void
+nautilus_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
+{
+ /* The timer is connected to PIC interrupt line also on Nautilus.
+ The timer interrupt handler enables the PIC line, so in order
+ not to get multiple timer interrupt sources, we mask it out
+ at all times. */
+
+ mask |= 0x100;
+ if (irq >= 8)
+ outb(mask >> 8, 0xA1);
+ else
+ outb(mask, 0x21);
+}
+
+static void __init
+nautilus_init_irq(void)
+{
+ STANDARD_INIT_IRQ_PROLOG;
+
+ enable_irq(2); /* enable cascade */
+ disable_irq(8);
+}
+
+static int __init
+nautilus_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ /* Preserve the IRQ set up by the console. */
+
+ u8 irq;
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
+ return irq;
+}
+
+void
+nautilus_kill_arch(int mode)
+{
+ u8 tmp;
+
+ if (mode == LINUX_REBOOT_CMD_RESTART) {
+ pcibios_read_config_byte(0, 0x38, 0x43, &tmp);
+ pcibios_write_config_byte(0, 0x38, 0x43, tmp | 0x80);
+ outb(1, 0x92);
+ outb(0, 0x92);
+ }
+}
+
+/* Machine check handler code
+ *
+ * Perform analysis of a machine check that was triggered by the EV6
+ * CPU's fault-detection mechanism.
+ */
+
+/* IPR structures for EV6, containing the necessary data for the
+ * machine check handler to unpick the logout frame
+ */
+
+/* I_STAT */
+
+#define EV6__I_STAT__PAR ( 1 << 29 )
+
+/* MM_STAT */
+
+#define EV6__MM_STAT__DC_TAG_PERR ( 1 << 10 )
+
+/* DC_STAT */
+
+#define EV6__DC_STAT__SEO ( 1 << 4 )
+#define EV6__DC_STAT__ECC_ERR_LD ( 1 << 3 )
+#define EV6__DC_STAT__ECC_ERR_ST ( 1 << 2 )
+#define EV6__DC_STAT__TPERR_P1 ( 1 << 1 )
+#define EV6__DC_STAT__TPERR_P0 ( 1 )
+
+/* C_STAT */
+
+#define EV6__C_STAT__BC_PERR ( 0x01 )
+#define EV6__C_STAT__DC_PERR ( 0x02 )
+#define EV6__C_STAT__DSTREAM_MEM_ERR ( 0x03 )
+#define EV6__C_STAT__DSTREAM_BC_ERR ( 0x04 )
+#define EV6__C_STAT__DSTREAM_DC_ERR ( 0x05 )
+#define EV6__C_STAT__PROBE_BC_ERR0 ( 0x06 )
+#define EV6__C_STAT__PROBE_BC_ERR1 ( 0x07 )
+#define EV6__C_STAT__ISTREAM_MEM_ERR ( 0x0B )
+#define EV6__C_STAT__ISTREAM_BC_ERR ( 0x0C )
+#define EV6__C_STAT__DSTREAM_MEM_DBL ( 0x13 )
+#define EV6__C_STAT__DSTREAM_BC_DBL ( 0x14 )
+#define EV6__C_STAT__ISTREAM_MEM_DBL ( 0x1B )
+#define EV6__C_STAT__ISTREAM_BC_DBL ( 0x1C )
+
+
+/* Take the two syndromes from the CBOX error chain and convert them
+ * into a bit number. */
+
+/* NOTE - since I don't know of any difference between C0 and C1 I
+ just ignore C1, since in all cases I've seen so far they are
+ identical. */
+
+static const unsigned char ev6_bit_to_syndrome[72] =
+{
+ 0xce, 0xcb, 0xd3, 0xd5, 0xd6, 0xd9, 0xda, 0xdc, /* 0 */
+ 0x23, 0x25, 0x26, 0x29, 0x2a, 0x2c, 0x31, 0x34, /* 8 */
+ 0x0e, 0x0b, 0x13, 0x15, 0x16, 0x19, 0x1a, 0x1c, /* 16 */
+ 0xe3, 0xe5, 0xe6, 0xe9, 0xea, 0xec, 0xf1, 0xf4, /* 24 */
+ 0x4f, 0x4a, 0x52, 0x54, 0x57, 0x58, 0x5b, 0x5d, /* 32 */
+ 0xa2, 0xa4, 0xa7, 0xa8, 0xab, 0xad, 0xb0, 0xb5, /* 40 */
+ 0x8f, 0x8a, 0x92, 0x94, 0x97, 0x98, 0x9b, 0x9d, /* 48 */
+ 0x62, 0x64, 0x67, 0x68, 0x6b, 0x6d, 0x70, 0x75, /* 56 */
+ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 /* 64 */
+};
+
+
+static int ev6_syn2bit(unsigned long c0, unsigned long c1)
+{
+ int bit;
+
+ for (bit = 0; bit < 72; bit++)
+ if (ev6_bit_to_syndrome[bit] == c0) return bit;
+ for (bit = 0; bit < 72; bit++)
+ if (ev6_bit_to_syndrome[bit] == c1) return bit + 64;
+
+ return -1; /* not found */
+}
+
+
+/* Single bit ECC errors are categorized here. */
+
+#if 0
+static const char *interr = "CPU internal error";
+static const char *slotb= "Slot-B error";
+static const char *membus= "Memory/EV6-bus error";
+#else
+static const char *interr = "";
+static const char *slotb = "";
+static const char *membus = "";
+#endif
+
+static void
+ev6_crd_interp(char *interp, struct el_common_EV6_mcheck * L)
+{
+ /* Icache data or tag parity error. */
+ if (L->I_STAT & EV6__I_STAT__PAR) {
+ sprintf(interp, "%s: I_STAT[PAR]\n "
+ "Icache data or tag parity error", interr);
+ return;
+ }
+
+ /* Dcache tag parity error (on issue) (DFAULT). */
+ if (L->MM_STAT & EV6__MM_STAT__DC_TAG_PERR) {
+ sprintf(interp, "%s: MM_STAT[DC_TAG_PERR]\n "
+ "Dcache tag parity error(on issue)", interr);
+ return;
+ }
+
+ /* Errors relating to D-stream set non-zero DC_STAT.
+ Mask CRD bits. */
+ switch (L->DC_STAT & (EV6__DC_STAT__ECC_ERR_ST
+ | EV6__DC_STAT__ECC_ERR_LD)) {
+ case EV6__DC_STAT__ECC_ERR_ST:
+ /* Dcache single-bit ECC error on small store */
+ sprintf(interp, "%s: DC_STAT[ECC_ERR_ST]\n "
+ "Dcache single-bit ECC error on small store", interr);
+ return;
+
+ case EV6__DC_STAT__ECC_ERR_LD:
+ switch (L->C_STAT) {
+ case 0:
+ /* Dcache single-bit error on speculative load */
+ /* Bcache victim read on Dcache/Bcache miss */
+ sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT=0\n "
+ "Dcache single-bit ECC error on speculative load",
+ slotb);
+ return;
+
+ case EV6__C_STAT__DSTREAM_DC_ERR:
+ /* Dcache single bit error on load */
+ sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT[DSTREAM_DC_ERR]\n"
+ " Dcache single-bit ECC error on speculative load, bit %d",
+ interr, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+ return;
+
+ case EV6__C_STAT__DSTREAM_BC_ERR:
+ /* Bcache single-bit error on Dcache fill */
+ sprintf(interp, "%s: DC_STAT[ECC_ERR_LD] C_STAT[DSTREAM_BC_ERR]\n"
+ " Bcache single-bit error on Dcache fill, bit %d",
+ slotb, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+ return;
+
+ case EV6__C_STAT__DSTREAM_MEM_ERR:
+ /* Memory single-bit error on Dcache fill */
+ sprintf(interp, "%s (to Dcache): DC_STAT[ECC_ERR_LD] "
+ "C_STAT[DSTREAM_MEM_ERR]\n "
+ "Memory single-bit error on Dcache fill, "
+ "Address 0x%lX, bit %d",
+ membus, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
+ L->DC1_SYNDROME));
+ return;
+ }
+ }
+
+ /* I-stream, other misc errors go on C_STAT alone */
+ switch (L->C_STAT) {
+ case EV6__C_STAT__ISTREAM_BC_ERR:
+ /* Bcache single-bit error on Icache fill (also MCHK) */
+ sprintf(interp, "%s: C_STAT[ISTREAM_BC_ERR]\n "
+ "Bcache single-bit error on Icache fill, bit %d",
+ slotb, ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+ return;
+
+ case EV6__C_STAT__ISTREAM_MEM_ERR:
+ /* Memory single-bit error on Icache fill (also MCHK) */
+ sprintf(interp, "%s : C_STATISTREAM_MEM_ERR]\n "
+ "Memory single-bit error on Icache fill "
+ "addr 0x%lX, bit %d",
+ membus, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
+ L->DC1_SYNDROME));
+ return;
+
+ case EV6__C_STAT__PROBE_BC_ERR0:
+ case EV6__C_STAT__PROBE_BC_ERR1:
+ /* Bcache single-bit error on a probe hit */
+ sprintf(interp, "%s: C_STAT[PROBE_BC_ERR]\n "
+ "Bcache single-bit error on a probe hit, "
+ "addr 0x%lx, bit %d",
+ slotb, L->C_ADDR, ev6_syn2bit(L->DC0_SYNDROME,
+ L->DC1_SYNDROME));
+ return;
+ }
+}
+
+static void
+ev6_mchk_interp(char *interp, struct el_common_EV6_mcheck * L)
+{
+ /* Machine check errors described by DC_STAT */
+ switch (L->DC_STAT) {
+ case EV6__DC_STAT__TPERR_P0:
+ case EV6__DC_STAT__TPERR_P1:
+ /* Dcache tag parity error (on retry) */
+ sprintf(interp, "%s: DC_STAT[TPERR_P0|TPERR_P1]\n "
+ "Dcache tag parity error(on retry)", interr);
+ return;
+
+ case EV6__DC_STAT__SEO:
+ /* Dcache second error on store */
+ sprintf(interp, "%s: DC_STAT[SEO]\n "
+ "Dcache second error during mcheck", interr);
+ return;
+ }
+
+ /* Machine check errors described by C_STAT */
+ switch (L->C_STAT) {
+ case EV6__C_STAT__DC_PERR:
+ /* Dcache duplicate tag parity error */
+ sprintf(interp, "%s: C_STAT[DC_PERR]\n "
+ "Dcache duplicate tag parity error at 0x%lX",
+ interr, L->C_ADDR);
+ return;
+
+ case EV6__C_STAT__BC_PERR:
+ /* Bcache tag parity error */
+ sprintf(interp, "%s: C_STAT[BC_PERR]\n "
+ "Bcache tag parity error at 0x%lX",
+ slotb, L->C_ADDR);
+ return;
+
+ case EV6__C_STAT__ISTREAM_BC_ERR:
+ /* Bcache single-bit error on Icache fill (also CRD) */
+ sprintf(interp, "%s: C_STAT[ISTREAM_BC_ERR]\n "
+ "Bcache single-bit error on Icache fill 0x%lX bit %d",
+ slotb, L->C_ADDR,
+ ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+ return;
+
+
+ case EV6__C_STAT__ISTREAM_MEM_ERR:
+ /* Memory single-bit error on Icache fill (also CRD) */
+ sprintf(interp, "%s: C_STAT[ISTREAM_MEM_ERR]\n "
+ "Memory single-bit error on Icache fill 0x%lX, bit %d",
+ membus, L->C_ADDR,
+ ev6_syn2bit(L->DC0_SYNDROME, L->DC1_SYNDROME));
+ return;
+
+
+ case EV6__C_STAT__ISTREAM_BC_DBL:
+ /* Bcache double-bit error on Icache fill */
+ sprintf(interp, "%s: C_STAT[ISTREAM_BC_DBL]\n "
+ "Bcache double-bit error on Icache fill at 0x%lX",
+ slotb, L->C_ADDR);
+ return;
+ case EV6__C_STAT__DSTREAM_BC_DBL:
+ /* Bcache double-bit error on Dcache fill */
+ sprintf(interp, "%s: C_STAT[DSTREAM_BC_DBL]\n "
+ "Bcache double-bit error on Dcache fill at 0x%lX",
+ slotb, L->C_ADDR);
+ return;
+
+ case EV6__C_STAT__ISTREAM_MEM_DBL:
+ /* Memory double-bit error on Icache fill */
+ sprintf(interp, "%s: C_STAT[ISTREAM_MEM_DBL]\n "
+ "Memory double-bit error on Icache fill at 0x%lX",
+ membus, L->C_ADDR);
+ return;
+
+ case EV6__C_STAT__DSTREAM_MEM_DBL:
+ /* Memory double-bit error on Dcache fill */
+ sprintf(interp, "%s: C_STAT[DSTREAM_MEM_DBL]\n "
+ "Memory double-bit error on Dcache fill at 0x%lX",
+ membus, L->C_ADDR);
+ return;
+ }
+}
+
+static void
+ev6_cpu_machine_check(unsigned long vector, struct el_common_EV6_mcheck *L,
+ struct pt_regs *regs)
+{
+ char interp[80];
+
+ /* This is verbose and looks intimidating. Should it be printed for
+ corrected (CRD) machine checks? */
+
+ printk(KERN_CRIT "PALcode logout frame: "
+ "MCHK_Code %d "
+ "MCHK_Frame_Rev %d\n"
+ "I_STAT %016lx "
+ "DC_STAT %016lx "
+ "C_ADDR %016lx\n"
+ "SYND1 %016lx "
+ "SYND0 %016lx "
+ "C_STAT %016lx\n"
+ "C_STS %016lx "
+ "RES %016lx "
+ "EXC_ADDR%016lx\n"
+ "IER_CM %016lx "
+ "ISUM %016lx "
+ "MM_STAT %016lx\n"
+ "PALBASE %016lx "
+ "I_CTL %016lx "
+ "PCTX %016lx\n"
+ "CPU registers: "
+ "PC %016lx "
+ "Return %016lx\n",
+ L->MCHK_Code, L->MCHK_Frame_Rev, L->I_STAT, L->DC_STAT,
+ L->C_ADDR, L->DC1_SYNDROME, L->DC0_SYNDROME, L->C_STAT,
+ L->C_STS, L->RESERVED0, L->EXC_ADDR, L->IER_CM, L->ISUM,
+ L->MM_STAT, L->PAL_BASE, L->I_CTL, L->PCTX,
+ regs->pc, regs->r26);
+
+ /* Attempt an interpretation on the meanings of the fields above. */
+ sprintf(interp, "No interpretation available!" );
+ if (vector == SCB_Q_PROCERR)
+ ev6_crd_interp(interp, L);
+ else if (vector == SCB_Q_PROCMCHK)
+ ev6_mchk_interp(interp, L);
+
+ printk(KERN_CRIT "interpretation: %s\n\n", interp);
+}
+
+
+/* Perform analysis of a machine check that arrived from the system (NMI) */
+
+static void
+naut_sys_machine_check(unsigned long vector, unsigned long la_ptr,
+ struct pt_regs *regs)
+{
+ printk("xtime %lx\n", CURRENT_TIME);
+ printk("PC %lx RA %lx\n", regs->pc, regs->r26);
+ irongate_pci_clr_err();
+}
+
+/* Machine checks can come from two sources - those on the CPU and those
+ in the system. They are analysed separately but all starts here. */
+
+void
+nautilus_machine_check(unsigned long vector, unsigned long la_ptr,
+ struct pt_regs *regs)
+{
+ char *mchk_class;
+ unsigned cpu_analysis=0, sys_analysis=0;
+
+ /* Now for some analysis. Machine checks fall into two classes --
+ those picked up by the system, and those picked up by the CPU.
+ Add to that the two levels of severity - correctable or not. */
+
+ if (vector == SCB_Q_SYSMCHK
+ && ((IRONGATE0->dramms & 0x3FF) == 0x300)) {
+ unsigned long nmi_ctl, temp;
+
+ /* Clear ALI NMI */
+ nmi_ctl = inb(0x61);
+ nmi_ctl |= 0x0c;
+ outb(nmi_ctl, 0x61);
+ nmi_ctl &= ~0x0c;
+ outb(nmi_ctl, 0x61);
+
+ temp = IRONGATE0->stat_cmd;
+ IRONGATE0->stat_cmd = temp; /* write again clears error bits */
+ mb();
+ temp = IRONGATE0->stat_cmd; /* re-read to force write */
+
+ temp = IRONGATE0->dramms;
+ IRONGATE0->dramms = temp; /* write again clears error bits */
+ mb();
+ temp = IRONGATE0->dramms; /* re-read to force write */
+
+ draina();
+ wrmces(0x7);
+ mb();
+ return;
+ }
+
+ switch (vector) {
+ case SCB_Q_SYSERR:
+ mchk_class = "Correctable System Machine Check (NMI)";
+ sys_analysis = 1;
+ break;
+ case SCB_Q_SYSMCHK:
+ mchk_class = "Fatal System Machine Check (NMI)";
+ sys_analysis = 1;
+ break;
+
+ case SCB_Q_PROCERR:
+ mchk_class = "Correctable Processor Machine Check";
+ cpu_analysis = 1;
+ break;
+ case SCB_Q_PROCMCHK:
+ mchk_class = "Fatal Processor Machine Check";
+ cpu_analysis = 1;
+ break;
+
+ default:
+ mchk_class = "Unknown vector!";
+ break;
+ }
+
+ printk(KERN_CRIT "NAUTILUS Machine check 0x%lx [%s]\n",
+ vector, mchk_class);
+
+ if (cpu_analysis)
+ ev6_cpu_machine_check(vector,
+ (struct el_common_EV6_mcheck *)la_ptr,
+ regs);
+ if (sys_analysis)
+ naut_sys_machine_check(vector, la_ptr, regs);
+
+ /* Tell the PALcode to clear the machine check */
+ draina();
+ wrmces(0x7);
+ mb();
+}
+
+
+
+/*
+ * The System Vectors
+ */
+
+struct alpha_machine_vector nautilus_mv __initmv = {
+ vector_name: "Nautilus",
+ DO_EV6_MMU,
+ DO_DEFAULT_RTC,
+ DO_IRONGATE_IO,
+ DO_IRONGATE_BUS,
+ machine_check: nautilus_machine_check,
+ max_dma_address: ALPHA_NAUTILUS_MAX_DMA_ADDRESS,
+ min_io_address: DEFAULT_IO_BASE,
+ min_mem_address: DEFAULT_MEM_BASE,
+
+ nr_irqs: 16,
+ irq_probe_mask: (_PROBE_MASK(16) & ~0x101UL),
+ update_irq_hw: nautilus_update_irq_hw,
+ ack_irq: common_ack_irq,
+ device_interrupt: isa_device_interrupt,
+
+ init_arch: irongate_init_arch,
+ init_irq: nautilus_init_irq,
+ init_pit: common_init_pit,
+ init_pci: common_init_pci,
+ kill_arch: nautilus_kill_arch,
+ pci_map_irq: nautilus_map_irq,
+ pci_swizzle: common_swizzle,
+};
+ALIAS_MV(nautilus)
diff --git a/arch/alpha/kernel/sys_noritake.c b/arch/alpha/kernel/sys_noritake.c
index adce91de2..c1a793393 100644
--- a/arch/alpha/kernel/sys_noritake.c
+++ b/arch/alpha/kernel/sys_noritake.c
@@ -29,7 +29,7 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -254,7 +254,7 @@ struct alpha_machine_vector noritake_mv __initmv = {
init_irq: noritake_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: noritake_map_irq,
pci_swizzle: noritake_swizzle,
};
@@ -283,7 +283,6 @@ struct alpha_machine_vector noritake_primo_mv __initmv = {
init_irq: noritake_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
pci_map_irq: noritake_map_irq,
pci_swizzle: noritake_swizzle,
};
diff --git a/arch/alpha/kernel/sys_rawhide.c b/arch/alpha/kernel/sys_rawhide.c
index 4561c4046..0a0ce2267 100644
--- a/arch/alpha/kernel/sys_rawhide.c
+++ b/arch/alpha/kernel/sys_rawhide.c
@@ -25,46 +25,59 @@
#include <asm/core_mcpcia.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
+static unsigned int hose_irq_masks[4] = {
+ 0xff0000, 0xfe0000, 0xff0000, 0xff0000
+};
+
+
+/* Note that `mask' initially contains only the low 64 bits. */
static void
rawhide_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
{
- if (irq >= 40) {
- /* PCI bus 1 with builtin NCR810 SCSI */
- *(vuip)MCPCIA_INT_MASK0(5) =
- (~((mask) >> 40) & 0x00ffffffU) | 0x00fe0000U;
- mb();
- /* ... and read it back to make sure it got written. */
- *(vuip)MCPCIA_INT_MASK0(5);
+ unsigned int saddle, hose, new_irq;
+
+ if (irq < 16) {
+ if (irq < 8)
+ outb(mask, 0x21); /* ISA PIC1 */
+ else
+ outb(mask >> 8, 0xA1); /* ISA PIC2 */
+ return;
}
- else if (irq >= 16) {
- /* PCI bus 0 with EISA bridge */
- *(vuip)MCPCIA_INT_MASK0(4) =
- (~((mask) >> 16) & 0x00ffffffU) | 0x00ff0000U;
- mb();
- /* ... and read it back to make sure it got written. */
- *(vuip)MCPCIA_INT_MASK0(4);
+
+ saddle = (irq > 63);
+ mask = _alpha_irq_masks[saddle];
+
+ if (saddle == 0) {
+ /* Saddle 0 includes EISA interrupts. */
+ mask >>= 16;
+ new_irq = irq - 16;
+ } else {
+ new_irq = irq - 64;
+ }
+
+ hose = saddle << 1;
+ if (new_irq >= 24) {
+ mask >>= 24;
+ hose += 1;
}
- else if (irq >= 8)
- outb(mask >> 8, 0xA1); /* ISA PIC2 */
- else
- outb(mask, 0x21); /* ISA PIC1 */
+
+ *(vuip)MCPCIA_INT_MASK0(hose) =
+ (~mask & 0x00ffffff) | hose_irq_masks[hose];
+ mb();
+ *(vuip)MCPCIA_INT_MASK0(hose);
}
static void
rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
{
- int irq, ack;
-
- ack = irq = (vector - 0x800) >> 4;
+ int irq;
- /* ??? A 4 bus RAWHIDE has 67 interrupts. Oops. We need
- something wider than one word for our own internal
- manipulations. */
+ irq = (vector - 0x800) >> 4;
/*
* The RAWHIDE SRM console reports PCI interrupts with a vector
@@ -73,37 +86,37 @@ rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
* it line up with the actual bit numbers from the REQ registers,
* which is how we manage the interrupts/mask. Sigh...
*
- * also, PCI #1 interrupts are offset some more... :-(
+ * Also, PCI #1 interrupts are offset some more... :-(
*/
- if (irq == 52)
- ack = irq = 56; /* SCSI on PCI 1 is special */
- else {
- if (irq >= 24) /* adjust all PCI interrupts down 8 */
- ack = irq = irq - 8;
- if (irq >= 48) /* adjust PCI bus 1 interrupts down another 8 */
- ack = irq = irq - 8;
+
+ if (irq == 52) {
+ /* SCSI on PCI1 is special. */
+ irq = 72;
}
- handle_irq(irq, ack, regs);
+ /* Adjust by which hose it is from. */
+ irq -= ((irq + 16) >> 2) & 0x38;
+
+ handle_irq(irq, irq, regs);
}
static void __init
rawhide_init_irq(void)
{
- STANDARD_INIT_IRQ_PROLOG;
+ struct pci_controler *hose;
- /* HACK ALERT! only PCI busses 0 and 1 are used currently,
- (MIDs 4 and 5 respectively) and routing is only to CPU #1*/
+ mcpcia_init_hoses();
- *(vuip)MCPCIA_INT_MASK0(4) =
- (~((alpha_irq_mask) >> 16) & 0x00ffffffU) | 0x00ff0000U; mb();
- /* ... and read it back to make sure it got written. */
- *(vuip)MCPCIA_INT_MASK0(4);
+ STANDARD_INIT_IRQ_PROLOG;
+
+ /* HACK ALERT! Routing is only to CPU #0. */
+ for (hose = hose_head; hose; hose = hose->next) {
+ int h = hose->index;
- *(vuip)MCPCIA_INT_MASK0(5) =
- (~((alpha_irq_mask) >> 40) & 0x00ffffffU) | 0x00fe0000U; mb();
- /* ... and read it back to make sure it got written. */
- *(vuip)MCPCIA_INT_MASK0(5);
+ *(vuip)MCPCIA_INT_MASK0(h) = hose_irq_masks[h];
+ mb();
+ *(vuip)MCPCIA_INT_MASK0(h);
+ }
enable_irq(2);
}
@@ -177,8 +190,8 @@ struct alpha_machine_vector rawhide_mv __initmv = {
min_io_address: DEFAULT_IO_BASE,
min_mem_address: MCPCIA_DEFAULT_MEM_BASE,
- nr_irqs: 64,
- irq_probe_mask: _PROBE_MASK(64),
+ nr_irqs: 128,
+ irq_probe_mask: _PROBE_MASK(128),
update_irq_hw: rawhide_update_irq_hw,
ack_irq: common_ack_irq,
device_interrupt: rawhide_srm_device_interrupt,
@@ -187,7 +200,7 @@ struct alpha_machine_vector rawhide_mv __initmv = {
init_irq: rawhide_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: rawhide_map_irq,
pci_swizzle: common_swizzle,
};
diff --git a/arch/alpha/kernel/sys_ruffian.c b/arch/alpha/kernel/sys_ruffian.c
index f303a8255..c03a91296 100644
--- a/arch/alpha/kernel/sys_ruffian.c
+++ b/arch/alpha/kernel/sys_ruffian.c
@@ -26,7 +26,7 @@
#include <asm/core_pyxis.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -212,15 +212,14 @@ ruffian_init_pit (void)
}
static void
-ruffian_kill_arch (int mode, char *reboot_cmd)
+ruffian_kill_arch (int mode)
{
#if 0
- /* this only causes re-entry to ARCSBIOS */
+ /* This only causes re-entry to ARCSBIOS */
/* Perhaps this works for other PYXIS as well? */
*(vuip) PYXIS_RESET = 0x0000dead;
mb();
#endif
- common_kill_arch(mode, reboot_cmd);
}
static int __init
diff --git a/arch/alpha/kernel/sys_rx164.c b/arch/alpha/kernel/sys_rx164.c
index c6a4ac5b3..969d3561f 100644
--- a/arch/alpha/kernel/sys_rx164.c
+++ b/arch/alpha/kernel/sys_rx164.c
@@ -26,7 +26,7 @@
#include <asm/core_polaris.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -229,7 +229,7 @@ struct alpha_machine_vector rx164_mv __initmv = {
init_irq: rx164_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: rx164_map_irq,
pci_swizzle: common_swizzle,
};
diff --git a/arch/alpha/kernel/sys_sable.c b/arch/alpha/kernel/sys_sable.c
index 86b1d8371..53afe259b 100644
--- a/arch/alpha/kernel/sys_sable.c
+++ b/arch/alpha/kernel/sys_sable.c
@@ -26,7 +26,7 @@
#include <asm/core_t2.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -248,7 +248,7 @@ struct alpha_machine_vector sable_mv __initmv = {
init_irq: sable_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: sable_map_irq,
pci_swizzle: common_swizzle,
@@ -283,7 +283,6 @@ struct alpha_machine_vector sable_gamma_mv __initmv = {
init_irq: sable_init_irq,
init_pit: common_init_pit,
init_pci: common_init_pci,
- kill_arch: common_kill_arch,
pci_map_irq: sable_map_irq,
pci_swizzle: common_swizzle,
diff --git a/arch/alpha/kernel/sys_sio.c b/arch/alpha/kernel/sys_sio.c
index a6575de9c..f26991f55 100644
--- a/arch/alpha/kernel/sys_sio.c
+++ b/arch/alpha/kernel/sys_sio.c
@@ -30,7 +30,7 @@
#include <asm/core_lca.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -55,7 +55,7 @@ sio_init_irq(void)
}
static inline void __init
-xl_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+xl_init_arch(void)
{
struct pci_controler *hose;
@@ -93,7 +93,7 @@ xl_init_arch(unsigned long *mem_start, unsigned long *mem_end)
* Create our single hose.
*/
- hose = alloc_pci_controler(mem_start);
+ hose = alloc_pci_controler();
hose->io_space = &ioport_resource;
hose->mem_space = &iomem_resource;
hose->config_space = LCA_CONF;
@@ -101,7 +101,7 @@ xl_init_arch(unsigned long *mem_start, unsigned long *mem_end)
}
static inline void __init
-alphabook1_init_arch(unsigned long *mem_start, unsigned long *mem_end)
+alphabook1_init_arch(void)
{
/* The AlphaBook1 has LCD video fixed at 800x600,
37 rows and 100 cols. */
@@ -109,7 +109,7 @@ alphabook1_init_arch(unsigned long *mem_start, unsigned long *mem_end)
screen_info.orig_video_cols = 100;
screen_info.orig_video_lines = 37;
- lca_init_arch(mem_start, mem_end);
+ lca_init_arch();
}
@@ -238,8 +238,8 @@ p2k_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
static inline void __init
noname_init_pci(void)
{
- sio_pci_route();
common_init_pci();
+ sio_pci_route();
sio_fixup_irq_levels(sio_collect_irq_levels());
ns87312_enable_ide(0x26e);
}
@@ -250,8 +250,8 @@ alphabook1_init_pci(void)
struct pci_dev *dev;
unsigned char orig, config;
- sio_pci_route();
common_init_pci();
+ sio_pci_route();
/*
* On the AlphaBook1, the PCMCIA chip (Cirrus 6729)
@@ -325,7 +325,7 @@ struct alpha_machine_vector alphabook1_mv __initmv = {
init_irq: sio_init_irq,
init_pit: common_init_pit,
init_pci: alphabook1_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: noname_map_irq,
pci_swizzle: common_swizzle,
@@ -359,7 +359,6 @@ struct alpha_machine_vector avanti_mv __initmv = {
init_irq: sio_init_irq,
init_pit: common_init_pit,
init_pci: noname_init_pci,
- kill_arch: common_kill_arch,
pci_map_irq: noname_map_irq,
pci_swizzle: common_swizzle,
@@ -392,7 +391,6 @@ struct alpha_machine_vector noname_mv __initmv = {
init_irq: sio_init_irq,
init_pit: common_init_pit,
init_pci: noname_init_pci,
- kill_arch: common_kill_arch,
pci_map_irq: noname_map_irq,
pci_swizzle: common_swizzle,
@@ -434,7 +432,6 @@ struct alpha_machine_vector p2k_mv __initmv = {
init_irq: sio_init_irq,
init_pit: common_init_pit,
init_pci: noname_init_pci,
- kill_arch: common_kill_arch,
pci_map_irq: p2k_map_irq,
pci_swizzle: common_swizzle,
@@ -467,7 +464,6 @@ struct alpha_machine_vector xl_mv __initmv = {
init_irq: sio_init_irq,
init_pit: common_init_pit,
init_pci: noname_init_pci,
- kill_arch: common_kill_arch,
pci_map_irq: noname_map_irq,
pci_swizzle: common_swizzle,
diff --git a/arch/alpha/kernel/sys_sx164.c b/arch/alpha/kernel/sys_sx164.c
index a8c7698fb..6ad08e442 100644
--- a/arch/alpha/kernel/sys_sx164.c
+++ b/arch/alpha/kernel/sys_sx164.c
@@ -26,7 +26,7 @@
#include <asm/core_pyxis.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -211,7 +211,7 @@ struct alpha_machine_vector sx164_mv __initmv = {
init_irq: sx164_init_irq,
init_pit: common_init_pit,
init_pci: sx164_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: sx164_map_irq,
pci_swizzle: common_swizzle,
};
diff --git a/arch/alpha/kernel/sys_takara.c b/arch/alpha/kernel/sys_takara.c
index c592ee65e..a17cd4de6 100644
--- a/arch/alpha/kernel/sys_takara.c
+++ b/arch/alpha/kernel/sys_takara.c
@@ -25,7 +25,7 @@
#include <asm/core_cia.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
#include "pci_impl.h"
#include "machvec_impl.h"
@@ -40,9 +40,13 @@ takara_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p)
outb(mask, 0x21); /* ISA PIC1 */
else
outb(mask >> 8, 0xA1); /* ISA PIC2 */
- } else if (irq <= 31) {
- regaddr = 0x510 + ((irq - 16) & 0x0c);
- outl((mask >> ((irq - 16) & 0x0c)) & 0xf0000Ul, regaddr);
+ } else {
+ if (irq > 63)
+ mask = _alpha_irq_masks[1] << 16;
+ else
+ mask = mask >> ((irq - 16) & 0x30);
+ regaddr = 0x510 + (((irq - 16) >> 2) & 0x0c);
+ outl(mask & 0xffff0000UL, regaddr);
}
}
@@ -87,10 +91,6 @@ static void
takara_srm_device_interrupt(unsigned long vector, struct pt_regs * regs)
{
int irq = (vector - 0x800) >> 4;
-
- if (irq > 15)
- irq = ((vector - 0x800) >> 6) + 12;
-
handle_irq(irq, irq, regs);
}
@@ -99,10 +99,9 @@ takara_init_irq(void)
{
STANDARD_INIT_IRQ_PROLOG;
- if (alpha_using_srm)
+ if (alpha_using_srm) {
alpha_mv.device_interrupt = takara_srm_device_interrupt;
-
- if (!alpha_using_srm) {
+ } else {
unsigned int ctlreg = inl(0x500);
/* Return to non-accelerated mode. */
@@ -127,6 +126,37 @@ takara_init_irq(void)
*/
static int __init
+takara_map_irq_srm(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ static char irq_tab[15][5] __initlocaldata = {
+ { 16+3, 16+3, 16+3, 16+3, 16+3}, /* slot 6 == device 3 */
+ { 16+2, 16+2, 16+2, 16+2, 16+2}, /* slot 7 == device 2 */
+ { 16+1, 16+1, 16+1, 16+1, 16+1}, /* slot 8 == device 1 */
+ { -1, -1, -1, -1, -1}, /* slot 9 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 10 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 11 == nothing */
+ /* These are behind the bridges. */
+ { 12, 12, 13, 14, 15}, /* slot 12 == nothing */
+ { 8, 8, 9, 19, 11}, /* slot 13 == nothing */
+ { 4, 4, 5, 6, 7}, /* slot 14 == nothing */
+ { 0, 0, 1, 2, 3}, /* slot 15 == nothing */
+ { -1, -1, -1, -1, -1}, /* slot 16 == nothing */
+ {64+ 0, 64+0, 64+1, 64+2, 64+3}, /* slot 17= device 4 */
+ {48+ 0, 48+0, 48+1, 48+2, 48+3}, /* slot 18= device 3 */
+ {32+ 0, 32+0, 32+1, 32+2, 32+3}, /* slot 19= device 2 */
+ {16+ 0, 16+0, 16+1, 16+2, 16+3}, /* slot 20= device 1 */
+ };
+ const long min_idsel = 6, max_idsel = 20, irqs_per_slot = 5;
+ int irq = COMMON_TABLE_LOOKUP;
+ if (irq >= 0 && irq < 16) {
+ /* Guess that we are behind a bridge. */
+ unsigned int busslot = PCI_SLOT(dev->bus->self->devfn);
+ irq += irq_tab[busslot-min_idsel][0];
+ }
+ return irq;
+}
+
+static int __init
takara_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
static char irq_tab[15][5] __initlocaldata = {
@@ -165,10 +195,13 @@ takara_swizzle(struct pci_dev *dev, u8 *pinp)
if (pin == 1)
pin += (20 - busslot);
else {
- /* Must be a card-based bridge. */
- printk(KERN_WARNING "takara_swizzle: cannot handle "
- "card-bridge behind builtin bridge yet.\n");
+ printk(KERN_WARNING "takara_swizzle: can only "
+ "handle cards with INTA IRQ pin.\n");
}
+ } else {
+ /* Must be a card-based bridge. */
+ printk(KERN_WARNING "takara_swizzle: cannot handle "
+ "card-bridge behind builtin bridge yet.\n");
}
*pinp = pin;
@@ -178,8 +211,11 @@ takara_swizzle(struct pci_dev *dev, u8 *pinp)
static void __init
takara_init_pci(void)
{
+ if (alpha_using_srm)
+ alpha_mv.pci_map_irq = takara_map_irq_srm;
+
common_init_pci();
- /* ns87312_enable_ide(0x26e); */
+ ns87312_enable_ide(0x26e);
}
@@ -198,8 +234,8 @@ struct alpha_machine_vector takara_mv __initmv = {
min_io_address: DEFAULT_IO_BASE,
min_mem_address: CIA_DEFAULT_MEM_BASE,
- nr_irqs: 20,
- irq_probe_mask: _PROBE_MASK(20),
+ nr_irqs: 128,
+ irq_probe_mask: _PROBE_MASK(48),
update_irq_hw: takara_update_irq_hw,
ack_irq: common_ack_irq,
device_interrupt: takara_device_interrupt,
@@ -208,7 +244,7 @@ struct alpha_machine_vector takara_mv __initmv = {
init_irq: takara_init_irq,
init_pit: common_init_pit,
init_pci: takara_init_pci,
- kill_arch: common_kill_arch,
+ kill_arch: NULL,
pci_map_irq: takara_map_irq,
pci_swizzle: takara_swizzle,
};
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index a86c79cc1..6e528e08f 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -40,7 +40,7 @@
#include <linux/timex.h>
#include "proto.h"
-#include "irq_impl.h"
+#include <asm/hw_irq.h>
extern rwlock_t xtime_lock;
extern volatile unsigned long lost_ticks; /* kernel/sched.c */
@@ -174,7 +174,7 @@ static inline unsigned long mktime(unsigned int year, unsigned int mon,
#ifdef CONFIG_RTC
void
-rtc_init_pit (void)
+rtc_init_pit(void)
{
unsigned char control;
@@ -193,6 +193,25 @@ rtc_init_pit (void)
outb(0x31, 0x42);
outb(0x13, 0x42);
}
+
+void
+rtc_kill_pit(void)
+{
+ unsigned char control;
+
+ cli();
+
+ /* Reset periodic interrupt frequency. */
+ CMOS_WRITE(0x26, RTC_FREQ_SELECT);
+
+ /* Turn on periodic interrupts. */
+ control = CMOS_READ(RTC_CONTROL);
+ control |= RTC_PIE;
+ CMOS_WRITE(control, RTC_CONTROL);
+ CMOS_READ(RTC_INTR_FLAGS);
+
+ sti();
+}
#endif
void
diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
index 59f021a77..36b0cc43a 100644
--- a/arch/alpha/kernel/traps.c
+++ b/arch/alpha/kernel/traps.c
@@ -113,7 +113,7 @@ die_if_kernel(char * str, struct pt_regs *regs, long err, unsigned long *r9_15)
}
#ifndef CONFIG_MATHEMU
-static long dummy_emul() { return 0; }
+static long dummy_emul(void) { return 0; }
long (*alpha_fp_emul_imprecise)(struct pt_regs *regs, unsigned long writemask)
= (void *)dummy_emul;
long (*alpha_fp_emul) (unsigned long pc)
diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile
index f550ba7cb..a224f84bb 100644
--- a/arch/alpha/lib/Makefile
+++ b/arch/alpha/lib/Makefile
@@ -7,7 +7,7 @@ OBJS = __divqu.o __remqu.o __divlu.o __remlu.o memset.o memcpy.o io.o \
strcat.o strcpy.o strncat.o strncpy.o stxcpy.o stxncpy.o \
strchr.o strrchr.o memchr.o \
copy_user.o clear_user.o strncpy_from_user.o strlen_user.o \
- csum_ipv6_magic.o strcasecmp.o semaphore.o \
+ csum_ipv6_magic.o strcasecmp.o semaphore.o fpreg.o \
srm_dispatch.o srm_fixup.o srm_puts.o srm_printk.o
lib.a: $(OBJS)
diff --git a/arch/alpha/kernel/fpreg.c b/arch/alpha/lib/fpreg.c
index 0bd8b9f67..c09d257bc 100644
--- a/arch/alpha/kernel/fpreg.c
+++ b/arch/alpha/lib/fpreg.c
@@ -1,5 +1,5 @@
/*
- * arch/alpha/kernel/fpreg.c
+ * arch/alpha/lib/fpreg.c
*
* (C) Copyright 1998 Linus Torvalds
*/
@@ -96,3 +96,96 @@ alpha_write_fp_reg (unsigned long reg, unsigned long val)
case 31: LDT(31, val); break;
}
}
+
+#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#define STS(reg,val) asm volatile ("ftois $f"#reg",%0" : "=r"(val));
+#else
+#define STS(reg,val) asm volatile ("sts $f"#reg",%0" : "=m"(val));
+#endif
+
+unsigned long
+alpha_read_fp_reg_s (unsigned long reg)
+{
+ unsigned long val;
+
+ switch (reg) {
+ case 0: STS( 0, val); break;
+ case 1: STS( 1, val); break;
+ case 2: STS( 2, val); break;
+ case 3: STS( 3, val); break;
+ case 4: STS( 4, val); break;
+ case 5: STS( 5, val); break;
+ case 6: STS( 6, val); break;
+ case 7: STS( 7, val); break;
+ case 8: STS( 8, val); break;
+ case 9: STS( 9, val); break;
+ case 10: STS(10, val); break;
+ case 11: STS(11, val); break;
+ case 12: STS(12, val); break;
+ case 13: STS(13, val); break;
+ case 14: STS(14, val); break;
+ case 15: STS(15, val); break;
+ case 16: STS(16, val); break;
+ case 17: STS(17, val); break;
+ case 18: STS(18, val); break;
+ case 19: STS(19, val); break;
+ case 20: STS(20, val); break;
+ case 21: STS(21, val); break;
+ case 22: STS(22, val); break;
+ case 23: STS(23, val); break;
+ case 24: STS(24, val); break;
+ case 25: STS(25, val); break;
+ case 26: STS(26, val); break;
+ case 27: STS(27, val); break;
+ case 28: STS(28, val); break;
+ case 29: STS(29, val); break;
+ case 30: STS(30, val); break;
+ case 31: STS(31, val); break;
+ }
+ return val;
+}
+
+#if defined(__alpha_cix__) || defined(__alpha_fix__)
+#define LDS(reg,val) asm volatile ("itofs %0,$f"#reg : : "r"(val));
+#else
+#define LDS(reg,val) asm volatile ("lds $f"#reg",%0" : : "m"(val));
+#endif
+
+void
+alpha_write_fp_reg_s (unsigned long reg, unsigned long val)
+{
+ switch (reg) {
+ case 0: LDS( 0, val); break;
+ case 1: LDS( 1, val); break;
+ case 2: LDS( 2, val); break;
+ case 3: LDS( 3, val); break;
+ case 4: LDS( 4, val); break;
+ case 5: LDS( 5, val); break;
+ case 6: LDS( 6, val); break;
+ case 7: LDS( 7, val); break;
+ case 8: LDS( 8, val); break;
+ case 9: LDS( 9, val); break;
+ case 10: LDS(10, val); break;
+ case 11: LDS(11, val); break;
+ case 12: LDS(12, val); break;
+ case 13: LDS(13, val); break;
+ case 14: LDS(14, val); break;
+ case 15: LDS(15, val); break;
+ case 16: LDS(16, val); break;
+ case 17: LDS(17, val); break;
+ case 18: LDS(18, val); break;
+ case 19: LDS(19, val); break;
+ case 20: LDS(20, val); break;
+ case 21: LDS(21, val); break;
+ case 22: LDS(22, val); break;
+ case 23: LDS(23, val); break;
+ case 24: LDS(24, val); break;
+ case 25: LDS(25, val); break;
+ case 26: LDS(26, val); break;
+ case 27: LDS(27, val); break;
+ case 28: LDS(28, val); break;
+ case 29: LDS(29, val); break;
+ case 30: LDS(30, val); break;
+ case 31: LDS(31, val); break;
+ }
+}
diff --git a/arch/alpha/lib/io.c b/arch/alpha/lib/io.c
index 25de0f871..de592ff08 100644
--- a/arch/alpha/lib/io.c
+++ b/arch/alpha/lib/io.c
@@ -2,8 +2,11 @@
* Alpha IO and memory functions.. Just expand the inlines in the header
* files..
*/
+
#include <linux/kernel.h>
#include <linux/types.h>
+#include <linux/string.h>
+
#include <asm/io.h>
unsigned int _inb(unsigned long addr)
@@ -562,3 +565,28 @@ void _memset_c_io(unsigned long to, unsigned long c, long count)
}
mb();
}
+
+void
+scr_memcpyw(u16 *d, const u16 *s, unsigned int count)
+{
+ if (! __is_ioaddr((unsigned long) s)) {
+ /* Source is memory. */
+ if (! __is_ioaddr((unsigned long) d))
+ memcpy(d, s, count);
+ else
+ memcpy_toio(d, s, count);
+ } else {
+ /* Source is screen. */
+ if (! __is_ioaddr((unsigned long) d))
+ memcpy_fromio(d, s, count);
+ else {
+ /* FIXME: Should handle unaligned ops and
+ operation widening. */
+ count /= 2;
+ while (count--) {
+ u16 tmp = __raw_readw((unsigned long)(s++));
+ __raw_writew(tmp, (unsigned long)(d++));
+ }
+ }
+ }
+}
diff --git a/arch/alpha/math-emu/Makefile b/arch/alpha/math-emu/Makefile
index 6ea85465f..b5fc37765 100644
--- a/arch/alpha/math-emu/Makefile
+++ b/arch/alpha/math-emu/Makefile
@@ -1,9 +1,15 @@
#
-# Makefile for math-emulator files...
+# Makefile for the FPU instruction emulation.
#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := math-emu.o
-O_OBJS := fp-emul.o ieee-math.o
+O_OBJS := math.o
+CFLAGS += -I. -I$(TOPDIR)/include/math-emu -w
ifeq ($(CONFIG_MATHEMU),m)
M_OBJS := $(O_TARGET)
diff --git a/arch/alpha/math-emu/fp-emul.c b/arch/alpha/math-emu/fp-emul.c
deleted file mode 100644
index c2ebbbb60..000000000
--- a/arch/alpha/math-emu/fp-emul.c
+++ /dev/null
@@ -1,354 +0,0 @@
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#include <asm/uaccess.h>
-
-#include "ieee-math.h"
-
-#define OPC_PAL 0x00
-
-#define OPC_INTA 0x10
-#define OPC_INTL 0x11
-#define OPC_INTS 0x12
-#define OPC_INTM 0x13
-#define OPC_FLTC 0x14
-#define OPC_FLTV 0x15
-#define OPC_FLTI 0x16
-#define OPC_FLTL 0x17
-
-#define OPC_MISC 0x18
-
-#define OPC_JSR 0x1a
-
-#define OP_FUN(OP,FUN) ((OP << 26) | (FUN << 5))
-
-/*
- * "Base" function codes for the FLTI-class instructions.
- * Note that in most cases these actually correspond to the "chopped"
- * form of the instruction. Not to worry---we extract the qualifier
- * bits separately and deal with them separately. Notice that base
- * function code 0x2c is used for both CVTTS and CVTST. The other bits
- * in the function code are used to distinguish the two.
- */
-#define FLTI_FUNC_ADDS OP_FUN(OPC_FLTI, 0x000)
-#define FLTI_FUNC_ADDT OP_FUN(OPC_FLTI, 0x020)
-#define FLTI_FUNC_CMPTEQ OP_FUN(OPC_FLTI, 0x025)
-#define FLTI_FUNC_CMPTLT OP_FUN(OPC_FLTI, 0x026)
-#define FLTI_FUNC_CMPTLE OP_FUN(OPC_FLTI, 0x027)
-#define FLTI_FUNC_CMPTUN OP_FUN(OPC_FLTI, 0x024)
-#define FLTI_FUNC_CVTTS_or_CVTST OP_FUN(OPC_FLTI, 0x02c)
-#define FLTI_FUNC_CVTTQ OP_FUN(OPC_FLTI, 0x02f)
-#define FLTI_FUNC_CVTQS OP_FUN(OPC_FLTI, 0x03c)
-#define FLTI_FUNC_CVTQT OP_FUN(OPC_FLTI, 0x03e)
-#define FLTI_FUNC_DIVS OP_FUN(OPC_FLTI, 0x003)
-#define FLTI_FUNC_DIVT OP_FUN(OPC_FLTI, 0x023)
-#define FLTI_FUNC_MULS OP_FUN(OPC_FLTI, 0x002)
-#define FLTI_FUNC_MULT OP_FUN(OPC_FLTI, 0x022)
-#define FLTI_FUNC_SUBS OP_FUN(OPC_FLTI, 0x001)
-#define FLTI_FUNC_SUBT OP_FUN(OPC_FLTI, 0x021)
-
-#define FLTC_FUNC_SQRTS OP_FUN(OPC_FLTC, 0x00B)
-#define FLTC_FUNC_SQRTT OP_FUN(OPC_FLTC, 0x02B)
-
-#define FLTL_FUNC_CVTQL OP_FUN(OPC_FLTL, 0x030)
-
-#define MISC_TRAPB 0x0000
-#define MISC_EXCB 0x0400
-
-extern unsigned long alpha_read_fp_reg (unsigned long reg);
-extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
-
-
-#ifdef MODULE
-
-MODULE_DESCRIPTION("FP Software completion module");
-
-extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long);
-extern long (*alpha_fp_emul) (unsigned long pc);
-
-static long (*save_emul_imprecise)(struct pt_regs *, unsigned long);
-static long (*save_emul) (unsigned long pc);
-
-long do_alpha_fp_emul_imprecise(struct pt_regs *, unsigned long);
-long do_alpha_fp_emul(unsigned long);
-
-int init_module(void)
-{
- save_emul_imprecise = alpha_fp_emul_imprecise;
- save_emul = alpha_fp_emul;
- alpha_fp_emul_imprecise = do_alpha_fp_emul_imprecise;
- alpha_fp_emul = do_alpha_fp_emul;
- return 0;
-}
-
-void cleanup_module(void)
-{
- alpha_fp_emul_imprecise = save_emul_imprecise;
- alpha_fp_emul = save_emul;
-}
-
-#undef alpha_fp_emul_imprecise
-#define alpha_fp_emul_imprecise do_alpha_fp_emul_imprecise
-#undef alpha_fp_emul
-#define alpha_fp_emul do_alpha_fp_emul
-
-#endif /* MODULE */
-
-/*
- * Emulate the floating point instruction at address PC. Returns 0 if
- * emulation fails. Notice that the kernel does not and cannot use FP
- * regs. This is good because it means that instead of
- * saving/restoring all fp regs, we simply stick the result of the
- * operation into the appropriate register.
- */
-long
-alpha_fp_emul (unsigned long pc)
-{
- unsigned long op_fun, fa, fb, fc, func, mode;
- unsigned long fpcw = current->thread.flags;
- unsigned long va, vb, vc, res, fpcr;
- __u32 insn;
-
- MOD_INC_USE_COUNT;
-
- get_user(insn, (__u32*)pc);
- fc = (insn >> 0) & 0x1f; /* destination register */
- fb = (insn >> 16) & 0x1f;
- fa = (insn >> 21) & 0x1f;
- func = (insn >> 5) & 0x7ff;
- mode = (insn >> 5) & 0xc0;
- op_fun = insn & OP_FUN(0x3f, 0x3f);
-
- va = alpha_read_fp_reg(fa);
- vb = alpha_read_fp_reg(fb);
- fpcr = rdfpcr();
-
- /*
- * Try the operation in software. First, obtain the rounding
- * mode...
- */
- if (mode == 0xc0) {
- /* dynamic---get rounding mode from fpcr: */
- mode = ((fpcr & FPCR_DYN_MASK) >> FPCR_DYN_SHIFT) << ROUND_SHIFT;
- }
- mode |= (fpcw & IEEE_TRAP_ENABLE_MASK);
-
- if ((IEEE_TRAP_ENABLE_MASK & 0xc0)) {
- extern int something_is_wrong (void);
- something_is_wrong();
- }
-
- switch (op_fun) {
- case FLTI_FUNC_CMPTEQ:
- res = ieee_CMPTEQ(va, vb, &vc);
- break;
-
- case FLTI_FUNC_CMPTLT:
- res = ieee_CMPTLT(va, vb, &vc);
- break;
-
- case FLTI_FUNC_CMPTLE:
- res = ieee_CMPTLE(va, vb, &vc);
- break;
-
- case FLTI_FUNC_CMPTUN:
- res = ieee_CMPTUN(va, vb, &vc);
- break;
-
- case FLTL_FUNC_CVTQL:
- /*
- * Notice: We can get here only due to an integer
- * overflow. Such overflows are reported as invalid
- * ops. We return the result the hw would have
- * computed.
- */
- vc = ((vb & 0xc0000000) << 32 | /* sign and msb */
- (vb & 0x3fffffff) << 29); /* rest of the integer */
- res = FPCR_INV;
- break;
-
- case FLTI_FUNC_CVTQS:
- res = ieee_CVTQS(mode, vb, &vc);
- break;
-
- case FLTI_FUNC_CVTQT:
- res = ieee_CVTQT(mode, vb, &vc);
- break;
-
- case FLTI_FUNC_CVTTS_or_CVTST:
- if (func == 0x6ac) {
- /*
- * 0x2ac is also CVTST, but if the /S
- * qualifier isn't set, we wouldn't be here in
- * the first place...
- */
- res = ieee_CVTST(mode, vb, &vc);
- } else {
- res = ieee_CVTTS(mode, vb, &vc);
- }
- break;
-
- case FLTI_FUNC_DIVS:
- res = ieee_DIVS(mode, va, vb, &vc);
- break;
-
- case FLTI_FUNC_DIVT:
- res = ieee_DIVT(mode, va, vb, &vc);
- break;
-
- case FLTI_FUNC_MULS:
- res = ieee_MULS(mode, va, vb, &vc);
- break;
-
- case FLTI_FUNC_MULT:
- res = ieee_MULT(mode, va, vb, &vc);
- break;
-
- case FLTI_FUNC_SUBS:
- res = ieee_SUBS(mode, va, vb, &vc);
- break;
-
- case FLTI_FUNC_SUBT:
- res = ieee_SUBT(mode, va, vb, &vc);
- break;
-
- case FLTI_FUNC_ADDS:
- res = ieee_ADDS(mode, va, vb, &vc);
- break;
-
- case FLTI_FUNC_ADDT:
- res = ieee_ADDT(mode, va, vb, &vc);
- break;
-
- case FLTI_FUNC_CVTTQ:
- res = ieee_CVTTQ(mode, vb, &vc);
- break;
-
- case FLTC_FUNC_SQRTS:
- res = ieee_SQRTS(mode, vb, &vc);
- break;
-
- case FLTC_FUNC_SQRTT:
- res = ieee_SQRTT(mode, vb, &vc);
- break;
-
- default:
- printk("alpha_fp_emul: unexpected function code %#lx at %#lx\n",
- func & 0x3f, pc);
- MOD_DEC_USE_COUNT;
- return 0;
- }
-
- /*
- * Take the appropriate action for each possible
- * floating-point result:
- *
- * - Set the appropriate bits in the FPCR
- * - If the specified exception is enabled in the FPCR,
- * return. The caller (entArith) will dispatch
- * the appropriate signal to the translated program.
- *
- * In addition, properly track the exception state in software
- * as described in the Alpha Architectre Handbook section 4.7.7.3.
- */
- if (res) {
- /* Record exceptions in software control word. */
- current->thread.flags = fpcw |= res >> 35;
-
- /* Update hardware control register */
- fpcr &= (~FPCR_MASK | FPCR_DYN_MASK);
- fpcr |= ieee_swcr_to_fpcr(fpcw);
- wrfpcr(fpcr);
-
- /* Do we generate a signal? */
- if (res >> 51 & fpcw & IEEE_TRAP_ENABLE_MASK) {
- MOD_DEC_USE_COUNT;
- return 0;
- }
- }
-
- /*
- * Whoo-kay... we got this far, and we're not generating a signal
- * to the translated program. All that remains is to write the
- * result:
- */
- alpha_write_fp_reg(fc, vc);
-
- MOD_DEC_USE_COUNT;
- return 1;
-}
-
-
-long
-alpha_fp_emul_imprecise (struct pt_regs *regs, unsigned long write_mask)
-{
- unsigned long trigger_pc = regs->pc - 4;
- unsigned long insn, opcode, rc;
-
- MOD_INC_USE_COUNT;
-
- /*
- * Turn off the bits corresponding to registers that are the
- * target of instructions that set bits in the exception
- * summary register. We have some slack doing this because a
- * register that is the target of a trapping instruction can
- * be written at most once in the trap shadow.
- *
- * Branches, jumps, TRAPBs, EXCBs and calls to PALcode all
- * bound the trap shadow, so we need not look any further than
- * up to the first occurrence of such an instruction.
- */
- while (write_mask) {
- get_user(insn, (__u32*)(trigger_pc));
- opcode = insn >> 26;
- rc = insn & 0x1f;
-
- switch (opcode) {
- case OPC_PAL:
- case OPC_JSR:
- case 0x30 ... 0x3f: /* branches */
- MOD_DEC_USE_COUNT;
- return 0;
-
- case OPC_MISC:
- switch (insn & 0xffff) {
- case MISC_TRAPB:
- case MISC_EXCB:
- MOD_DEC_USE_COUNT;
- return 0;
-
- default:
- break;
- }
- break;
-
- case OPC_INTA:
- case OPC_INTL:
- case OPC_INTS:
- case OPC_INTM:
- write_mask &= ~(1UL << rc);
- break;
-
- case OPC_FLTC:
- case OPC_FLTV:
- case OPC_FLTI:
- case OPC_FLTL:
- write_mask &= ~(1UL << (rc + 32));
- break;
- }
- if (!write_mask) {
- if (alpha_fp_emul(trigger_pc)) {
- /* re-execute insns in trap-shadow: */
- regs->pc = trigger_pc + 4;
- MOD_DEC_USE_COUNT;
- return 1;
- }
- break;
- }
- trigger_pc -= 4;
- }
- MOD_DEC_USE_COUNT;
- return 0;
-}
diff --git a/arch/alpha/math-emu/fp-emul.h b/arch/alpha/math-emu/fp-emul.h
deleted file mode 100644
index 12965fedc..000000000
--- a/arch/alpha/math-emu/fp-emul.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * These defines correspond to the dynamic rounding mode bits in the
- * Floating Point Control Register. They also happen to correspond to
- * the instruction encodings except that 0x03 signifies dynamic
- * rounding mode in that case.
- */
-#define ROUND_CHOP 0x00 /* chopped (aka round towards zero) */
-#define ROUND_NINF 0x01 /* round towards negative infinity */
-#define ROUND_NEAR 0x02 /* round towards nearest number */
-#define ROUND_PINF 0x03 /* round towards positive infinity */
diff --git a/arch/alpha/math-emu/ieee-math.c b/arch/alpha/math-emu/ieee-math.c
deleted file mode 100644
index 9a86b1048..000000000
--- a/arch/alpha/math-emu/ieee-math.c
+++ /dev/null
@@ -1,1382 +0,0 @@
-/*
- * ieee-math.c - IEEE floating point emulation code
- * Copyright (C) 1989,1990,1991,1995 by
- * Digital Equipment Corporation, Maynard, Massachusetts.
- *
- * Heavily modified for Linux/Alpha. Changes are Copyright (c) 1995
- * by David Mosberger (davidm@azstarnet.com).
- *
- * This file may be redistributed according to the terms of the
- * GNU General Public License.
- */
-/*
- * The original code did not have any comments. I have created many
- * comments as I fix the bugs in the code. My comments are based on
- * my observation and interpretation of the code. If the original
- * author would have spend a few minutes to comment the code, we would
- * never had a problem of misinterpretation. -HA
- *
- * This code could probably be a lot more optimized (especially the
- * division routine). However, my foremost concern was to get the
- * IEEE behavior right. Performance is less critical as these
- * functions are used on exceptional numbers only (well, assuming you
- * don't turn on the "trap on inexact"...).
- */
-#include <linux/sched.h>
-#include "ieee-math.h"
-
-#define STICKY_S 0x20000000 /* both in longword 0 of fraction */
-#define STICKY_T 1
-
-/*
- * Careful: order matters here!
- */
-enum {
- NaN, QNaN, INFTY, ZERO, DENORM, NORMAL
-};
-
-enum {
- SINGLE, DOUBLE
-};
-
-typedef unsigned long fpclass_t;
-
-#define IEEE_TMAX 0x7fefffffffffffff
-#define IEEE_SMAX 0x47efffffe0000000
-#define IEEE_SNaN 0xfff00000000f0000
-#define IEEE_QNaN 0xfff8000000000000
-#define IEEE_PINF 0x7ff0000000000000
-#define IEEE_NINF 0xfff0000000000000
-
-
-/*
- * The memory format of S floating point numbers differs from the
- * register format. In the following, the bitnumbers above the
- * diagram below give the memory format while the numbers below give
- * the register format.
- *
- * 31 30 23 22 0
- * +-----------------------------------------------+
- * S | s | exp | fraction |
- * +-----------------------------------------------+
- * 63 62 52 51 29
- *
- * For T floating point numbers, the register and memory formats
- * match:
- *
- * +-------------------------------------------------------------------+
- * T | s | exp | frac | tion |
- * +-------------------------------------------------------------------+
- * 63 62 52 51 32 31 0
- */
-typedef struct {
- unsigned long f[2]; /* bit 55 in f[0] is the factor of 2^0*/
- int s; /* 1 bit sign (0 for +, 1 for -) */
- int e; /* 16 bit signed exponent */
-} EXTENDED;
-
-
-/*
- * Return the sign of a Q integer, S or T fp number in the register
- * format.
- */
-static inline int
-sign (unsigned long a)
-{
- if ((long) a < 0)
- return -1;
- else
- return 1;
-}
-
-
-static inline long
-cmp128 (const long a[2], const long b[2])
-{
- if (a[1] < b[1]) return -1;
- if (a[1] > b[1]) return 1;
- return a[0] - b[0];
-}
-
-
-static inline void
-sll128 (unsigned long a[2])
-{
- a[1] = (a[1] << 1) | (a[0] >> 63);
- a[0] <<= 1;
-}
-
-
-static inline void
-srl128 (unsigned long a[2])
-{
- a[0] = (a[0] >> 1) | (a[1] << 63);
- a[1] >>= 1;
-}
-
-
-static inline void
-add128 (const unsigned long a[2], const unsigned long b[2], unsigned long c[2])
-{
- unsigned long carry = a[0] > (0xffffffffffffffff - b[0]);
-
- c[0] = a[0] + b[0];
- c[1] = a[1] + b[1] + carry;
-}
-
-
-static inline void
-sub128 (const unsigned long a[2], const unsigned long b[2], unsigned long c[2])
-{
- unsigned long borrow = a[0] < b[0];
-
- c[0] = a[0] - b[0];
- c[1] = a[1] - b[1] - borrow;
-}
-
-
-static inline void
-mul64 (const unsigned long a, const unsigned long b, unsigned long c[2])
-{
- c[0] = a * b;
- asm ("umulh %1,%2,%0" : "=r"(c[1]) : "r"(a), "r"(b));
-}
-
-
-static void
-div128 (unsigned long a[2], unsigned long b[2], unsigned long c[2])
-{
- unsigned long mask[2] = {1, 0};
-
- /*
- * Shift b until either the sign bit is set or until it is at
- * least as big as the dividend:
- */
- while (cmp128(b, a) < 0 && sign(b[1]) >= 0) {
- sll128(b);
- sll128(mask);
- }
- c[0] = c[1] = 0;
- do {
- if (cmp128(a, b) >= 0) {
- sub128(a, b, a);
- add128(mask, c, c);
- }
- srl128(mask);
- srl128(b);
- } while (mask[0] || mask[1]);
-}
-
-
-static void
-normalize (EXTENDED *a)
-{
- if (!a->f[0] && !a->f[1])
- return; /* zero fraction, unnormalizable... */
- /*
- * In "extended" format, the "1" in "1.f" is explicit; it is
- * in bit 55 of f[0], and the decimal point is understood to
- * be between bit 55 and bit 54. To normalize, shift the
- * fraction until we have a "1" in bit 55.
- */
- if ((a->f[0] & 0xff00000000000000) != 0 || a->f[1] != 0) {
- /*
- * Mantissa is greater than 1.0:
- */
- while ((a->f[0] & 0xff80000000000000) != 0x0080000000000000 ||
- a->f[1] != 0)
- {
- unsigned long sticky;
-
- ++a->e;
- sticky = a->f[0] & 1;
- srl128(a->f);
- a->f[0] |= sticky;
- }
- return;
- }
-
- if (!(a->f[0] & 0x0080000000000000)) {
- /*
- * Mantissa is less than 1.0:
- */
- while (!(a->f[0] & 0x0080000000000000)) {
- --a->e;
- a->f[0] <<= 1;
- }
- return;
- }
-}
-
-
-static inline fpclass_t
-ieee_fpclass (unsigned long a)
-{
- unsigned long exp, fract;
-
- exp = (a >> 52) & 0x7ff; /* 11 bits of exponent */
- fract = a & 0x000fffffffffffff; /* 52 bits of fraction */
- if (exp == 0) {
- if (fract == 0)
- return ZERO;
- return DENORM;
- }
- if (exp == 0x7ff) {
- if (fract == 0)
- return INFTY;
- if (((fract >> 51) & 1) != 0)
- return QNaN;
- return NaN;
- }
- return NORMAL;
-}
-
-
-/*
- * Translate S/T fp number in register format into extended format.
- */
-static fpclass_t
-extend_ieee (unsigned long a, EXTENDED *b, int prec)
-{
- fpclass_t result_kind;
-
- b->s = a >> 63;
- b->e = ((a >> 52) & 0x7ff) - 0x3ff; /* remove bias */
- b->f[1] = 0;
- /*
- * We shift f[1] left three bits so that the higher order bits
- * of the fraction will reside in bits 55 through 0 of f[0].
- */
- b->f[0] = (a & 0x000fffffffffffff) << 3;
- result_kind = ieee_fpclass(a);
- if (result_kind == NORMAL) {
- /* set implied 1. bit: */
- b->f[0] |= 1UL << 55;
- } else if (result_kind == DENORM) {
- if (prec == SINGLE)
- b->e = -126;
- else
- b->e = -1022;
- }
- return result_kind;
-}
-
-
-/*
- * INPUT PARAMETERS:
- * a a number in EXTENDED format to be converted to
- * s-floating format.
- * f rounding mode and exception enable bits.
- * OUTPUT PARAMETERS:
- * b will contain the s-floating number that "a" was
- * converted to (in register format).
- */
-static unsigned long
-make_s_ieee (long f, EXTENDED *a, unsigned long *b)
-{
- unsigned long res, sticky;
-
- if (!a->e && !a->f[0] && !a->f[1]) {
- *b = (unsigned long) a->s << 63; /* return +/-0 */
- return 0;
- }
-
- normalize(a);
- res = 0;
-
- if (a->e < -0x7e) {
- res = FPCR_INE;
- if (f & IEEE_TRAP_ENABLE_UNF) {
- res |= FPCR_UNF;
- a->e += 0xc0; /* scale up result by 2^alpha */
- } else {
- /* try making denormalized number: */
- while (a->e < -0x7e) {
- ++a->e;
- sticky = a->f[0] & 1;
- srl128(a->f);
- if (!a->f[0] && !a->f[0]) {
- /* underflow: replace with exact 0 */
- res |= FPCR_UNF;
- break;
- }
- a->f[0] |= sticky;
- }
- a->e = -0x3ff;
- }
- }
- if (a->e >= 0x80) {
- res = FPCR_OVF | FPCR_INE;
- if (f & IEEE_TRAP_ENABLE_OVF) {
- a->e -= 0xc0; /* scale down result by 2^alpha */
- } else {
- /*
- * Overflow without trap enabled, substitute
- * result according to rounding mode:
- */
- switch (RM(f)) {
- case ROUND_NEAR:
- *b = IEEE_PINF;
- break;
-
- case ROUND_CHOP:
- *b = IEEE_SMAX;
- break;
-
- case ROUND_NINF:
- if (a->s) {
- *b = IEEE_PINF;
- } else {
- *b = IEEE_SMAX;
- }
- break;
-
- case ROUND_PINF:
- if (a->s) {
- *b = IEEE_SMAX;
- } else {
- *b = IEEE_PINF;
- }
- break;
- }
- *b |= ((unsigned long) a->s << 63);
- return res;
- }
- }
-
- *b = (((unsigned long) a->s << 63) |
- (((unsigned long) a->e + 0x3ff) << 52) |
- ((a->f[0] >> 3) & 0x000fffffe0000000));
- return res;
-}
-
-
-static unsigned long
-make_t_ieee (long f, EXTENDED *a, unsigned long *b)
-{
- unsigned long res, sticky;
-
- if (!a->e && !a->f[0] && !a->f[1]) {
- *b = (unsigned long) a->s << 63; /* return +/-0 */
- return 0;
- }
-
- normalize(a);
- res = 0;
- if (a->e < -0x3fe) {
- res = FPCR_INE;
- if (f & IEEE_TRAP_ENABLE_UNF) {
- res |= FPCR_UNF;
- a->e += 0x600;
- } else {
- /* try making denormalized number: */
- while (a->e < -0x3fe) {
- ++a->e;
- sticky = a->f[0] & 1;
- srl128(a->f);
- if (!a->f[0] && !a->f[0]) {
- /* underflow: replace with exact 0 */
- res |= FPCR_UNF;
- break;
- }
- a->f[0] |= sticky;
- }
- a->e = -0x3ff;
- }
- }
- if (a->e >= 0x3ff) {
- res = FPCR_OVF | FPCR_INE;
- if (f & IEEE_TRAP_ENABLE_OVF) {
- a->e -= 0x600; /* scale down result by 2^alpha */
- } else {
- /*
- * Overflow without trap enabled, substitute
- * result according to rounding mode:
- */
- switch (RM(f)) {
- case ROUND_NEAR:
- *b = IEEE_PINF;
- break;
-
- case ROUND_CHOP:
- *b = IEEE_TMAX;
- break;
-
- case ROUND_NINF:
- if (a->s) {
- *b = IEEE_PINF;
- } else {
- *b = IEEE_TMAX;
- }
- break;
-
- case ROUND_PINF:
- if (a->s) {
- *b = IEEE_TMAX;
- } else {
- *b = IEEE_PINF;
- }
- break;
- }
- *b |= ((unsigned long) a->s << 63);
- return res;
- }
- }
- *b = (((unsigned long) a->s << 63) |
- (((unsigned long) a->e + 0x3ff) << 52) |
- ((a->f[0] >> 3) & 0x000fffffffffffff));
- return res;
-}
-
-
-/*
- * INPUT PARAMETERS:
- * a EXTENDED format number to be rounded.
- * rm integer with value ROUND_NEAR, ROUND_CHOP, etc.
- * indicates how "a" should be rounded to produce "b".
- * OUTPUT PARAMETERS:
- * b s-floating number produced by rounding "a".
- * RETURN VALUE:
- * if no errors occurred, will be zero. Else will contain flags
- * like FPCR_INE_OP, etc.
- */
-static unsigned long
-round_s_ieee (int f, EXTENDED *a, unsigned long *b)
-{
- unsigned long diff1, diff2, res = 0;
- EXTENDED z1, z2;
-
- if (!(a->f[0] & 0xffffffff)) {
- return make_s_ieee(f, a, b); /* no rounding error */
- }
-
- /*
- * z1 and z2 are the S-floating numbers with the next smaller/greater
- * magnitude than a, respectively.
- */
- z1.s = z2.s = a->s;
- z1.e = z2.e = a->e;
- z1.f[0] = z2.f[0] = a->f[0] & 0xffffffff00000000;
- z1.f[1] = z2.f[1] = 0;
- z2.f[0] += 0x100000000; /* next bigger S float number */
-
- switch (RM(f)) {
- case ROUND_NEAR:
- diff1 = a->f[0] - z1.f[0];
- diff2 = z2.f[0] - a->f[0];
- if (diff1 > diff2)
- res = make_s_ieee(f, &z2, b);
- else if (diff2 > diff1)
- res = make_s_ieee(f, &z1, b);
- else
- /* equal distance: round towards even */
- if (z1.f[0] & 0x100000000)
- res = make_s_ieee(f, &z2, b);
- else
- res = make_s_ieee(f, &z1, b);
- break;
-
- case ROUND_CHOP:
- res = make_s_ieee(f, &z1, b);
- break;
-
- case ROUND_PINF:
- if (a->s) {
- res = make_s_ieee(f, &z1, b);
- } else {
- res = make_s_ieee(f, &z2, b);
- }
- break;
-
- case ROUND_NINF:
- if (a->s) {
- res = make_s_ieee(f, &z2, b);
- } else {
- res = make_s_ieee(f, &z1, b);
- }
- break;
- }
- return FPCR_INE | res;
-}
-
-
-static unsigned long
-round_t_ieee (int f, EXTENDED *a, unsigned long *b)
-{
- unsigned long diff1, diff2, res;
- EXTENDED z1, z2;
-
- if (!(a->f[0] & 0x7)) {
- /* no rounding error */
- return make_t_ieee(f, a, b);
- }
-
- z1.s = z2.s = a->s;
- z1.e = z2.e = a->e;
- z1.f[0] = z2.f[0] = a->f[0] & ~0x7;
- z1.f[1] = z2.f[1] = 0;
- z2.f[0] += (1 << 3);
-
- res = 0;
- switch (RM(f)) {
- case ROUND_NEAR:
- diff1 = a->f[0] - z1.f[0];
- diff2 = z2.f[0] - a->f[0];
- if (diff1 > diff2)
- res = make_t_ieee(f, &z2, b);
- else if (diff2 > diff1)
- res = make_t_ieee(f, &z1, b);
- else
- /* equal distance: round towards even */
- if (z1.f[0] & (1 << 3))
- res = make_t_ieee(f, &z2, b);
- else
- res = make_t_ieee(f, &z1, b);
- break;
-
- case ROUND_CHOP:
- res = make_t_ieee(f, &z1, b);
- break;
-
- case ROUND_PINF:
- if (a->s) {
- res = make_t_ieee(f, &z1, b);
- } else {
- res = make_t_ieee(f, &z2, b);
- }
- break;
-
- case ROUND_NINF:
- if (a->s) {
- res = make_t_ieee(f, &z2, b);
- } else {
- res = make_t_ieee(f, &z1, b);
- }
- break;
- }
- return FPCR_INE | res;
-}
-
-
-static fpclass_t
-add_kernel_ieee (EXTENDED *op_a, EXTENDED *op_b, EXTENDED *op_c)
-{
- unsigned long mask, fa, fb, fc;
- int diff;
-
- diff = op_a->e - op_b->e;
- fa = op_a->f[0];
- fb = op_b->f[0];
- if (diff < 0) {
- diff = -diff;
- op_c->e = op_b->e;
- mask = (1UL << diff) - 1;
- fa >>= diff;
- if (op_a->f[0] & mask) {
- fa |= 1; /* set sticky bit */
- }
- } else {
- op_c->e = op_a->e;
- mask = (1UL << diff) - 1;
- fb >>= diff;
- if (op_b->f[0] & mask) {
- fb |= 1; /* set sticky bit */
- }
- }
- if (op_a->s)
- fa = -fa;
- if (op_b->s)
- fb = -fb;
- fc = fa + fb;
- op_c->f[1] = 0;
- op_c->s = fc >> 63;
- if (op_c->s) {
- fc = -fc;
- }
- op_c->f[0] = fc;
- normalize(op_c);
- return 0;
-}
-
-
-/*
- * converts s-floating "a" to t-floating "b".
- *
- * INPUT PARAMETERS:
- * a a s-floating number to be converted
- * f the rounding mode (ROUND_NEAR, etc. )
- * OUTPUT PARAMETERS:
- * b the t-floating number that "a" is converted to.
- * RETURN VALUE:
- * error flags - i.e., zero if no errors occurred,
- * FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTST (int f, unsigned long a, unsigned long *b)
-{
- EXTENDED temp;
- fpclass_t a_type;
-
- a_type = extend_ieee(a, &temp, SINGLE);
- if (a_type >= NaN && a_type <= INFTY) {
- *b = a;
- if (a_type == NaN) {
- *b |= (1UL << 51); /* turn SNaN into QNaN */
- return FPCR_INV;
- }
- return 0;
- }
- return round_t_ieee(f, &temp, b);
-}
-
-
-/*
- * converts t-floating "a" to s-floating "b".
- *
- * INPUT PARAMETERS:
- * a a t-floating number to be converted
- * f the rounding mode (ROUND_NEAR, etc. )
- * OUTPUT PARAMETERS:
- * b the s-floating number that "a" is converted to.
- * RETURN VALUE:
- * error flags - i.e., zero if no errors occurred,
- * FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTTS (int f, unsigned long a, unsigned long *b)
-{
- EXTENDED temp;
- fpclass_t a_type;
-
- a_type = extend_ieee(a, &temp, DOUBLE);
- if (a_type >= NaN && a_type <= INFTY) {
- *b = a;
- if (a_type == NaN) {
- *b |= (1UL << 51); /* turn SNaN into QNaN */
- return FPCR_INV;
- }
- return 0;
- }
- return round_s_ieee(f, &temp, b);
-}
-
-
-/*
- * converts q-format (64-bit integer) "a" to s-floating "b".
- *
- * INPUT PARAMETERS:
- * a an 64-bit integer to be converted.
- * f the rounding mode (ROUND_NEAR, etc. )
- * OUTPUT PARAMETERS:
- * b the s-floating number "a" is converted to.
- * RETURN VALUE:
- * error flags - i.e., zero if no errors occurred,
- * FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTQS (int f, unsigned long a, unsigned long *b)
-{
- EXTENDED op_b;
-
- op_b.s = 0;
- op_b.f[0] = a;
- op_b.f[1] = 0;
- if (sign(a) < 0) {
- op_b.s = 1;
- op_b.f[0] = -a;
- }
- op_b.e = 55;
- normalize(&op_b);
- return round_s_ieee(f, &op_b, b);
-}
-
-
-/*
- * converts 64-bit integer "a" to t-floating "b".
- *
- * INPUT PARAMETERS:
- * a a 64-bit integer to be converted.
- * f the rounding mode (ROUND_NEAR, etc.)
- * OUTPUT PARAMETERS:
- * b the t-floating number "a" is converted to.
- * RETURN VALUE:
- * error flags - i.e., zero if no errors occurred,
- * FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTQT (int f, long a, unsigned long *b)
-{
- EXTENDED op_b;
-
- if (a != 0) {
- op_b.s = (a < 0 ? 1 : 0);
- op_b.f[0] = (a < 0 ? -a : a);
- op_b.f[1] = 0;
- op_b.e = 55;
- normalize(&op_b);
- return round_t_ieee(f, &op_b, b);
- } else {
- *b = 0;
- return 0;
- }
-}
-
-
-/*
- * converts t-floating "a" to 64-bit integer (q-format) "b".
- *
- * INPUT PARAMETERS:
- * a a t-floating number to be converted.
- * f the rounding mode (ROUND_NEAR, etc. )
- * OUTPUT PARAMETERS:
- * b the 64-bit integer "a" is converted to.
- * RETURN VALUE:
- * error flags - i.e., zero if no errors occurred,
- * FPCR_INV if invalid operation occurred, etc.
- */
-unsigned long
-ieee_CVTTQ (int f, unsigned long a, unsigned long *pb)
-{
- unsigned int midway;
- unsigned long ov, uv, res, b;
- fpclass_t a_type;
- EXTENDED temp;
-
- a_type = extend_ieee(a, &temp, DOUBLE);
-
- b = 0x7fffffffffffffff;
- res = FPCR_INV;
- if (a_type == NaN || a_type == INFTY)
- goto out;
-
- res = 0;
- if (a_type == QNaN)
- goto out;
-
- if (temp.e > 0) {
- ov = 0;
- while (temp.e > 0) {
- --temp.e;
- ov |= temp.f[1] >> 63;
- sll128(temp.f);
- }
- if (ov || (temp.f[1] & 0xffc0000000000000))
- res |= FPCR_IOV | FPCR_INE;
- }
- else if (temp.e < 0) {
- while (temp.e < 0) {
- ++temp.e;
- uv = temp.f[0] & 1; /* save sticky bit */
- srl128(temp.f);
- temp.f[0] |= uv;
- }
- }
- b = (temp.f[1] << 9) | (temp.f[0] >> 55);
-
- /*
- * Notice: the fraction is only 52 bits long. Thus, rounding
- * cannot possibly result in an integer overflow.
- */
- switch (RM(f)) {
- case ROUND_NEAR:
- if (temp.f[0] & 0x0040000000000000) {
- midway = (temp.f[0] & 0x003fffffffffffff) == 0;
- if ((midway && (temp.f[0] & 0x0080000000000000)) ||
- !midway)
- ++b;
- }
- break;
-
- case ROUND_PINF:
- b += ((temp.f[0] & 0x007fffffffffffff) != 0 && !temp.s);
- break;
-
- case ROUND_NINF:
- b += ((temp.f[0] & 0x007fffffffffffff) != 0 && temp.s);
- break;
-
- case ROUND_CHOP:
- /* no action needed */
- break;
- }
- if ((temp.f[0] & 0x007fffffffffffff) != 0)
- res |= FPCR_INE;
-
- if (temp.s) {
- b = -b;
- }
-
-out:
- *pb = b;
- return res;
-}
-
-
-unsigned long
-ieee_CMPTEQ (unsigned long a, unsigned long b, unsigned long *c)
-{
- EXTENDED op_a, op_b;
- fpclass_t a_type, b_type;
-
- *c = 0;
- a_type = extend_ieee(a, &op_a, DOUBLE);
- b_type = extend_ieee(b, &op_b, DOUBLE);
- if (a_type == NaN || b_type == NaN)
- return FPCR_INV;
- if (a_type == QNaN || b_type == QNaN)
- return 0;
-
- if ((op_a.e == op_b.e && op_a.s == op_b.s &&
- op_a.f[0] == op_b.f[0] && op_a.f[1] == op_b.f[1]) ||
- (a_type == ZERO && b_type == ZERO))
- *c = 0x4000000000000000;
- return 0;
-}
-
-
-unsigned long
-ieee_CMPTLT (unsigned long a, unsigned long b, unsigned long *c)
-{
- fpclass_t a_type, b_type;
- EXTENDED op_a, op_b;
-
- *c = 0;
- a_type = extend_ieee(a, &op_a, DOUBLE);
- b_type = extend_ieee(b, &op_b, DOUBLE);
- if (a_type == NaN || b_type == NaN)
- return FPCR_INV;
- if (a_type == QNaN || b_type == QNaN)
- return 0;
-
- if ((op_a.s == 1 && op_b.s == 0 &&
- (a_type != ZERO || b_type != ZERO)) ||
- (op_a.s == 1 && op_b.s == 1 &&
- (op_a.e > op_b.e || (op_a.e == op_b.e &&
- cmp128(op_a.f, op_b.f) > 0))) ||
- (op_a.s == 0 && op_b.s == 0 &&
- (op_a.e < op_b.e || (op_a.e == op_b.e &&
- cmp128(op_a.f,op_b.f) < 0))))
- *c = 0x4000000000000000;
- return 0;
-}
-
-
-unsigned long
-ieee_CMPTLE (unsigned long a, unsigned long b, unsigned long *c)
-{
- fpclass_t a_type, b_type;
- EXTENDED op_a, op_b;
-
- *c = 0;
- a_type = extend_ieee(a, &op_a, DOUBLE);
- b_type = extend_ieee(b, &op_b, DOUBLE);
- if (a_type == NaN || b_type == NaN)
- return FPCR_INV;
- if (a_type == QNaN || b_type == QNaN)
- return 0;
-
- if ((a_type == ZERO && b_type == ZERO) ||
- (op_a.s == 1 && op_b.s == 0) ||
- (op_a.s == 1 && op_b.s == 1 &&
- (op_a.e > op_b.e || (op_a.e == op_b.e &&
- cmp128(op_a.f,op_b.f) >= 0))) ||
- (op_a.s == 0 && op_b.s == 0 &&
- (op_a.e < op_b.e || (op_a.e == op_b.e &&
- cmp128(op_a.f,op_b.f) <= 0))))
- *c = 0x4000000000000000;
- return 0;
-}
-
-
-unsigned long
-ieee_CMPTUN (unsigned long a, unsigned long b, unsigned long *c)
-{
- fpclass_t a_type, b_type;
- EXTENDED op_a, op_b;
-
- *c = 0x4000000000000000;
- a_type = extend_ieee(a, &op_a, DOUBLE);
- b_type = extend_ieee(b, &op_b, DOUBLE);
- if (a_type == NaN || b_type == NaN)
- return FPCR_INV;
- if (a_type == QNaN || b_type == QNaN)
- return 0;
- *c = 0;
- return 0;
-}
-
-
-/*
- * Add a + b = c, where a, b, and c are ieee s-floating numbers. "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_ADDS (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
- fpclass_t a_type, b_type;
- EXTENDED op_a, op_b, op_c;
-
- a_type = extend_ieee(a, &op_a, SINGLE);
- b_type = extend_ieee(b, &op_b, SINGLE);
- if ((a_type >= NaN && a_type <= INFTY) ||
- (b_type >= NaN && b_type <= INFTY))
- {
- /* propagate NaNs according to arch. ref. handbook: */
- if (b_type == QNaN)
- *c = b;
- else if (b_type == NaN)
- *c = b | (1UL << 51);
- else if (a_type == QNaN)
- *c = a;
- else if (a_type == NaN)
- *c = a | (1UL << 51);
-
- if (a_type == NaN || b_type == NaN)
- return FPCR_INV;
- if (a_type == QNaN || b_type == QNaN)
- return 0;
-
- if (a_type == INFTY && b_type == INFTY && sign(a) != sign(b)) {
- *c = IEEE_QNaN;
- return FPCR_INV;
- }
- if (a_type == INFTY)
- *c = a;
- else
- *c = b;
- return 0;
- }
-
- add_kernel_ieee(&op_a, &op_b, &op_c);
- /* special case for -0 + -0 ==> -0 */
- if (a_type == ZERO && b_type == ZERO)
- op_c.s = op_a.s && op_b.s;
- return round_s_ieee(f, &op_c, c);
-}
-
-
-/*
- * Add a + b = c, where a, b, and c are ieee t-floating numbers. "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_ADDT (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
- fpclass_t a_type, b_type;
- EXTENDED op_a, op_b, op_c;
-
- a_type = extend_ieee(a, &op_a, DOUBLE);
- b_type = extend_ieee(b, &op_b, DOUBLE);
- if ((a_type >= NaN && a_type <= INFTY) ||
- (b_type >= NaN && b_type <= INFTY))
- {
- /* propagate NaNs according to arch. ref. handbook: */
- if (b_type == QNaN)
- *c = b;
- else if (b_type == NaN)
- *c = b | (1UL << 51);
- else if (a_type == QNaN)
- *c = a;
- else if (a_type == NaN)
- *c = a | (1UL << 51);
-
- if (a_type == NaN || b_type == NaN)
- return FPCR_INV;
- if (a_type == QNaN || b_type == QNaN)
- return 0;
-
- if (a_type == INFTY && b_type == INFTY && sign(a) != sign(b)) {
- *c = IEEE_QNaN;
- return FPCR_INV;
- }
- if (a_type == INFTY)
- *c = a;
- else
- *c = b;
- return 0;
- }
- add_kernel_ieee(&op_a, &op_b, &op_c);
- /* special case for -0 + -0 ==> -0 */
- if (a_type == ZERO && b_type == ZERO)
- op_c.s = op_a.s && op_b.s;
-
- return round_t_ieee(f, &op_c, c);
-}
-
-
-/*
- * Subtract a - b = c, where a, b, and c are ieee s-floating numbers.
- * "f" contains the rounding mode etc.
- */
-unsigned long
-ieee_SUBS (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
- fpclass_t a_type, b_type;
- EXTENDED op_a, op_b, op_c;
-
- a_type = extend_ieee(a, &op_a, SINGLE);
- b_type = extend_ieee(b, &op_b, SINGLE);
- if ((a_type >= NaN && a_type <= INFTY) ||
- (b_type >= NaN && b_type <= INFTY))
- {
- /* propagate NaNs according to arch. ref. handbook: */
- if (b_type == QNaN)
- *c = b;
- else if (b_type == NaN)
- *c = b | (1UL << 51);
- else if (a_type == QNaN)
- *c = a;
- else if (a_type == NaN)
- *c = a | (1UL << 51);
-
- if (a_type == NaN || b_type == NaN)
- return FPCR_INV;
- if (a_type == QNaN || b_type == QNaN)
- return 0;
-
- if (a_type == INFTY && b_type == INFTY && sign(a) == sign(b)) {
- *c = IEEE_QNaN;
- return FPCR_INV;
- }
- if (a_type == INFTY)
- *c = a;
- else
- *c = b ^ (1UL << 63);
- return 0;
- }
- op_b.s = !op_b.s;
- add_kernel_ieee(&op_a, &op_b, &op_c);
- /* special case for -0 - +0 ==> -0 */
- if (a_type == ZERO && b_type == ZERO)
- op_c.s = op_a.s && op_b.s;
-
- return round_s_ieee(f, &op_c, c);
-}
-
-
-/*
- * Subtract a - b = c, where a, b, and c are ieee t-floating numbers.
- * "f" contains the rounding mode etc.
- */
-unsigned long
-ieee_SUBT (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
- fpclass_t a_type, b_type;
- EXTENDED op_a, op_b, op_c;
-
- a_type = extend_ieee(a, &op_a, DOUBLE);
- b_type = extend_ieee(b, &op_b, DOUBLE);
- if ((a_type >= NaN && a_type <= INFTY) ||
- (b_type >= NaN && b_type <= INFTY))
- {
- /* propagate NaNs according to arch. ref. handbook: */
- if (b_type == QNaN)
- *c = b;
- else if (b_type == NaN)
- *c = b | (1UL << 51);
- else if (a_type == QNaN)
- *c = a;
- else if (a_type == NaN)
- *c = a | (1UL << 51);
-
- if (a_type == NaN || b_type == NaN)
- return FPCR_INV;
- if (a_type == QNaN || b_type == QNaN)
- return 0;
-
- if (a_type == INFTY && b_type == INFTY && sign(a) == sign(b)) {
- *c = IEEE_QNaN;
- return FPCR_INV;
- }
- if (a_type == INFTY)
- *c = a;
- else
- *c = b ^ (1UL << 63);
- return 0;
- }
- op_b.s = !op_b.s;
- add_kernel_ieee(&op_a, &op_b, &op_c);
- /* special case for -0 - +0 ==> -0 */
- if (a_type == ZERO && b_type == ZERO)
- op_c.s = op_a.s && op_b.s;
-
- return round_t_ieee(f, &op_c, c);
-}
-
-
-/*
- * Multiply a x b = c, where a, b, and c are ieee s-floating numbers.
- * "f" contains the rounding mode.
- */
-unsigned long
-ieee_MULS (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
- fpclass_t a_type, b_type;
- EXTENDED op_a, op_b, op_c;
-
- a_type = extend_ieee(a, &op_a, SINGLE);
- b_type = extend_ieee(b, &op_b, SINGLE);
- if ((a_type >= NaN && a_type <= INFTY) ||
- (b_type >= NaN && b_type <= INFTY))
- {
- /* propagate NaNs according to arch. ref. handbook: */
- if (b_type == QNaN)
- *c = b;
- else if (b_type == NaN)
- *c = b | (1UL << 51);
- else if (a_type == QNaN)
- *c = a;
- else if (a_type == NaN)
- *c = a | (1UL << 51);
-
- if (a_type == NaN || b_type == NaN)
- return FPCR_INV;
- if (a_type == QNaN || b_type == QNaN)
- return 0;
-
- if ((a_type == INFTY && b_type == ZERO) ||
- (b_type == INFTY && a_type == ZERO))
- {
- *c = IEEE_QNaN; /* return canonical QNaN */
- return FPCR_INV;
- }
- if (a_type == INFTY)
- *c = a ^ ((b >> 63) << 63);
- else if (b_type == INFTY)
- *c = b ^ ((a >> 63) << 63);
- else
- /* either of a and b are +/-0 */
- *c = ((unsigned long) op_a.s ^ op_b.s) << 63;
- return 0;
- }
- op_c.s = op_a.s ^ op_b.s;
- op_c.e = op_a.e + op_b.e - 55;
- mul64(op_a.f[0], op_b.f[0], op_c.f);
-
- return round_s_ieee(f, &op_c, c);
-}
-
-
-/*
- * Multiply a x b = c, where a, b, and c are ieee t-floating numbers.
- * "f" contains the rounding mode.
- */
-unsigned long
-ieee_MULT (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
- fpclass_t a_type, b_type;
- EXTENDED op_a, op_b, op_c;
-
- *c = IEEE_QNaN;
- a_type = extend_ieee(a, &op_a, DOUBLE);
- b_type = extend_ieee(b, &op_b, DOUBLE);
- if ((a_type >= NaN && a_type <= ZERO) ||
- (b_type >= NaN && b_type <= ZERO))
- {
- /* propagate NaNs according to arch. ref. handbook: */
- if (b_type == QNaN)
- *c = b;
- else if (b_type == NaN)
- *c = b | (1UL << 51);
- else if (a_type == QNaN)
- *c = a;
- else if (a_type == NaN)
- *c = a | (1UL << 51);
-
- if (a_type == NaN || b_type == NaN)
- return FPCR_INV;
- if (a_type == QNaN || b_type == QNaN)
- return 0;
-
- if ((a_type == INFTY && b_type == ZERO) ||
- (b_type == INFTY && a_type == ZERO))
- {
- *c = IEEE_QNaN; /* return canonical QNaN */
- return FPCR_INV;
- }
- if (a_type == INFTY)
- *c = a ^ ((b >> 63) << 63);
- else if (b_type == INFTY)
- *c = b ^ ((a >> 63) << 63);
- else
- /* either of a and b are +/-0 */
- *c = ((unsigned long) op_a.s ^ op_b.s) << 63;
- return 0;
- }
- op_c.s = op_a.s ^ op_b.s;
- op_c.e = op_a.e + op_b.e - 55;
- mul64(op_a.f[0], op_b.f[0], op_c.f);
-
- return round_t_ieee(f, &op_c, c);
-}
-
-
-/*
- * Divide a / b = c, where a, b, and c are ieee s-floating numbers.
- * "f" contains the rounding mode etc.
- */
-unsigned long
-ieee_DIVS (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
- fpclass_t a_type, b_type;
- EXTENDED op_a, op_b, op_c;
-
- a_type = extend_ieee(a, &op_a, SINGLE);
- b_type = extend_ieee(b, &op_b, SINGLE);
- if ((a_type >= NaN && a_type <= ZERO) ||
- (b_type >= NaN && b_type <= ZERO))
- {
- unsigned long res;
-
- /* propagate NaNs according to arch. ref. handbook: */
- if (b_type == QNaN)
- *c = b;
- else if (b_type == NaN)
- *c = b | (1UL << 51);
- else if (a_type == QNaN)
- *c = a;
- else if (a_type == NaN)
- *c = a | (1UL << 51);
-
- if (a_type == NaN || b_type == NaN)
- return FPCR_INV;
- if (a_type == QNaN || b_type == QNaN)
- return 0;
-
- res = 0;
- *c = IEEE_PINF;
- if (a_type == INFTY) {
- if (b_type == INFTY) {
- *c = IEEE_QNaN;
- return FPCR_INV;
- }
- } else if (b_type == ZERO) {
- if (a_type == ZERO) {
- *c = IEEE_QNaN;
- return FPCR_INV;
- }
- res = FPCR_DZE;
- } else
- /* a_type == ZERO || b_type == INFTY */
- *c = 0;
- *c |= (unsigned long) (op_a.s ^ op_b.s) << 63;
- return res;
- }
- op_c.s = op_a.s ^ op_b.s;
- op_c.e = op_a.e - op_b.e;
-
- op_a.f[1] = op_a.f[0];
- op_a.f[0] = 0;
- div128(op_a.f, op_b.f, op_c.f);
- if (a_type != ZERO)
- /* force a sticky bit because DIVs never hit exact .5: */
- op_c.f[0] |= STICKY_S;
- normalize(&op_c);
- op_c.e -= 9; /* remove excess exp from original shift */
- return round_s_ieee(f, &op_c, c);
-}
-
-
-/*
- * Divide a/b = c, where a, b, and c are ieee t-floating numbers. "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_DIVT (int f, unsigned long a, unsigned long b, unsigned long *c)
-{
- fpclass_t a_type, b_type;
- EXTENDED op_a, op_b, op_c;
-
- *c = IEEE_QNaN;
- a_type = extend_ieee(a, &op_a, DOUBLE);
- b_type = extend_ieee(b, &op_b, DOUBLE);
- if ((a_type >= NaN && a_type <= ZERO) ||
- (b_type >= NaN && b_type <= ZERO))
- {
- unsigned long res;
-
- /* propagate NaNs according to arch. ref. handbook: */
- if (b_type == QNaN)
- *c = b;
- else if (b_type == NaN)
- *c = b | (1UL << 51);
- else if (a_type == QNaN)
- *c = a;
- else if (a_type == NaN)
- *c = a | (1UL << 51);
-
- if (a_type == NaN || b_type == NaN)
- return FPCR_INV;
- if (a_type == QNaN || b_type == QNaN)
- return 0;
-
- res = 0;
- *c = IEEE_PINF;
- if (a_type == INFTY) {
- if (b_type == INFTY) {
- *c = IEEE_QNaN;
- return FPCR_INV;
- }
- } else if (b_type == ZERO) {
- if (a_type == ZERO) {
- *c = IEEE_QNaN;
- return FPCR_INV;
- }
- res = FPCR_DZE;
- } else
- /* a_type == ZERO || b_type == INFTY */
- *c = 0;
- *c |= (unsigned long) (op_a.s ^ op_b.s) << 63;
- return res;
- }
- op_c.s = op_a.s ^ op_b.s;
- op_c.e = op_a.e - op_b.e;
-
- op_a.f[1] = op_a.f[0];
- op_a.f[0] = 0;
- div128(op_a.f, op_b.f, op_c.f);
- if (a_type != ZERO)
- /* force a sticky bit because DIVs never hit exact .5 */
- op_c.f[0] |= STICKY_T;
- normalize(&op_c);
- op_c.e -= 9; /* remove excess exp from original shift */
- return round_t_ieee(f, &op_c, c);
-}
-
-/*
- * Sqrt a = b, where a and b are ieee s-floating numbers. "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_SQRTS (int f, unsigned long a, unsigned long *b)
-{
- fpclass_t a_type;
- EXTENDED op_a, op_b;
-
- *b = IEEE_QNaN;
- a_type = extend_ieee(a, &op_a, SINGLE);
- if (op_a.s == 0) {
- /* FIXME -- handle positive denormals. */
- send_sig(SIGFPE, current, 1);
- }
- return FPCR_INV;
-}
-
-/*
- * Sqrt a = b, where a and b are ieee t-floating numbers. "f"
- * contains the rounding mode etc.
- */
-unsigned long
-ieee_SQRTT (int f, unsigned long a, unsigned long *b)
-{
- fpclass_t a_type;
- EXTENDED op_a, op_b;
-
- *b = IEEE_QNaN;
- a_type = extend_ieee(a, &op_a, DOUBLE);
- if (op_a.s == 0) {
- /* FIXME -- handle positive denormals. */
- send_sig(SIGFPE, current, 1);
- }
- return FPCR_INV;
-}
diff --git a/arch/alpha/math-emu/ieee-math.h b/arch/alpha/math-emu/ieee-math.h
deleted file mode 100644
index 076a6d1c8..000000000
--- a/arch/alpha/math-emu/ieee-math.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 1992,1995 by
- * Digital Equipment Corporation, Maynard, Massachusetts.
- * This file may be redistributed according to the terms of the
- * GNU General Public License.
- */
-#ifndef __ieee_math_h__
-#define __ieee_math_h__
-
-#include <asm/fpu.h>
-
-#define ROUND_SHIFT 6 /* make space for trap-enable bits */
-#define RM(f) (((f) >> ROUND_SHIFT) & 0x3)
-
-#define ROUND_CHOP (FPCR_DYN_CHOPPED >> FPCR_DYN_SHIFT)
-#define ROUND_NINF (FPCR_DYN_MINUS >> FPCR_DYN_SHIFT)
-#define ROUND_NEAR (FPCR_DYN_NORMAL >> FPCR_DYN_SHIFT)
-#define ROUND_PINF (FPCR_DYN_PLUS >> FPCR_DYN_SHIFT)
-
-extern unsigned long ieee_CVTST (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_CVTTS (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_CVTQS (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_CVTQT (int rm, long a, unsigned long *b);
-extern unsigned long ieee_CVTTQ (int rm, unsigned long a, unsigned long *b);
-
-extern unsigned long ieee_CMPTEQ (unsigned long a, unsigned long b,
- unsigned long *c);
-extern unsigned long ieee_CMPTLT (unsigned long a, unsigned long b,
- unsigned long *c);
-extern unsigned long ieee_CMPTLE (unsigned long a, unsigned long b,
- unsigned long *c);
-extern unsigned long ieee_CMPTUN (unsigned long a, unsigned long b,
- unsigned long *c);
-
-extern unsigned long ieee_ADDS (int rm, unsigned long a, unsigned long b,
- unsigned long *c);
-extern unsigned long ieee_ADDT (int rm, unsigned long a, unsigned long b,
- unsigned long *c);
-extern unsigned long ieee_SUBS (int rm, unsigned long a, unsigned long b,
- unsigned long *c);
-extern unsigned long ieee_SUBT (int rm, unsigned long a, unsigned long b,
- unsigned long *c);
-extern unsigned long ieee_MULS (int rm, unsigned long a, unsigned long b,
- unsigned long *c);
-extern unsigned long ieee_MULT (int rm, unsigned long a, unsigned long b,
- unsigned long *c);
-extern unsigned long ieee_DIVS (int rm, unsigned long a, unsigned long b,
- unsigned long *c);
-extern unsigned long ieee_DIVT (int rm, unsigned long a, unsigned long b,
- unsigned long *c);
-extern unsigned long ieee_SQRTS (int rm, unsigned long a, unsigned long *b);
-extern unsigned long ieee_SQRTT (int rm, unsigned long a, unsigned long *b);
-
-#endif /* __ieee_math_h__ */
diff --git a/arch/alpha/math-emu/math.c b/arch/alpha/math-emu/math.c
new file mode 100644
index 000000000..c0ece7bcb
--- /dev/null
+++ b/arch/alpha/math-emu/math.c
@@ -0,0 +1,447 @@
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#include <asm/uaccess.h>
+
+#include "sfp-util.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+#include <math-emu/double.h>
+
+#define OPC_PAL 0x00
+#define OPC_INTA 0x10
+#define OPC_INTL 0x11
+#define OPC_INTS 0x12
+#define OPC_INTM 0x13
+#define OPC_FLTC 0x14
+#define OPC_FLTV 0x15
+#define OPC_FLTI 0x16
+#define OPC_FLTL 0x17
+#define OPC_MISC 0x18
+#define OPC_JSR 0x1a
+
+#define FOP_SRC_S 0
+#define FOP_SRC_T 2
+#define FOP_SRC_Q 3
+
+#define FOP_FNC_ADDx 0
+#define FOP_FNC_CVTQL 0
+#define FOP_FNC_SUBx 1
+#define FOP_FNC_MULx 2
+#define FOP_FNC_DIVx 3
+#define FOP_FNC_CMPxUN 4
+#define FOP_FNC_CMPxEQ 5
+#define FOP_FNC_CMPxLT 6
+#define FOP_FNC_CMPxLE 7
+#define FOP_FNC_SQRTx 11
+#define FOP_FNC_CVTxS 12
+#define FOP_FNC_CVTxT 14
+#define FOP_FNC_CVTxQ 15
+
+#define MISC_TRAPB 0x0000
+#define MISC_EXCB 0x0400
+
+extern unsigned long alpha_read_fp_reg (unsigned long reg);
+extern void alpha_write_fp_reg (unsigned long reg, unsigned long val);
+extern unsigned long alpha_read_fp_reg_s (unsigned long reg);
+extern void alpha_write_fp_reg_s (unsigned long reg, unsigned long val);
+
+
+#ifdef MODULE
+
+MODULE_DESCRIPTION("FP Software completion module");
+
+extern long (*alpha_fp_emul_imprecise)(struct pt_regs *, unsigned long);
+extern long (*alpha_fp_emul) (unsigned long pc);
+
+static long (*save_emul_imprecise)(struct pt_regs *, unsigned long);
+static long (*save_emul) (unsigned long pc);
+
+long do_alpha_fp_emul_imprecise(struct pt_regs *, unsigned long);
+long do_alpha_fp_emul(unsigned long);
+
+int init_module(void)
+{
+ save_emul_imprecise = alpha_fp_emul_imprecise;
+ save_emul = alpha_fp_emul;
+ alpha_fp_emul_imprecise = do_alpha_fp_emul_imprecise;
+ alpha_fp_emul = do_alpha_fp_emul;
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ alpha_fp_emul_imprecise = save_emul_imprecise;
+ alpha_fp_emul = save_emul;
+}
+
+#undef alpha_fp_emul_imprecise
+#define alpha_fp_emul_imprecise do_alpha_fp_emul_imprecise
+#undef alpha_fp_emul
+#define alpha_fp_emul do_alpha_fp_emul
+
+#endif /* MODULE */
+
+/* For 128-bit division. */
+
+void
+udiv128(unsigned long divisor_f0, unsigned long divisor_f1,
+ unsigned long dividend_f0, unsigned long dividend_f1,
+ unsigned long *quot, unsigned long *remd)
+{
+ _FP_FRAC_DECL_2(quo);
+ _FP_FRAC_DECL_2(rem);
+ _FP_FRAC_DECL_2(tmp);
+ unsigned long i, num_bits, bit;
+
+ _FP_FRAC_SET_2(rem, _FP_ZEROFRAC_2);
+ _FP_FRAC_SET_2(quo, _FP_ZEROFRAC_2);
+
+ if (_FP_FRAC_ZEROP_2(divisor))
+ goto out;
+
+ if (_FP_FRAC_GT_2(divisor, dividend)) {
+ _FP_FRAC_COPY_2(rem, dividend);
+ goto out;
+ }
+
+ if (_FP_FRAC_EQ_2(divisor, dividend)) {
+ __FP_FRAC_SET_2(quo, 0, 1);
+ goto out;
+ }
+
+ num_bits = 128;
+ while (1) {
+ bit = _FP_FRAC_NEGP_2(dividend);
+ _FP_FRAC_COPY_2(tmp, rem);
+ _FP_FRAC_SLL_2(tmp, 1);
+ _FP_FRAC_LOW_2(tmp) |= bit;
+ if (! _FP_FRAC_GE_2(tmp, divisor))
+ break;
+ _FP_FRAC_COPY_2(rem, tmp);
+ _FP_FRAC_SLL_2(dividend, 1);
+ num_bits--;
+ }
+
+ for (i = 0; i < num_bits; i++) {
+ bit = _FP_FRAC_NEGP_2(dividend);
+ _FP_FRAC_SLL_2(rem, 1);
+ _FP_FRAC_LOW_2(rem) |= bit;
+ _FP_FRAC_SUB_2(tmp, rem, divisor);
+ bit = _FP_FRAC_NEGP_2(tmp);
+ _FP_FRAC_SLL_2(dividend, 1);
+ _FP_FRAC_SLL_2(quo, 1);
+ if (!bit) {
+ _FP_FRAC_LOW_2(quo) |= 1;
+ _FP_FRAC_COPY_2(rem, tmp);
+ }
+ }
+
+out:
+ *quot = quo_f1;
+ *remd = rem_f1;
+ return;
+}
+
+/*
+ * Emulate the floating point instruction at address PC. Returns 0 if
+ * emulation fails. Notice that the kernel does not and cannot use FP
+ * regs. This is good because it means that instead of
+ * saving/restoring all fp regs, we simply stick the result of the
+ * operation into the appropriate register.
+ */
+long
+alpha_fp_emul (unsigned long pc)
+{
+ FP_DECL_EX;
+ FP_DECL_S(SA); FP_DECL_S(SB); FP_DECL_S(SR);
+ FP_DECL_D(DA); FP_DECL_D(DB); FP_DECL_D(DR);
+
+ unsigned long fa, fb, fc, func, mode, src;
+ unsigned long fpcw = current->thread.flags;
+ unsigned long res, va, vb, vc, fpcr;
+ __u32 insn;
+
+ MOD_INC_USE_COUNT;
+
+ get_user(insn, (__u32*)pc);
+ fc = (insn >> 0) & 0x1f; /* destination register */
+ fb = (insn >> 16) & 0x1f;
+ fa = (insn >> 21) & 0x1f;
+ func = (insn >> 5) & 0xf;
+ src = (insn >> 9) & 0x3;
+ mode = (insn >> 11) & 0x3;
+
+ fpcr = rdfpcr();
+
+ if (mode == 3) {
+ /* Dynamic -- get rounding mode from fpcr. */
+ mode = (fpcr >> FPCR_DYN_SHIFT) & 3;
+ }
+
+ switch (src) {
+ case FOP_SRC_S:
+ va = alpha_read_fp_reg_s(fa);
+ vb = alpha_read_fp_reg_s(fb);
+
+ FP_UNPACK_SP(SA, &va);
+ FP_UNPACK_SP(SB, &vb);
+
+ switch (func) {
+ case FOP_FNC_SUBx:
+ FP_SUB_S(SR, SA, SB);
+ goto pack_s;
+
+ case FOP_FNC_ADDx:
+ FP_ADD_S(SR, SA, SB);
+ goto pack_s;
+
+ case FOP_FNC_MULx:
+ FP_MUL_S(SR, SA, SB);
+ goto pack_s;
+
+ case FOP_FNC_DIVx:
+ FP_DIV_S(SR, SA, SB);
+ goto pack_s;
+
+ case FOP_FNC_SQRTx:
+ FP_SQRT_S(SR, SB);
+ goto pack_s;
+ }
+ goto bad_insn;
+
+ case FOP_SRC_T:
+ va = alpha_read_fp_reg(fa);
+ vb = alpha_read_fp_reg(fb);
+
+ if ((func & ~3) == FOP_FNC_CMPxUN) {
+ FP_UNPACK_RAW_DP(DA, &va);
+ FP_UNPACK_RAW_DP(DB, &vb);
+ if (!DA_e && !_FP_FRAC_ZEROP_1(DA)) {
+ FP_SET_EXCEPTION(FP_EX_DENORM);
+ if (FP_DENORM_ZERO)
+ _FP_FRAC_SET_1(DA, _FP_ZEROFRAC_1);
+ }
+ if (!DB_e && !_FP_FRAC_ZEROP_1(DB)) {
+ FP_SET_EXCEPTION(FP_EX_DENORM);
+ if (FP_DENORM_ZERO)
+ _FP_FRAC_SET_1(DB, _FP_ZEROFRAC_1);
+ }
+ FP_CMP_D(res, DA, DB, 3);
+ vc = 0x4000000000000000;
+ /* CMPTEQ, CMPTUN don't trap on QNaN, while CMPTLT and CMPTLE do */
+ if (res == 3 && ((func & 3) >= 2 || FP_ISSIGNAN_D(DA) || FP_ISSIGNAN_D(DB)))
+ FP_SET_EXCEPTION(FP_EX_INVALID);
+ switch (func) {
+ case FOP_FNC_CMPxUN: if (res != 3) vc = 0; break;
+ case FOP_FNC_CMPxEQ: if (res) vc = 0; break;
+ case FOP_FNC_CMPxLT: if (res != -1) vc = 0; break;
+ case FOP_FNC_CMPxLE: if ((long)res > 0) vc = 0; break;
+ }
+ goto done_d;
+ }
+
+ FP_UNPACK_DP(DA, &va);
+ FP_UNPACK_DP(DB, &vb);
+
+ switch (func) {
+ case FOP_FNC_SUBx:
+ FP_SUB_D(DR, DA, DB);
+ goto pack_d;
+
+ case FOP_FNC_ADDx:
+ FP_ADD_D(DR, DA, DB);
+ goto pack_d;
+
+ case FOP_FNC_MULx:
+ FP_MUL_D(DR, DA, DB);
+ goto pack_d;
+
+ case FOP_FNC_DIVx:
+ FP_DIV_D(DR, DA, DB);
+ goto pack_d;
+
+ case FOP_FNC_SQRTx:
+ FP_SQRT_D(DR, DB);
+ goto pack_d;
+
+ case FOP_FNC_CVTxS:
+ /* It is irritating that DEC encoded CVTST with
+ SRC == T_floating. It is also interesting that
+ the bit used to tell the two apart is /U... */
+ if (insn & 0x2000) {
+ FP_CONV(S,D,1,1,SR,DB);
+ goto pack_s;
+ } else {
+ /* CVTST need do nothing else but copy the
+ bits and repack. */
+ DR_c = DB_c;
+ DR_s = DB_s;
+ DR_e = DB_e;
+ DR_f = DB_f;
+ goto pack_d;
+ }
+
+ case FOP_FNC_CVTxQ:
+ if (DB_c == FP_CLS_NAN && (_FP_FRAC_HIGH_RAW_D(DB) & _FP_QNANBIT_D))
+ vc = 0; /* AAHB Table B-2 sais QNaN should not trigger INV */
+ else
+ FP_TO_INT_ROUND_D(vc, DB, 64, 2);
+ goto done_d;
+ }
+ goto bad_insn;
+
+ case FOP_SRC_Q:
+ vb = alpha_read_fp_reg(fb);
+
+ switch (func) {
+ case FOP_FNC_CVTQL:
+ /* Notice: We can get here only due to an integer
+ overflow. Such overflows are reported as invalid
+ ops. We return the result the hw would have
+ computed. */
+ vc = ((vb & 0xc0000000) << 32 | /* sign and msb */
+ (vb & 0x3fffffff) << 29); /* rest of the int */
+ FP_SET_EXCEPTION (FP_EX_INVALID);
+ goto done_d;
+
+ case FOP_FNC_CVTxS:
+ FP_FROM_INT_S(SR, ((long)vb), 64, long);
+ goto pack_s;
+
+ case FOP_FNC_CVTxT:
+ FP_FROM_INT_D(DR, ((long)vb), 64, long);
+ goto pack_d;
+ }
+ goto bad_insn;
+ }
+ goto bad_insn;
+
+pack_s:
+ FP_PACK_SP(&vc, SR);
+ alpha_write_fp_reg_s(fc, vc);
+ goto done;
+
+pack_d:
+ FP_PACK_DP(&vc, DR);
+done_d:
+ alpha_write_fp_reg(fc, vc);
+ goto done;
+
+ /*
+ * Take the appropriate action for each possible
+ * floating-point result:
+ *
+ * - Set the appropriate bits in the FPCR
+ * - If the specified exception is enabled in the FPCR,
+ * return. The caller (entArith) will dispatch
+ * the appropriate signal to the translated program.
+ *
+ * In addition, properly track the exception state in software
+ * as described in the Alpha Architectre Handbook section 4.7.7.3.
+ */
+done:
+ if (_fex) {
+ /* Record exceptions in software control word. */
+ current->thread.flags
+ = fpcw |= (_fex << IEEE_STATUS_TO_EXCSUM_SHIFT);
+
+ /* Update hardware control register */
+ fpcr &= (~FPCR_MASK | FPCR_DYN_MASK);
+ fpcr |= ieee_swcr_to_fpcr(fpcw);
+ wrfpcr(fpcr);
+
+ /* Do we generate a signal? */
+ if (_fex & fpcw & IEEE_TRAP_ENABLE_MASK) {
+ MOD_DEC_USE_COUNT;
+ return 0;
+ }
+ }
+
+ /* We used to write the destination register here, but DEC FORTRAN
+ requires that the result *always* be written... so we do the write
+ immediately after the operations above. */
+
+ MOD_DEC_USE_COUNT;
+ return 1;
+
+bad_insn:
+ printk(KERN_ERR "alpha_fp_emul: Invalid FP insn %#x at %#lx\n",
+ insn, pc);
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+long
+alpha_fp_emul_imprecise (struct pt_regs *regs, unsigned long write_mask)
+{
+ unsigned long trigger_pc = regs->pc - 4;
+ unsigned long insn, opcode, rc;
+
+ MOD_INC_USE_COUNT;
+
+ /*
+ * Turn off the bits corresponding to registers that are the
+ * target of instructions that set bits in the exception
+ * summary register. We have some slack doing this because a
+ * register that is the target of a trapping instruction can
+ * be written at most once in the trap shadow.
+ *
+ * Branches, jumps, TRAPBs, EXCBs and calls to PALcode all
+ * bound the trap shadow, so we need not look any further than
+ * up to the first occurrence of such an instruction.
+ */
+ while (write_mask) {
+ get_user(insn, (__u32*)(trigger_pc));
+ opcode = insn >> 26;
+ rc = insn & 0x1f;
+
+ switch (opcode) {
+ case OPC_PAL:
+ case OPC_JSR:
+ case 0x30 ... 0x3f: /* branches */
+ MOD_DEC_USE_COUNT;
+ return 0;
+
+ case OPC_MISC:
+ switch (insn & 0xffff) {
+ case MISC_TRAPB:
+ case MISC_EXCB:
+ MOD_DEC_USE_COUNT;
+ return 0;
+
+ default:
+ break;
+ }
+ break;
+
+ case OPC_INTA:
+ case OPC_INTL:
+ case OPC_INTS:
+ case OPC_INTM:
+ write_mask &= ~(1UL << rc);
+ break;
+
+ case OPC_FLTC:
+ case OPC_FLTV:
+ case OPC_FLTI:
+ case OPC_FLTL:
+ write_mask &= ~(1UL << (rc + 32));
+ break;
+ }
+ if (!write_mask) {
+ if (alpha_fp_emul(trigger_pc)) {
+ /* re-execute insns in trap-shadow: */
+ regs->pc = trigger_pc + 4;
+ MOD_DEC_USE_COUNT;
+ return 1;
+ }
+ break;
+ }
+ trigger_pc -= 4;
+ }
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
diff --git a/arch/alpha/math-emu/sfp-util.h b/arch/alpha/math-emu/sfp-util.h
new file mode 100644
index 000000000..7a6a8cf45
--- /dev/null
+++ b/arch/alpha/math-emu/sfp-util.h
@@ -0,0 +1,40 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <asm/byteorder.h>
+#include <asm/fpu.h>
+
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+ ((sl) = (al) + (bl), (sh) = (ah) + (bh) + ((sl) < (al)))
+
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ ((sl) = (al) - (bl), (sh) = (ah) - (bh) - ((al) < (bl)))
+
+#define umul_ppmm(wh, wl, u, v) \
+ __asm__ ("mulq %2,%3,%1; umulh %2,%3,%0" \
+ : "=r" ((UDItype)(wh)), \
+ "=&r" ((UDItype)(wl)) \
+ : "r" ((UDItype)(u)), \
+ "r" ((UDItype)(v)))
+
+extern void udiv128(unsigned long, unsigned long,
+ unsigned long, unsigned long,
+ unsigned long *,
+ unsigned long *);
+
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { \
+ unsigned long xr, xi; \
+ udiv128((n0), (n1), 0, (d), &xr, &xi); \
+ (q) = xr; \
+ (r) = xi; \
+ } while (0)
+
+#define UDIV_NEEDS_NORMALIZATION 1
+
+#define abort() goto bad_insn
+
+#ifndef __LITTLE_ENDIAN
+#define __LITTLE_ENDIAN -1
+#endif
+#define __BYTE_ORDER __LITTLE_ENDIAN
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index dc15db08b..4da99bad2 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -11,7 +11,7 @@
#define __EXTERN_INLINE inline
#include <asm/mmu_context.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#undef __EXTERN_INLINE
#include <linux/signal.h>
diff --git a/arch/alpha/mm/init.c b/arch/alpha/mm/init.c
index 0ec65b409..8c40bc6a2 100644
--- a/arch/alpha/mm/init.c
+++ b/arch/alpha/mm/init.c
@@ -4,6 +4,8 @@
* Copyright (C) 1995 Linus Torvalds
*/
+/* 2.3.x zone allocator, 1999 Andrea Arcangeli <andrea@suse.de> */
+
#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
@@ -15,6 +17,8 @@
#include <linux/mman.h>
#include <linux/mm.h>
#include <linux/swap.h>
+#include <linux/init.h>
+#include <linux/bootmem.h> /* max_low_pfn */
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h>
#endif
@@ -22,10 +26,12 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/hwrpb.h>
#include <asm/dma.h>
+#include <asm/mmu_context.h>
-#define DEBUG_POISON 0
+static unsigned long totalram_pages;
extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void);
@@ -58,7 +64,7 @@ get_pmd_slow(pgd_t *pgd, unsigned long offset)
pmd = (pmd_t *) __get_free_page(GFP_KERNEL);
if (pgd_none(*pgd)) {
if (pmd) {
- clear_page((unsigned long)pmd);
+ clear_page((void *)pmd);
pgd_set(pgd, pmd);
return pmd + offset;
}
@@ -81,7 +87,7 @@ get_pte_slow(pmd_t *pmd, unsigned long offset)
pte = (pte_t *) __get_free_page(GFP_KERNEL);
if (pmd_none(*pmd)) {
if (pte) {
- clear_page((unsigned long)pte);
+ clear_page((void *)pte);
pmd_set(pmd, pte);
return pte + offset;
}
@@ -136,7 +142,7 @@ pte_t
__bad_page(void)
{
memset((void *) EMPTY_PGE, 0, PAGE_SIZE);
- return pte_mkdirty(mk_pte((unsigned long) EMPTY_PGE, PAGE_SHARED));
+ return pte_mkdirty(mk_pte(mem_map + MAP_NR(EMPTY_PGE), PAGE_SHARED));
}
void
@@ -172,8 +178,6 @@ show_mem(void)
#endif
}
-extern unsigned long free_area_init(unsigned long, unsigned long);
-
static inline unsigned long
load_PCB(struct thread_struct * pcb)
{
@@ -186,40 +190,39 @@ load_PCB(struct thread_struct * pcb)
* paging_init() sets up the page tables: in the alpha version this actually
* unmaps the bootup page table (as we're now in KSEG, so we don't need it).
*/
-unsigned long
-paging_init(unsigned long start_mem, unsigned long end_mem)
+void
+paging_init(void)
{
- int i;
unsigned long newptbr;
- struct memclust_struct * cluster;
- struct memdesc_struct * memdesc;
unsigned long original_pcb_ptr;
+ unsigned int zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned long dma_pfn, high_pfn;
+
+ dma_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ high_pfn = max_low_pfn;
+
+#define ORDER_MASK (~((1 << (MAX_ORDER-1))-1))
+#define ORDER_ALIGN(n) (((n) + ~ORDER_MASK) & ORDER_MASK)
+
+ dma_pfn = ORDER_ALIGN(dma_pfn);
+ high_pfn = ORDER_ALIGN(high_pfn);
+
+#undef ORDER_MASK
+#undef ORDER_ALIGN
- /* initialize mem_map[] */
- start_mem = free_area_init(start_mem, end_mem);
-
- /* find free clusters, update mem_map[] accordingly */
- memdesc = (struct memdesc_struct *)
- (hwrpb->mddt_offset + (unsigned long) hwrpb);
- cluster = memdesc->cluster;
- for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
- unsigned long pfn, nr;
-
- /* Bit 0 is console/PALcode reserved. Bit 1 is
- non-volatile memory -- we might want to mark
- this for later */
- if (cluster->usage & 3)
- continue;
- pfn = cluster->start_pfn;
- nr = cluster->numpages;
-
- while (nr--)
- clear_bit(PG_reserved, &mem_map[pfn++].flags);
+ if (dma_pfn > high_pfn)
+ zones_size[ZONE_DMA] = high_pfn;
+ else {
+ zones_size[ZONE_DMA] = dma_pfn;
+ zones_size[ZONE_NORMAL] = high_pfn - dma_pfn;
}
+ /* Initialize mem_map[]. */
+ free_area_init(zones_size);
+
/* Initialize the kernel's page tables. Linux puts the vptb in
the last slot of the L1 page table. */
- memset((void *) ZERO_PAGE(0), 0, PAGE_SIZE);
+ memset((void *)ZERO_PGE, 0, PAGE_SIZE);
memset(swapper_pg_dir, 0, PAGE_SIZE);
newptbr = ((unsigned long) swapper_pg_dir - PAGE_OFFSET) >> PAGE_SHIFT;
pgd_val(swapper_pg_dir[1023]) =
@@ -252,8 +255,6 @@ paging_init(unsigned long start_mem, unsigned long end_mem)
phys_to_virt(original_pcb_ptr);
}
original_pcb = *(struct thread_struct *) original_pcb_ptr;
-
- return start_mem;
}
#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM)
@@ -273,64 +274,42 @@ srm_paging_stop (void)
}
#endif
-#if DEBUG_POISON
-static void
-kill_page(unsigned long pg)
+static void __init printk_memory_info(void)
{
- unsigned long *p = (unsigned long *)pg;
- unsigned long i = PAGE_SIZE, v = 0xdeadbeefdeadbeef;
- do {
- p[0] = v;
- p[1] = v;
- p[2] = v;
- p[3] = v;
- p[4] = v;
- p[5] = v;
- p[6] = v;
- p[7] = v;
- i -= 64;
- p += 8;
- } while (i != 0);
+ unsigned long codesize, reservedpages, datasize, initsize, tmp;
+ extern int page_is_ram(unsigned long) __init;
+ extern char _text, _etext, _data, _edata;
+ extern char __init_begin, __init_end;
+
+ /* printk all informations */
+ reservedpages = 0;
+ for (tmp = 0; tmp < max_low_pfn; tmp++)
+ /*
+ * Only count reserved RAM pages
+ */
+ if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
+ reservedpages++;
+
+ codesize = (unsigned long) &_etext - (unsigned long) &_text;
+ datasize = (unsigned long) &_edata - (unsigned long) &_data;
+ initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
+ printk("Memory: %luk/%luk available (%luk kernel code, %luk reserved, %luk data, %luk init)\n",
+ (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+ max_mapnr << (PAGE_SHIFT-10),
+ codesize >> 10,
+ reservedpages << (PAGE_SHIFT-10),
+ datasize >> 10,
+ initsize >> 10);
}
-#else
-#define kill_page(pg)
-#endif
-void
-mem_init(unsigned long start_mem, unsigned long end_mem)
+void __init
+mem_init(void)
{
- unsigned long tmp;
-
- end_mem &= PAGE_MASK;
- max_mapnr = num_physpages = MAP_NR(end_mem);
- high_memory = (void *) end_mem;
- start_mem = PAGE_ALIGN(start_mem);
-
- /*
- * Mark the pages used by the kernel as reserved.
- */
- tmp = KERNEL_START;
- while (tmp < start_mem) {
- set_bit(PG_reserved, &mem_map[MAP_NR(tmp)].flags);
- tmp += PAGE_SIZE;
- }
+ max_mapnr = num_physpages = max_low_pfn;
+ totalram_pages += free_all_bootmem();
- for (tmp = PAGE_OFFSET ; tmp < end_mem ; tmp += PAGE_SIZE) {
- if (tmp >= MAX_DMA_ADDRESS)
- clear_bit(PG_DMA, &mem_map[MAP_NR(tmp)].flags);
- if (PageReserved(mem_map+MAP_NR(tmp)))
- continue;
- atomic_set(&mem_map[MAP_NR(tmp)].count, 1);
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start && tmp >= initrd_start && tmp < initrd_end)
- continue;
-#endif
- kill_page(tmp);
- free_page(tmp);
- }
- tmp = nr_free_pages << PAGE_SHIFT;
- printk("Memory: %luk available\n", tmp >> 10);
- return;
+ printk_memory_info();
}
void
@@ -341,34 +320,37 @@ free_initmem (void)
addr = (unsigned long)(&__init_begin);
for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) {
- mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved);
- atomic_set(&mem_map[MAP_NR(addr)].count, 1);
- kill_page(addr);
+ ClearPageReserved(mem_map + MAP_NR(addr));
+ set_page_count(mem_map+MAP_NR(addr), 1);
free_page(addr);
+ totalram_pages++;
}
printk ("Freeing unused kernel memory: %ldk freed\n",
(&__init_end - &__init_begin) >> 10);
}
+#ifdef CONFIG_BLK_DEV_INITRD
void
-si_meminfo(struct sysinfo *val)
+free_initrd_mem(unsigned long start, unsigned long end)
{
- int i;
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(mem_map + MAP_NR(start));
+ set_page_count(mem_map+MAP_NR(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
- i = max_mapnr;
- val->totalram = 0;
+void
+si_meminfo(struct sysinfo *val)
+{
+ val->totalram = totalram_pages;
val->sharedram = 0;
- val->freeram = nr_free_pages << PAGE_SHIFT;
- val->bufferram = atomic_read(&buffermem);
- while (i-- > 0) {
- if (PageReserved(mem_map+i))
- continue;
- val->totalram++;
- if (!atomic_read(&mem_map[i].count))
- continue;
- val->sharedram += atomic_read(&mem_map[i].count) - 1;
- }
- val->totalram <<= PAGE_SHIFT;
- val->sharedram <<= PAGE_SHIFT;
- return;
+ 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/Makefile b/arch/arm/Makefile
index f8c91aca3..2c81731b9 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -156,7 +156,7 @@ endif
ifeq ($(CONFIG_ARCH_ACORN),y)
SUBDIRS += drivers/acorn
DRIVERS += drivers/acorn/block/acorn-block.a
-DRIVERS += drivers/acorn/char/acorn-char.a
+DRIVERS += drivers/acorn/char/acorn-char.o
DRIVERS += drivers/acorn/net/acorn-net.a
DRIVERS += drivers/acorn/scsi/acorn-scsi.a
endif
@@ -241,5 +241,3 @@ victor_config:
empeg_config:
$(RM) arch/arm/defconfig
cp arch/arm/def-configs/empeg arch/arm/defconfig
-
-
diff --git a/arch/arm/boot/compressed/head-netwinder.S b/arch/arm/boot/compressed/head-netwinder.S
index 1dcdfcd14..489bb4d96 100644
--- a/arch/arm/boot/compressed/head-netwinder.S
+++ b/arch/arm/boot/compressed/head-netwinder.S
@@ -24,6 +24,7 @@
bcs 1b
movs r4, r5
mov r5, #0
+ mov r1, #5 @ only here to fix NeTTroms which dont set r1
movne pc, r0
mov r0, #0
diff --git a/arch/arm/config.in b/arch/arm/config.in
index 249759e1a..e1d54c4e7 100644
--- a/arch/arm/config.in
+++ b/arch/arm/config.in
@@ -110,6 +110,7 @@ fi
if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o \
"$CONFIG_HOST_FOOTBRIDGE" = "y" ]; then
define_bool CONFIG_PCI y
+ source drivers/pci/Config.h
fi
#
diff --git a/arch/arm/def-configs/brutus b/arch/arm/def-configs/brutus
index a700f7d17..aade81639 100644
--- a/arch/arm/def-configs/brutus
+++ b/arch/arm/def-configs/brutus
@@ -203,9 +203,6 @@ CONFIG_EXT2_FS=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
diff --git a/arch/arm/def-configs/footbridge b/arch/arm/def-configs/footbridge
index a3acd8954..fa410d522 100644
--- a/arch/arm/def-configs/footbridge
+++ b/arch/arm/def-configs/footbridge
@@ -100,16 +100,27 @@ CONFIG_IDEDISK_MULTI_MODE=y
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_RZ1000 is not set
CONFIG_BLK_DEV_IDEPCI=y
-CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_BLK_DEV_IDEDMA_PCI=y
+CONFIG_IDEDMA_PCI_AUTO=y
+# IDEDMA_NEW_DRIVE_LISTINGS is not set
+IDEDMA_PCI_EXPERIMENTAL=y
CONFIG_BLK_DEV_OFFBOARD=y
-CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_AEC6210 is not set
+# CONFIG_BLK_DEV_CMD646 is not set
+CONFIG_BLK_DEV_CY82C693=y
+# CONFIG_BLK_DEV_HPT34X is not set
+# CONFIG_BLK_DEV_HPT366 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_OPTI621 is not set
+CONFIG_BLK_DEV_PDC202XX=y
+# PDC202XX_FORCE_BURST_BIT is not set
+# PDC202XX_FORCE_MASTER_MODE is not set
# CONFIG_BLK_DEV_TRM290 is not set
-# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_BLK_DEV_CMD646 is not set
CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_IDEDMA_AUTO=y
# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_BLK_CPQ_DA is not set
#
# Additional Block Devices
diff --git a/arch/arm/defconfig b/arch/arm/defconfig
index ef7d1e315..2aba351c2 100644
--- a/arch/arm/defconfig
+++ b/arch/arm/defconfig
@@ -18,6 +18,7 @@ CONFIG_ARCH_EBSA285=y
CONFIG_ARCH_NETWINDER=y
# CONFIG_ARCH_ACORN is not set
CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
CONFIG_ISA_DMA=y
CONFIG_CPU_32=y
# CONFIG_CPU_26 is not set
@@ -91,7 +92,7 @@ CONFIG_IDEDMA_PCI_AUTO=y
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_NS87415 is not set
-# CONFIG_BLK_DEV_VIA82CXXX is not set
+# CONFIG_BLK_DEV_VIA82C586 is not set
# CONFIG_BLK_DEV_CMD646 is not set
CONFIG_BLK_DEV_SL82C105=y
# CONFIG_IDE_CHIPSETS is not set
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 43cc0574f..cdd7a9821 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -14,7 +14,7 @@
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/dma.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/proc-fns.h>
#include <asm/semaphore.h>
#include <asm/system.h>
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 28c12d3e8..041d4f4ed 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -47,6 +47,7 @@ void pcibios_report_device_errors(void)
* - (0x48) enable all memory requests from ISA to be channeled to PCI
* - (0x42) disable ping-pong (as per errata)
* - (0x40) enable PCI packet retry
+ * - (0x44) Route INTA to IRQ11
* - (0x83) don't use CPU park enable, park on last master, disable GAT bit
* - (0x80) default rotating priorities
* - (0x81) rotate bank 4
@@ -62,6 +63,7 @@ static void __init pci_fixup_83c553(struct pci_dev *dev)
pci_write_config_byte(dev, 0x48, 0xff);
pci_write_config_byte(dev, 0x42, 0x00);
pci_write_config_byte(dev, 0x40, 0x22);
+ pci_write_config_word(dev, 0x44, 0xb000);
pci_write_config_byte(dev, 0x83, 0x02);
pci_write_config_byte(dev, 0x80, 0xe0);
pci_write_config_byte(dev, 0x81, 0x01);
@@ -203,6 +205,15 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
}
}
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *ranges)
+{
+ ranges->io_start -= bus->resource[0]->start;
+ ranges->io_end -= bus->resource[0]->start;
+ ranges->mem_start -= bus->resource[1]->start;
+ ranges->mem_end -= bus->resource[1]->start;
+}
+
static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
{
return 0;
@@ -218,6 +229,14 @@ static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin)
static int __init ebsa285_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
{
+ if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
+ dev->device == PCI_DEVICE_ID_CONTAQ_82C693)
+ switch (PCI_FUNC(dev->devfn)) {
+ case 1: return 14;
+ case 2: return 15;
+ case 3: return 12;
+ }
+
return irqmap_ebsa285[(slot + pin) & 3];
}
@@ -261,6 +280,8 @@ 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):
+ case DEV(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C885):
+ case DEV(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_YELLOWFIN):
return IRQ_NETWINDER_ETHER100;
case DEV(PCI_VENDOR_ID_WINBOND2, 0x5a5a):
@@ -273,6 +294,7 @@ static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
return IRQ_ISA_HARDDISK1;
case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000):
+ case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010):
return IRQ_NETWINDER_VGA;
default:
@@ -339,3 +361,8 @@ char * __init pcibios_setup(char *str)
}
return str;
}
+
+void __init
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+}
diff --git a/arch/arm/kernel/bios32.h b/arch/arm/kernel/bios32.h
new file mode 100644
index 000000000..fb3117452
--- /dev/null
+++ b/arch/arm/kernel/bios32.h
@@ -0,0 +1,9 @@
+struct hw_pci {
+ void (*init)(void);
+ unsigned long io_start;
+ unsigned long mem_start;
+ u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
+ int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin);
+};
+
+void __init dc21285_init(void);
diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c
index 2622dec25..dc7cc054e 100644
--- a/arch/arm/kernel/dec21285.c
+++ b/arch/arm/kernel/dec21285.c
@@ -205,6 +205,7 @@ static struct irqaction dc21285_error_action = {
void __init dc21285_init(void)
{
+ static struct resource csrmem, csrio;
unsigned int mem_size;
unsigned long cntl;
@@ -217,6 +218,15 @@ void __init dc21285_init(void)
*CSR_PCIADDR_EXTN = 0;
#ifdef CONFIG_HOST_FOOTBRIDGE
+
+ csrio.flags = IORESOURCE_IO;
+ csrmem.flags = IORESOURCE_MEM;
+
+ allocate_resource(&ioport_resource, &csrio, 128,
+ 0xff00, 0xffff, 128, NULL, NULL);
+ allocate_resource(&iomem_resource, &csrmem, 128,
+ 0xf4000000, 0xf8000000, 128, NULL, NULL);
+
/*
* Map our SDRAM at a known address in PCI space, just in case
* the firmware had other ideas. Using a nonzero base is
@@ -224,8 +234,8 @@ void __init dc21285_init(void)
* in the range 0x000a0000 to 0x000c0000. (eg, S3 cards).
*/
*CSR_PCICACHELINESIZE = 0x00002008;
- *CSR_PCICSRBASE = 0;
- *CSR_PCICSRIOBASE = 0;
+ *CSR_PCICSRBASE = csrmem.start;
+ *CSR_PCICSRIOBASE = csrio.start;
*CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET);
*CSR_PCIROMBASE = 0;
*CSR_PCICMD = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index c777db993..c7d1da3e1 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -43,7 +43,7 @@
#include <asm/hardware.h>
#include <asm/io.h>
#include <asm/irq.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#ifdef CONFIG_ARCH_ARC
@@ -865,7 +865,7 @@ static int ecard_prints(char *buffer, ecard_t *ec)
return buffer - start;
}
-int get_ecard_dev_info(char *buf, char **start, off_t pos, int count, int wr)
+static int get_ecard_dev_info(char *buf, char **start, off_t pos, int count)
{
ecard_t *ec = cards;
off_t at = 0;
@@ -892,7 +892,7 @@ 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_bus_ecard_dir = proc_mkdir("ecard", proc_bus);
create_proc_info_entry("devices", 0, proc_bus_ecard_dir,
get_ecard_dev_info);
}
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 7e6d4fe51..6d4107ede 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -20,6 +20,10 @@
#include "../lib/constants.h"
+#ifndef MODE_SVC
+#define MODE_SVC 0x13
+#endif
+
.text
#define PF_TRACESYS 0x20
@@ -342,10 +346,8 @@ irq_prio_ebsa110:
.endm
.macro restore_user_regs
- mrs r1, cpsr @ disable IRQs
- orr r1, r1, #I_BIT
ldr r0, [sp, #S_PSR] @ Get calling cpsr
- msr cpsr, r1
+ msr cpsr_c, #I_BIT | MODE_SVC @ disable IRQs
msr spsr, r0 @ save in spsr_svc
ldmia sp, {r0 - lr}^ @ Get calling r0 - lr
mov r0, r0
@@ -360,16 +362,13 @@ irq_prio_ebsa110:
/* If we're optimising for StrongARM the resulting code won't
run on an ARM7 and we can save a couple of instructions.
--pb */
-#ifdef __ARM_ARCH_4__
- .macro arm700_bug_check, instr, temp
- .endm
-#else
.macro arm700_bug_check, instr, temp
+#ifndef __ARM_ARCH_4__
and \temp, \instr, #0x0f000000 @ check for SWI
teq \temp, #0x0f000000
bne .Larm700bug
- .endm
#endif
+ .endm
.macro enable_irqs, temp
mrs \temp, cpsr
@@ -389,6 +388,13 @@ irq_prio_ebsa110:
adr\cond \reg, \label
.endm
+ .macro alignment_trap, rbase, rtemp, sym
+#ifdef CONFIG_ALIGNMENT_TRAP
+ ldr \rtemp, [\rbase, #OFF_CR_ALIGNMENT(\sym)]
+ mcr p15, 0, \rtemp, c1, c0
+#endif
+ .endm
+
/*
* Invalid mode handlers
*/
@@ -473,11 +479,9 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE
add r5, sp, #S_SP
mov r1, lr
stmia r5, {r0 - r4} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro
-
mrs r9, cpsr @ Enable interrupts if they were
tst r3, #I_BIT
biceq r9, r9, #I_BIT @ previously
-
mov r0, r2
/*
* This routine must not corrupt r9
@@ -489,9 +493,10 @@ __dabt_svc: sub sp, sp, #S_FRAME_SIZE
#else
bl cpu_data_abort
#endif
- msr cpsr, r9
+ msr cpsr_c, r9
mov r3, sp
bl SYMBOL_NAME(do_DataAbort)
+ msr cpsr_c, #I_BIT | MODE_SVC
ldr r0, [sp, #S_PSR]
msr spsr, r0
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
@@ -512,7 +517,7 @@ __irq_svc: sub sp, sp, #S_FRAME_SIZE
@
adrsvc ne, lr, 1b
bne do_IRQ
- ldr r0, [sp, #S_PSR]
+ ldr r0, [sp, #S_PSR] @ irqs are already disabled
msr spsr, r0
ldmia sp, {r0 - pc}^ @ load r0 - pc, cpsr
@@ -533,7 +538,8 @@ __und_svc: sub sp, sp, #S_FRAME_SIZE
mov r1, sp @ struct pt_regs *regs
bl SYMBOL_NAME(do_undefinstr)
-1: ldr lr, [sp, #S_PSR] @ Get SVC cpsr
+1: msr cpsr_c, #I_BIT | MODE_SVC
+ ldr lr, [sp, #S_PSR] @ Get SVC cpsr
msr spsr, lr
ldmia sp, {r0 - pc}^ @ Restore SVC registers
@@ -554,10 +560,6 @@ __und_svc: sub sp, sp, #S_FRAME_SIZE
/*
* User mode handlers
*/
-#ifdef DEBUG_UNDEF
-t: .ascii "Prefetch -> undefined instruction\n\0"
- .align
-#endif
.align 5
__dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
stmia sp, {r0 - r12} @ save r0 - r12
@@ -566,12 +568,7 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
ldmia r4, {r0 - r2} @ Get USR pc, cpsr
stmia r3, {r0 - r2} @ Save USR pc, cpsr, old_r0
stmdb r3, {sp, lr}^
-
-#ifdef CONFIG_ALIGNMENT_TRAP
- ldr r7, [r4, #OFF_CR_ALIGNMENT(__temp_abt)]
- mcr p15, 0, r7, c1, c0
-#endif
-
+ alignment_trap r4, r7, __temp_abt
mov fp, #0
#ifdef MULTI_CPU
ldr r2, .LCprocfns
@@ -580,10 +577,7 @@ __dabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
#else
bl cpu_data_abort
#endif
- mrs r3, cpsr @ Enable interrupts if they were
- bic r3, r3, #I_BIT @ previously
- msr cpsr, r3
-
+ msr cpsr_c, #MODE_SVC @ Enable interrupts
mov r3, sp
adrsvc al, lr, ret_from_sys_call
b SYMBOL_NAME(do_DataAbort)
@@ -596,12 +590,7 @@ __irq_usr: sub sp, sp, #S_FRAME_SIZE
ldmia r4, {r5 - r7} @ get saved PC, SPSR
stmia r8, {r5 - r7} @ save pc, psr, old_r0
stmdb r8, {sp, lr}^
-
-#ifdef CONFIG_ALIGNMENT_TRAP
- ldr r7, [r4, #OFF_CR_ALIGNMENT(__temp_irq)]
- mcr p15, 0, r7, c1, c0
-#endif
-
+ alignment_trap r4, r7, __temp_irq
mov fp, #0
1: get_irqnr_and_base r0, r6, r5
movne r1, sp
@@ -621,12 +610,7 @@ __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
ldmia r4, {r5 - r7}
stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0
stmdb r8, {sp, lr}^ @ Save user r0 - r12
-
-#ifdef CONFIG_ALIGNMENT_TRAP
- ldr r7, [r4, #OFF_CR_ALIGNMENT(__temp_und)]
- mcr p15, 0, r7, c1, c0
-#endif
-
+ alignment_trap r4, r7, __temp_und
mov fp, #0
adrsvc al, r9, ret_from_sys_call @ r9 = normal FP return
adrsvc al, lr, fpundefinstr @ lr = undefined instr return
@@ -640,9 +624,7 @@ call_fpe: get_current_task r10
fpundefinstr: mov r0, lr
mov r1, sp
- mrs r4, cpsr @ Enable interrupts
- bic r4, r4, #I_BIT
- msr cpsr, r4
+ msr cpsr_c, #MODE_SVC @ Enable interrupts
adrsvc al, lr, ret_from_sys_call
b SYMBOL_NAME(do_undefinstr)
@@ -654,16 +636,9 @@ __pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
ldmia r4, {r5 - r7} @ Get USR pc, cpsr
stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0
stmdb r8, {sp, lr}^ @ Save sp_usr lr_usr
-
-#ifdef CONFIG_ALIGNMENT_TRAP
- ldr r7, [r4, #OFF_CR_ALIGNMENT(__temp_abt)]
- mcr p15, 0, r7, c1, c0
-#endif
-
+ alignment_trap r4, r7, __temp_abt
mov fp, #0
- mrs r7, cpsr @ Enable interrupts if they were
- bic r7, r7, #I_BIT @ previously
- msr cpsr, r7
+ msr cpsr_c, #MODE_SVC @ Enable interrupts
mov r0, r5 @ address (pc)
mov r1, sp @ regs
bl SYMBOL_NAME(do_PrefetchAbort) @ call abort handler
@@ -681,6 +656,11 @@ __pabt_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go
msr spsr, lr
ldmia sp, {r0 - pc}^ @ Restore USR registers
+#ifdef DEBUG_UNDEF
+t: .ascii "Prefetch -> undefined instruction\n\0"
+ .align
+#endif
+
#include "entry-common.S"
.text
@@ -738,14 +718,31 @@ vector_IRQ: @
@
@ now branch to the relevent MODE handling routine
@
- bic r13, lr, #63
- orr r13, r13, #0x93
- msr spsr, r13 @ switch to SVC_32 mode
+ msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode
and lr, lr, #15
- adr r13, .LCtab_irq
- ldr lr, [r13, lr, lsl #2]
+ ldr lr, [pc, lr, lsl #2]
movs pc, lr @ Changes mode and branches
+
+.LCtab_irq: .word __irq_usr @ 0 (USR_26 / USR_32)
+ .word __irq_invalid @ 1 (FIQ_26 / FIQ_32)
+ .word __irq_invalid @ 2 (IRQ_26 / IRQ_32)
+ .word __irq_svc @ 3 (SVC_26 / SVC_32)
+ .word __irq_invalid @ 4
+ .word __irq_invalid @ 5
+ .word __irq_invalid @ 6
+ .word __irq_invalid @ 7
+ .word __irq_invalid @ 8
+ .word __irq_invalid @ 9
+ .word __irq_invalid @ a
+ .word __irq_invalid @ b
+ .word __irq_invalid @ c
+ .word __irq_invalid @ d
+ .word __irq_invalid @ e
+ .word __irq_invalid @ f
+
+ .align 5
+
/*
* Data abort dispatcher - dispatches it to the correct handler for the processor mode
* Enter in ABT mode, spsr = USR CPSR, lr = USR PC
@@ -761,15 +758,31 @@ vector_data: @
@
@ now branch to the relevent MODE handling routine
@
- bic r13, lr, #63
- orr r13, r13, #0x93
- msr spsr, r13 @ switch to SVC_32 mode
+ msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode
and lr, lr, #15
- adr r13, .LCtab_dabt
- ldr lr, [r13, lr, lsl #2]
+ ldr lr, [pc, lr, lsl #2]
movs pc, lr @ Changes mode and branches
+.LCtab_dabt: .word __dabt_usr @ 0 (USR_26 / USR_32)
+ .word __dabt_invalid @ 1 (FIQ_26 / FIQ_32)
+ .word __dabt_invalid @ 2 (IRQ_26 / IRQ_32)
+ .word __dabt_svc @ 3 (SVC_26 / SVC_32)
+ .word __dabt_invalid @ 4
+ .word __dabt_invalid @ 5
+ .word __dabt_invalid @ 6
+ .word __dabt_invalid @ 7
+ .word __dabt_invalid @ 8
+ .word __dabt_invalid @ 9
+ .word __dabt_invalid @ a
+ .word __dabt_invalid @ b
+ .word __dabt_invalid @ c
+ .word __dabt_invalid @ d
+ .word __dabt_invalid @ e
+ .word __dabt_invalid @ f
+
+ .align 5
+
/*
* Prefetch abort dispatcher - dispatches it to the correct handler for the processor mode
* Enter in ABT mode, spsr = USR CPSR, lr = USR PC
@@ -786,15 +799,18 @@ vector_prefetch:
@
@ now branch to the relevent MODE handling routine
@
- bic r13, lr, #63
- orr r13, r13, #0x93
- msr spsr, r13 @ switch to SVC_32 mode
+ msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode
ands lr, lr, #15
ldreq lr, .LCtab_pabt
ldrne lr, .LCtab_pabt + 4
movs pc, lr
+.LCtab_pabt: .word __pabt_usr
+ .word __pabt_invalid
+
+ .align 5
+
/*
* Undef instr entry dispatcher - dispatches it to the correct handler for the processor mode
* Enter in UND mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
@@ -810,15 +826,31 @@ vector_undefinstr:
@
@ now branch to the relevent MODE handling routine
@
- bic r13, lr, #63
- orr r13, r13, #0x93
- msr spsr, r13 @ switch to SVC_32 mode
+ msr spsr_c, #I_BIT | MODE_SVC @ switch to SVC_32 mode
and lr, lr, #15
- adr r13, .LCtab_und
- ldr lr, [r13, lr, lsl #2]
+ ldr lr, [pc, lr, lsl #2]
movs pc, lr @ Changes mode and branches
+.LCtab_und: .word __und_usr @ 0 (USR_26 / USR_32)
+ .word __und_invalid @ 1 (FIQ_26 / FIQ_32)
+ .word __und_invalid @ 2 (IRQ_26 / IRQ_32)
+ .word __und_svc @ 3 (SVC_26 / SVC_32)
+ .word __und_invalid @ 4
+ .word __und_invalid @ 5
+ .word __und_invalid @ 6
+ .word __und_invalid @ 7
+ .word __und_invalid @ 8
+ .word __und_invalid @ 9
+ .word __und_invalid @ a
+ .word __und_invalid @ b
+ .word __und_invalid @ c
+ .word __und_invalid @ d
+ .word __und_invalid @ e
+ .word __und_invalid @ f
+
+ .align 5
+
/*=============================================================================
* Undefined FIQs
*-----------------------------------------------------------------------------
@@ -848,60 +880,6 @@ vector_addrexcptn:
*/
.align 5
-.LCtab_irq: .word __irq_usr @ 0 (USR_26 / USR_32)
- .word __irq_invalid @ 1 (FIQ_26 / FIQ_32)
- .word __irq_invalid @ 2 (IRQ_26 / IRQ_32)
- .word __irq_svc @ 3 (SVC_26 / SVC_32)
- .word __irq_invalid @ 4
- .word __irq_invalid @ 5
- .word __irq_invalid @ 6
- .word __irq_invalid @ 7
- .word __irq_invalid @ 8
- .word __irq_invalid @ 9
- .word __irq_invalid @ a
- .word __irq_invalid @ b
- .word __irq_invalid @ c
- .word __irq_invalid @ d
- .word __irq_invalid @ e
- .word __irq_invalid @ f
-
-.LCtab_und: .word __und_usr @ 0 (USR_26 / USR_32)
- .word __und_invalid @ 1 (FIQ_26 / FIQ_32)
- .word __und_invalid @ 2 (IRQ_26 / IRQ_32)
- .word __und_svc @ 3 (SVC_26 / SVC_32)
- .word __und_invalid @ 4
- .word __und_invalid @ 5
- .word __und_invalid @ 6
- .word __und_invalid @ 7
- .word __und_invalid @ 8
- .word __und_invalid @ 9
- .word __und_invalid @ a
- .word __und_invalid @ b
- .word __und_invalid @ c
- .word __und_invalid @ d
- .word __und_invalid @ e
- .word __und_invalid @ f
-
-.LCtab_dabt: .word __dabt_usr @ 0 (USR_26 / USR_32)
- .word __dabt_invalid @ 1 (FIQ_26 / FIQ_32)
- .word __dabt_invalid @ 2 (IRQ_26 / IRQ_32)
- .word __dabt_svc @ 3 (SVC_26 / SVC_32)
- .word __dabt_invalid @ 4
- .word __dabt_invalid @ 5
- .word __dabt_invalid @ 6
- .word __dabt_invalid @ 7
- .word __dabt_invalid @ 8
- .word __dabt_invalid @ 9
- .word __dabt_invalid @ a
- .word __dabt_invalid @ b
- .word __dabt_invalid @ c
- .word __dabt_invalid @ d
- .word __dabt_invalid @ e
- .word __dabt_invalid @ f
-
-.LCtab_pabt: .word __pabt_usr
- .word __pabt_invalid
-
.LCvswi: .word vector_swi
.LCsirq: .word __temp_irq
@@ -921,7 +899,7 @@ __stubs_end:
b __real_stubs_start + (vector_IRQ - __stubs_start)
b __real_stubs_start + (vector_FIQ - __stubs_start)
-ENTRY(trap_init)
+ENTRY(__trap_init)
stmfd sp!, {r4 - r6, lr}
adr r1, .LCvectors @ set up the vectors
diff --git a/arch/arm/kernel/fiq.c b/arch/arm/kernel/fiq.c
index 7a16832c7..6597de184 100644
--- a/arch/arm/kernel/fiq.c
+++ b/arch/arm/kernel/fiq.c
@@ -42,7 +42,7 @@
#include <asm/fiq.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/system.h>
#include <asm/uaccess.h>
diff --git a/arch/arm/kernel/head-armv.S b/arch/arm/kernel/head-armv.S
index 16436684e..2996d89af 100644
--- a/arch/arm/kernel/head-armv.S
+++ b/arch/arm/kernel/head-armv.S
@@ -189,6 +189,7 @@ __create_page_tables:
str r3, [r0], #4
add r3, r3, #1 << 20
str r3, [r0], #4
+1:
#endif
#endif
#ifdef CONFIG_ARCH_RPC
diff --git a/arch/arm/kernel/hw-footbridge.c b/arch/arm/kernel/hw-footbridge.c
index 117011e1d..e06c8092d 100644
--- a/arch/arm/kernel/hw-footbridge.c
+++ b/arch/arm/kernel/hw-footbridge.c
@@ -678,6 +678,7 @@ void __init hw_init(void)
*/
if (machine_is_netwinder()) {
unsigned long flags;
+ extern int isapnp_disable;
wb977_init();
cpld_init();
@@ -686,6 +687,15 @@ void __init hw_init(void)
spin_lock_irqsave(&gpio_lock, flags);
gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, DEFAULT_LEDS);
spin_unlock_irqrestore(&gpio_lock, flags);
+
+#ifdef CONFIG_ISAPNP
+ /*
+ * We must not use the kernels ISAPnP code
+ * on the NetWinder - it will reset the settings
+ * for the WaveArtist chip and render it inoperable.
+ */
+ isapnp_disable = 1;
+#endif
}
#endif
#ifdef CONFIG_CATS
diff --git a/arch/arm/kernel/ioport.c b/arch/arm/kernel/ioport.c
index d40ea1cf1..07a52ba8e 100644
--- a/arch/arm/kernel/ioport.c
+++ b/arch/arm/kernel/ioport.c
@@ -4,6 +4,7 @@
* IO permission support for ARM.
*/
+#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 3c82ee68c..9afacbde3 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -5,10 +5,6 @@
* Origional Copyright (C) 1995 Linus Torvalds
*/
-/*
- * This file handles the architecture-dependent parts of process handling..
- */
-
#include <stdarg.h>
#include <linux/errno.h>
@@ -39,7 +35,7 @@ extern char *processor_modes[];
asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call");
-static int hlt_counter=0;
+static int hlt_counter;
void disable_hlt(void)
{
@@ -51,6 +47,21 @@ void enable_hlt(void)
hlt_counter--;
}
+static int __init nohlt_setup(char *__unused)
+{
+ hlt_counter = 1;
+ return 0;
+}
+
+static int __init hlt_setup(char *__unused)
+{
+ hlt_counter = 0;
+ return 0;
+}
+
+__setup("nohlt", nohlt_setup);
+__setup("hlt", hlt_setup);
+
/*
* The idle loop on an ARM...
*/
@@ -91,8 +102,9 @@ void machine_restart(char * __unused)
arch_reset(reboot_mode);
+ mdelay(1000);
printk("Reboot failed -- System halted\n");
-
+ cli();
while (1);
}
@@ -110,18 +122,18 @@ void show_regs(struct pt_regs * regs)
flags = condition_codes(regs);
- printk( "pc : [<%08lx>] lr : [<%08lx>]\n"
- "sp : %08lx ip : %08lx fp : %08lx\n",
+ printk("pc : [<%08lx>] lr : [<%08lx>]\n"
+ "sp : %08lx ip : %08lx fp : %08lx\n",
instruction_pointer(regs),
regs->ARM_lr, regs->ARM_sp,
regs->ARM_ip, regs->ARM_fp);
- printk( "r10: %08lx r9 : %08lx r8 : %08lx\n",
+ printk("r10: %08lx r9 : %08lx r8 : %08lx\n",
regs->ARM_r10, regs->ARM_r9,
regs->ARM_r8);
- printk( "r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
+ printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n",
regs->ARM_r7, regs->ARM_r6,
regs->ARM_r5, regs->ARM_r4);
- printk( "r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
+ printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n",
regs->ARM_r3, regs->ARM_r2,
regs->ARM_r1, regs->ARM_r0);
printk("Flags: %c%c%c%c",
@@ -179,62 +191,51 @@ void show_fpregs(struct user_fp *regs)
/*
* Task structure and kernel stack allocation.
- *
- * Taken from the i386 version.
*/
+static struct task_struct *task_struct_head;
+static unsigned int nr_task_struct;
+
#ifdef CONFIG_CPU_32
-#define EXTRA_TASK_STRUCT 8
-static struct task_struct *task_struct_stack[EXTRA_TASK_STRUCT];
-static int task_struct_stack_ptr = -1;
+#define EXTRA_TASK_STRUCT 4
+#else
+#define EXTRA_TASK_STRUCT 0
#endif
struct task_struct *alloc_task_struct(void)
{
struct task_struct *tsk;
-#ifndef EXTRA_TASK_STRUCT
- tsk = ll_alloc_task_struct();
-#else
- int index;
-
- index = task_struct_stack_ptr;
- if (index >= EXTRA_TASK_STRUCT/2)
- goto use_cache;
-
- tsk = ll_alloc_task_struct();
+ if (EXTRA_TASK_STRUCT)
+ tsk = task_struct_head;
+ else
+ tsk = NULL;
- if (!tsk) {
- index = task_struct_stack_ptr;
+ if (tsk) {
+ task_struct_head = tsk->next_task;
+ nr_task_struct -= 1;
+ } else
+ tsk = ll_alloc_task_struct();
- if (index >= 0) {
-use_cache: tsk = task_struct_stack[index];
- task_struct_stack_ptr = index - 1;
- }
- }
-#endif
#ifdef CONFIG_SYSRQ
- /* You need this if you want SYSRQ-T to give sensible stack
- * usage information
+ /*
+ * The stack must be cleared if you want SYSRQ-T to
+ * give sensible stack usage information
*/
if (tsk) {
char *p = (char *)tsk;
memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE);
}
#endif
-
return tsk;
}
-void free_task_struct(struct task_struct *p)
+void __free_task_struct(struct task_struct *p)
{
-#ifdef EXTRA_TASK_STRUCT
- int index = task_struct_stack_ptr + 1;
-
- if (index < EXTRA_TASK_STRUCT) {
- task_struct_stack[index] = p;
- task_struct_stack_ptr = index;
+ if (EXTRA_TASK_STRUCT && nr_task_struct < EXTRA_TASK_STRUCT) {
+ p->next_task = task_struct_head;
+ task_struct_head = p;
+ nr_task_struct += 1;
} else
-#endif
ll_free_task_struct(p);
}
@@ -263,6 +264,8 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
struct pt_regs * childregs;
struct context_save_struct * save;
+ atomic_set(&p->thread.refcount, 1);
+
childregs = ((struct pt_regs *)((unsigned long)p + 8192)) - 1;
*childregs = *regs;
childregs->ARM_r0 = 0;
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 340700dbe..a060bf4d9 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -3,12 +3,6 @@
*
* Copyright (C) 1995-1999 Russell King
*/
-
-/*
- * This file obtains various parameters about the system that the kernel
- * is running on.
- */
-
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/mm.h>
@@ -37,11 +31,7 @@
#define CONFIG_CMDLINE ""
#endif
-#ifndef PARAMS_BASE
-#define PARAMS_BASE NULL
-#endif
-
-extern void reboot_setup(char *str, int *ints);
+extern void reboot_setup(char *str);
extern void disable_hlt(void);
extern int root_mountflags;
extern int _stext, _text, _etext, _edata, _end;
@@ -61,6 +51,20 @@ unsigned int number_mfm_drives;
struct meminfo meminfo;
+struct machine_desc {
+ const char *name; /* architecture name */
+ unsigned int param_offset; /* parameter page */
+ unsigned int reserve_lp0 :1; /* never has lp0 */
+ unsigned int reserve_lp1 :1; /* never has lp1 */
+ unsigned int reserve_lp2 :1; /* never has lp2 */
+ unsigned int broken_hlt :1; /* hlt is broken */
+ unsigned int soft_reboot :1; /* soft reboot */
+ unsigned int video_start; /* start of video RAM */
+ unsigned int video_end; /* end of video RAM */
+ void (*fixup)(struct machine_desc *,
+ struct param_struct *, char **);
+};
+
#ifdef MULTI_CPU
struct processor processor;
#endif
@@ -81,6 +85,7 @@ char elf_platform[ELF_PLATFORM_SIZE];
char saved_command_line[COMMAND_LINE_SIZE];
static struct proc_info_item proc_info;
+static const char *machine_name;
static char command_line[COMMAND_LINE_SIZE] = { 0, };
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
@@ -91,16 +96,14 @@ static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '
* 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]
+#define video_ram mem_res[0]
+#define kernel_code mem_res[1]
+#define kernel_data mem_res[2]
static struct resource io_res[] = {
{ "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY },
@@ -140,6 +143,10 @@ static void __init setup_processor(void)
#ifdef MULTI_CPU
processor = *list->proc;
+
+ printk("Processor: %s %s revision %d\n",
+ proc_info.manufacturer, proc_info.cpu_name,
+ (int)processor_id & 15);
#endif
sprintf(system_utsname.machine, "%s%c", list->arch_name, ENDIANNESS);
@@ -218,10 +225,7 @@ static void __init
setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
{
#ifdef CONFIG_BLK_DEV_RAM
- extern int rd_doload;
- extern int rd_prompt;
- extern int rd_image_start;
- extern int rd_size;
+ extern int rd_doload, rd_prompt, rd_image_start, rd_size;
rd_image_start = image_start;
rd_prompt = prompt;
@@ -245,133 +249,205 @@ static void __init setup_initrd(unsigned int start, unsigned int size)
#endif
}
+#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT)
+#define P_PFN_DOWN(x) O_PFN_DOWN((x) - PHYS_OFFSET)
+#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x))
+
+#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT)
+#define P_PFN_UP(x) O_PFN_UP((x) - PHYS_OFFSET)
+#define V_PFN_UP(x) O_PFN_UP(__pa(x))
+
+#define PFN_SIZE(x) ((x) >> PAGE_SHIFT)
+#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \
+ (((unsigned long)(s)) & PAGE_MASK))
+
+#define free_bootmem(s,sz) free_bootmem((s)<<PAGE_SHIFT, (sz)<<PAGE_SHIFT)
+#define reserve_bootmem(s,sz) reserve_bootmem((s)<<PAGE_SHIFT, (sz)<<PAGE_SHIFT)
+
+static unsigned int __init find_bootmap_pfn(unsigned int bootmap_pages)
+{
+ unsigned int start_pfn, bank, bootmap_pfn;
+
+ start_pfn = V_PFN_UP(&_end);
+ bootmap_pfn = 0;
+
+ /*
+ * FIXME: We really want to avoid allocating the bootmap
+ * over the top of the initrd.
+ */
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start) {
+ if (__pa(initrd_end) > (meminfo.end + PHYS_OFFSET)) {
+ printk ("initrd extends beyond end of memory "
+ "(0x%08lx > 0x%08lx) - disabling initrd\n",
+ __pa(initrd_end), meminfo.end + PHYS_OFFSET);
+ initrd_start = 0;
+ initrd_end = 0;
+ }
+ }
+#endif
+
+ for (bank = 0; bank < meminfo.nr_banks; bank ++) {
+ unsigned int start, end;
+
+ if (meminfo.bank[bank].size == 0)
+ continue;
+
+ start = O_PFN_UP(meminfo.bank[bank].start);
+ end = O_PFN_DOWN(meminfo.bank[bank].size +
+ meminfo.bank[bank].start);
+
+ if (end < start_pfn)
+ continue;
+
+ if (start < start_pfn)
+ start = start_pfn;
+
+ if (end <= start)
+ continue;
+
+ if (end - start >= bootmap_pages) {
+ bootmap_pfn = start;
+ break;
+ }
+ }
+
+ if (bootmap_pfn == 0)
+ BUG();
+
+ return bootmap_pfn;
+}
+
/*
- * Work out our memory regions. Note that "pfn" is the physical page number
- * relative to the first physical page, not the physical address itself.
+ * Initialise the bootmem allocator.
*/
static void __init setup_bootmem(void)
{
- unsigned int end_pfn, bootmem_end;
- int bank;
+ unsigned int end_pfn, start_pfn, bootmap_pages, bootmap_pfn;
+ unsigned int i;
/*
- * Calculate the end of memory.
+ * Calculate the physical address of the top of memory.
*/
- for (bank = 0; bank < meminfo.nr_banks; bank++) {
- if (meminfo.bank[bank].size) {
- unsigned long end;
+ meminfo.end = 0;
+ for (i = 0; i < meminfo.nr_banks; i++) {
+ unsigned long end;
- end = meminfo.bank[bank].start +
- meminfo.bank[bank].size;
+ if (meminfo.bank[i].size != 0) {
+ end = meminfo.bank[i].start + meminfo.bank[i].size;
if (meminfo.end < end)
meminfo.end = end;
}
}
- bootmem_end = __pa(PAGE_ALIGN((unsigned long)&_end));
- end_pfn = meminfo.end >> PAGE_SHIFT;
+ start_pfn = O_PFN_UP(PHYS_OFFSET);
+ end_pfn = O_PFN_DOWN(meminfo.end);
+ bootmap_pages = bootmem_bootmap_pages(end_pfn - start_pfn);
+ bootmap_pfn = find_bootmap_pfn(bootmap_pages);
/*
* Initialise the boot-time allocator
*/
- bootmem_end += init_bootmem(bootmem_end >> PAGE_SHIFT, end_pfn);
+ init_bootmem_start(bootmap_pfn, start_pfn, 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);
+ for (i = 0; i < meminfo.nr_banks; i++)
+ if (meminfo.bank[i].size)
+ free_bootmem(O_PFN_UP(meminfo.bank[i].start),
+ PFN_SIZE(meminfo.bank[i].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)
+ * Register the reserved regions with bootmem
*/
- reserve_bootmem(0, PAGE_SIZE);
+ reserve_bootmem(bootmap_pfn, bootmap_pages);
+ reserve_bootmem(V_PFN_DOWN(&_stext), PFN_RANGE(&_stext, &_end));
+
#ifdef CONFIG_CPU_32
- reserve_bootmem(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(void *));
+ /*
+ * Reserve the page tables. These are already in use.
+ */
+ reserve_bootmem(V_PFN_DOWN(swapper_pg_dir),
+ PFN_SIZE(PTRS_PER_PGD * sizeof(void *)));
#endif
- reserve_bootmem(__pa(&_stext), bootmem_end - __pa(&_stext));
#ifdef CONFIG_BLK_DEV_INITRD
- if (__pa(initrd_end) > (end_pfn << PAGE_SHIFT)) {
- printk ("initrd extends beyond end of memory "
- "(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);
+ reserve_bootmem(O_PFN_DOWN(initrd_start),
+ PFN_RANGE(initrd_start, initrd_end));
#endif
}
-static void __init request_standard_resources(void)
+static void __init request_standard_resources(struct machine_desc *mdesc)
{
- 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(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)
+ struct resource *res;
+ int i;
+
+ kernel_code.start = __virt_to_bus(init_mm.start_code);
+ kernel_code.end = __virt_to_bus(init_mm.end_code - 1);
+ kernel_data.start = __virt_to_bus(init_mm.end_code);
+ kernel_data.end = __virt_to_bus(init_mm.brk - 1);
+
+ for (i = 0; i < meminfo.nr_banks; i++) {
+ unsigned long virt_start, virt_end;
+
+ if (meminfo.bank[i].size == 0)
+ continue;
+
+ virt_start = __phys_to_virt(meminfo.bank[i].start);
+ virt_end = virt_start + meminfo.bank[i].size - 1;
+
+ res = alloc_bootmem_low(sizeof(*res));
+ res->name = "System RAM";
+ res->start = __virt_to_bus(virt_start);
+ res->end = __virt_to_bus(virt_end);
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+
+ request_resource(&iomem_resource, res);
+
+ if (kernel_code.start >= res->start &&
+ kernel_code.end <= res->end)
+ request_resource(res, &kernel_code);
+ if (kernel_data.start >= res->start &&
+ kernel_data.end <= res->end)
+ request_resource(res, &kernel_data);
+ }
+
+ if (mdesc->video_start) {
+ video_ram.start = mdesc->video_start;
+ video_ram.end = mdesc->video_end;
request_resource(&iomem_resource, &video_ram);
+ }
/*
* Some machines don't have the possibility of ever
- * possessing LPT1 (lp0) and LPT3 (lp2)
+ * possessing lp0, lp1 or lp2
*/
- if (machine_is_ebsa110() || machine_is_riscpc() ||
- machine_is_netwinder())
+ if (mdesc->reserve_lp0)
request_resource(&ioport_resource, &lp0);
- if (machine_is_riscpc())
+ if (mdesc->reserve_lp1)
request_resource(&ioport_resource, &lp1);
- if (machine_is_ebsa110() || machine_is_netwinder())
+ if (mdesc->reserve_lp2)
request_resource(&ioport_resource, &lp2);
}
-void __init setup_arch(char **cmdline_p)
+/*
+ * Architecture specific fixups. This is where any
+ * parameters in the params struct are fixed up, or
+ * any additional architecture specific information
+ * is pulled from the params struct.
+ */
+static void __init
+fixup_acorn(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline)
{
- struct param_struct *params = (struct param_struct *)PARAMS_BASE;
- char *from = default_command_line;
-
-#if defined(CONFIG_ARCH_ARC)
- __machine_arch_type = MACH_TYPE_ARCHIMEDES;
-#elif defined(CONFIG_ARCH_A5K)
- __machine_arch_type = MACH_TYPE_A5K;
-#endif
-
- setup_processor();
-
- /*
- * Defaults
- */
- ROOT_DEV = MKDEV(0, 255);
- setup_ramdisk(1, 1, 0, 0);
-
- /*
- * Add your machine dependencies here
- */
- switch (machine_arch_type) {
- case MACH_TYPE_EBSA110:
- /* EBSA110 locks if we execute 'wait for interrupt' */
- disable_hlt();
- if (params && params->u1.s.page_size != PAGE_SIZE)
- params = NULL;
- break;
-
#ifdef CONFIG_ARCH_ACORN
-#ifdef CONFIG_ARCH_RPC
- case MACH_TYPE_RISCPC:
- /* RiscPC can't handle half-word loads and stores */
+ int i;
+
+ if (machine_is_riscpc()) {
+ /*
+ * RiscPC can't handle half-word loads and stores
+ */
elf_hwcap &= ~HWCAP_HALF;
switch (params->u1.s.pages_in_vram) {
@@ -382,106 +458,219 @@ void __init setup_arch(char **cmdline_p)
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;
+
+ if (vram_size) {
+ desc->video_start = 0x02000000;
+ desc->video_end = 0x02000000 + vram_size;
}
-#endif
- case MACH_TYPE_ARCHIMEDES:
- case MACH_TYPE_A5K:
- memc_ctrl_reg = params->u1.s.memc_control_reg;
- number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
- break;
-#endif
- case MACH_TYPE_EBSA285:
- if (params) {
- ORIG_X = params->u1.s.video_x;
- ORIG_Y = params->u1.s.video_y;
- ORIG_VIDEO_COLS = params->u1.s.video_num_cols;
- ORIG_VIDEO_LINES = params->u1.s.video_num_rows;
- video_ram.start = 0x0a0000;
- video_ram.end = 0x0bffff;
+ for (i = 0; i < 4; i++) {
+ meminfo.bank[i].start = PHYS_OFFSET + (i << 26);
+ meminfo.bank[i].size =
+ params->u1.s.pages_in_bank[i] *
+ params->u1.s.page_size;
}
- break;
+ meminfo.nr_banks = 4;
+ }
+ memc_ctrl_reg = params->u1.s.memc_control_reg;
+ number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3;
+#endif
+}
- case MACH_TYPE_CO285:
- {
+static void __init
+fixup_ebsa285(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline)
+{
+ ORIG_X = params->u1.s.video_x;
+ ORIG_Y = params->u1.s.video_y;
+ ORIG_VIDEO_COLS = params->u1.s.video_num_cols;
+ ORIG_VIDEO_LINES = params->u1.s.video_num_rows;
+}
+
+/*
+ * Older NeTTroms either do not provide a parameters
+ * page, or they don't supply correct information in
+ * the parameter page.
+ */
+static void __init
+fixup_netwinder(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline)
+{
+ if (params->u1.s.nr_pages != 0x2000 &&
+ params->u1.s.nr_pages != 0x4000) {
+ printk(KERN_WARNING "Warning: bad NeTTrom parameters "
+ "detected, using defaults\n");
+
+ params->u1.s.nr_pages = 0x2000; /* 32MB */
+ params->u1.s.ramdisk_size = 0;
+ params->u1.s.flags = FLAG_READONLY;
+ params->u1.s.initrd_start = 0;
+ params->u1.s.initrd_size = 0;
+ params->u1.s.rd_start = 0;
+ }
+}
+
+/*
+ * CATS uses soft-reboot by default, since
+ * hard reboots fail on early boards.
+ */
+static void __init
+fixup_cats(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline)
+{
+ ORIG_VIDEO_LINES = 25;
+ ORIG_VIDEO_POINTS = 16;
+ ORIG_Y = 24;
+}
+
+static void __init
+fixup_coebsa285(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline)
+{
#if 0
- extern unsigned long boot_memory_end;
- extern char boot_command_line[];
+ if (machine_is_co285()) {
+ extern unsigned long boot_memory_end;
+ extern char boot_command_line[];
- from = boot_command_line;
- memory_end = boot_memory_end;
-#endif
- params = NULL;
- }
- break;
+ meminfo.nr_banks = 1;
+ meminfo.bank[0].start = PHYS_OFFSET;
+ meminfo.bank[0].size = boot_memory_end;
- case MACH_TYPE_CATS:
- /* CATS uses soft-reboot by default, since hard reboots
- * fail on early boards.
- */
- reboot_setup("s", NULL);
- params = NULL;
- ORIG_VIDEO_LINES = 25;
- ORIG_VIDEO_POINTS = 16;
- ORIG_Y = 24;
- video_ram.start = 0x0a0000;
- video_ram.end = 0x0bffff;
- break;
+ *cmdline = boot_command_line;
+ }
+#endif
+}
- case MACH_TYPE_NETWINDER:
- /*
- * to be fixed in a future NeTTrom
- */
- if (params->u1.s.page_size == PAGE_SIZE) {
- if (params->u1.s.nr_pages != 0x2000 &&
- params->u1.s.nr_pages != 0x4000) {
- printk("Warning: bad NeTTrom parameters detected, using defaults\n");
- /*
- * This stuff doesn't appear to be initialised
- * properly by NeTTrom 2.0.6 and 2.0.7
- */
- params->u1.s.nr_pages = 0x2000; /* 32MB */
- params->u1.s.ramdisk_size = 0;
- params->u1.s.flags = FLAG_READONLY;
- params->u1.s.initrd_start = 0;
- params->u1.s.initrd_size = 0;
- params->u1.s.rd_start = 0;
- }
- } else {
- printk("Warning: no NeTTrom parameter page detected, using "
- "compiled-in settings\n");
- params = NULL;
- }
- video_ram.start = 0x0a0000;
- video_ram.end = 0x0bffff;
- break;
+#define NO_PARAMS 0
+#define NO_VIDEO 0, 0
- default:
- break;
+/*
+ * This is the list of all architectures supported by
+ * this kernel. This should be integrated with the list
+ * in head-armv.S.
+ */
+static struct machine_desc machine_desc[] __initdata = {
+ { "EBSA110", /* RMK */
+ 0x00000400,
+ NO_VIDEO,
+ 1, 0, 1, 1, 1,
+ NULL
+ }, { "Acorn-RiscPC", /* RMK */
+ 0x10000100,
+ NO_VIDEO,
+ 1, 1, 0, 0, 0,
+ fixup_acorn
+ }, { "unknown",
+ NO_PARAMS,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ NULL
+ }, { "Nexus-FTV/PCI", /* Philip Blundell */
+ NO_PARAMS,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ NULL
+ }, { "EBSA285", /* RMK */
+ 0x00000100,
+ 0x000a0000, 0x000bffff,
+ 0, 0, 0, 0, 0,
+ fixup_ebsa285
+ }, { "Rebel-NetWinder", /* RMK */
+ 0x00000100,
+ 0x000a0000, 0x000bffff,
+ 1, 0, 1, 0, 0,
+ fixup_netwinder
+ }, { "Chalice-CATS", /* Philip Blundell */
+ NO_PARAMS,
+ 0x000a0000, 0x000bffff,
+ 0, 0, 0, 0, 1,
+ fixup_cats
+ }, { "unknown-TBOX", /* Philip Blundell */
+ NO_PARAMS,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ NULL
+ }, { "co-EBSA285", /* Mark van Doesburg */
+ NO_PARAMS,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ fixup_coebsa285
+ }, { "CL-PS7110", /* Werner Almesberger */
+ NO_PARAMS,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ NULL
+ }, { "Acorn-Archimedes",/* RMK/DAG */
+ 0x0207c000,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ fixup_acorn
+ }, { "Acorn-A5000", /* RMK/PB */
+ 0x0207c000,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ fixup_acorn
+ }, { "Etoile", /* Alex de Vries */
+ NO_PARAMS,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ NULL
+ }, { "LaCie_NAS", /* Benjamin Herrenschmidt */
+ NO_PARAMS,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ NULL
+ }, { "CL-PS7500", /* Philip Blundell */
+ NO_PARAMS,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ NULL
+ }, { "Shark", /* Alexander Schulz */
+ NO_PARAMS,
+ NO_VIDEO,
+ 0, 0, 0, 0, 0,
+ NULL
}
+};
+
+void __init setup_arch(char **cmdline_p)
+{
+ struct param_struct *params = NULL;
+ struct machine_desc *mdesc;
+ char *from = default_command_line;
+
+#if defined(CONFIG_ARCH_ARC)
+ __machine_arch_type = MACH_TYPE_ARCHIMEDES;
+#elif defined(CONFIG_ARCH_A5K)
+ __machine_arch_type = MACH_TYPE_A5K;
+#endif
+
+ setup_processor();
+
+ ROOT_DEV = MKDEV(0, 255);
+
+ mdesc = machine_desc + machine_arch_type;
+ machine_name = mdesc->name;
+
+ if (mdesc->broken_hlt)
+ disable_hlt();
+
+ if (mdesc->soft_reboot)
+ reboot_setup("s");
+
+ if (mdesc->param_offset)
+ params = phys_to_virt(mdesc->param_offset);
+
+ if (mdesc->fixup)
+ mdesc->fixup(mdesc, params, &from);
if (params && params->u1.s.page_size != PAGE_SIZE) {
- printk("Warning: wrong page size configuration, "
+ printk(KERN_WARNING "Warning: bad configuration page, "
"trying to continue\n");
params = NULL;
}
if (params) {
- 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;
@@ -503,8 +692,11 @@ void __init setup_arch(char **cmdline_p)
if (meminfo.nr_banks == 0) {
meminfo.nr_banks = 1;
- meminfo.bank[0].start = 0;
- meminfo.bank[0].size = MEM_SIZE;
+ meminfo.bank[0].start = PHYS_OFFSET;
+ if (params)
+ meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT;
+ else
+ meminfo.bank[0].size = MEM_SIZE;
}
init_mm.start_code = (unsigned long) &_text;
@@ -512,12 +704,11 @@ void __init setup_arch(char **cmdline_p)
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_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();
+ request_standard_resources(mdesc);
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
@@ -528,26 +719,6 @@ void __init setup_arch(char **cmdline_p)
#endif
}
-static const char *machine_desc[] = {
- /* Machine name Allocater */
- "EBSA110", /* RMK */
- "Acorn-RiscPC", /* RMK */
- "unknown",
- "Nexus-FTV/PCI", /* Philip Blundell */
- "EBSA285", /* RMK */
- "Rebel-NetWinder", /* RMK */
- "Chalice-CATS", /* Philip Blundell */
- "unknown-TBOX", /* Philip Blundell */
- "co-EBSA285", /* Mark van Doesburg */
- "CL-PS7110", /* Werner Almesberger */
- "Acorn-Archimedes", /* RMK/DAG */
- "Acorn-A5000", /* RMK/PB */
- "Etoile", /* Alex de Vries */
- "LaCie_NAS", /* Benjamin Herrenschmidt */
- "CL-PS7500", /* Philip Blundell */
- "Shark" /* Alexander Schulz */
-};
-
int get_cpuinfo(char * buffer)
{
char *p = buffer;
@@ -560,8 +731,7 @@ int get_cpuinfo(char * buffer)
(loops_per_sec+2500) / 500000,
((loops_per_sec+2500) / 5000) % 100);
- p += sprintf(p, "Hardware\t: %s\n",
- machine_desc[machine_arch_type]);
+ p += sprintf(p, "Hardware\t: %s\n", machine_name);
p += sprintf(p, "Revision\t: %04x\n",
system_rev);
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 3f86f4740..852bbfac1 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -21,7 +21,7 @@
#include <asm/ucontext.h>
#include <asm/uaccess.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
@@ -545,6 +545,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index f25544c14..408149bc5 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -49,6 +49,36 @@ asmlinkage int sys_pipe(unsigned long * fildes)
return error;
}
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+ unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ int error = -EBADF;
+ struct file * file = NULL;
+
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ if (!(flags & MAP_ANONYMOUS)) {
+ file = fget(fd);
+ if (!file)
+ goto out;
+ }
+
+ down(&current->mm->mmap_sem);
+ lock_kernel();
+
+ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+
+ unlock_kernel();
+ up(&current->mm->mmap_sem);
+
+ if (file)
+ fput(file);
+out:
+ return error;
+}
+
/*
* Perform the select(nd, in, out, ex, tv) and mmap() system
* calls. ARM Linux didn't use to be able to handle more than
@@ -68,30 +98,20 @@ struct mmap_arg_struct {
asmlinkage int old_mmap(struct mmap_arg_struct *arg)
{
int error = -EFAULT;
- struct file * file = NULL;
struct mmap_arg_struct a;
- down(&current->mm->mmap_sem);
- lock_kernel();
if (copy_from_user(&a, arg, sizeof(a)))
+ goto out;;
+
+ error = -EINVAL;
+ if (a.offset & ~PAGE_MASK)
goto out;
- if (!(a.flags & MAP_ANONYMOUS)) {
- error = -EBADF;
- file = fget(a.fd);
- if (!file)
- goto out;
- }
- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
- if (file)
- fput(file);
+
+ error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
out:
- unlock_kernel();
- up(&current->mm->mmap_sem);
return error;
}
-
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
struct sel_arg_struct {
@@ -119,104 +139,73 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
{
int version, ret;
- lock_kernel();
version = call >> 16; /* hack for backward compatibility */
call &= 0xffff;
- if (call <= SEMCTL)
- switch (call) {
- case SEMOP:
- ret = sys_semop (first, (struct sembuf *)ptr, second);
- goto out;
- case SEMGET:
- ret = sys_semget (first, second, third);
- goto out;
- case SEMCTL: {
- union semun fourth;
- ret = -EINVAL;
+ 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)
- goto out;
- ret = -EFAULT;
- if (get_user(fourth.__pad, (void **) ptr))
- goto out;
- ret = sys_semctl (first, second, third, fourth);
- goto out;
- }
- default:
- ret = -EINVAL;
- goto out;
+ 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);
}
- if (call <= MSGCTL)
- switch (call) {
- case MSGSND:
- ret = sys_msgsnd (first, (struct msgbuf *) ptr,
- second, third);
- goto out;
- case MSGRCV:
- switch (version) {
- case 0: {
- struct ipc_kludge tmp;
- ret = -EINVAL;
- if (!ptr)
- goto out;
- ret = -EFAULT;
- if (copy_from_user(&tmp,(struct ipc_kludge *) ptr,
- sizeof (tmp)))
- goto out;
- ret = sys_msgrcv (first, tmp.msgp, second, tmp.msgtyp, third);
- goto out;
- }
- case 1: default:
- ret = sys_msgrcv (first, (struct msgbuf *) ptr, second, fifth, third);
- goto out;
- }
- case MSGGET:
- ret = sys_msgget ((key_t) first, second);
- goto out;
- case MSGCTL:
- ret = sys_msgctl (first, second, (struct msqid_ds *) ptr);
- goto out;
default:
- ret = -EINVAL;
- goto out;
+ return sys_msgrcv (first,
+ (struct msgbuf *) ptr,
+ second, fifth, third);
}
- if (call <= SHMCTL)
- switch (call) {
- case SHMAT:
- switch (version) {
- case 0: default: {
- ulong raddr;
- ret = sys_shmat (first, (char *) ptr, second, &raddr);
- if (ret)
- goto out;
- ret = put_user (raddr, (ulong *) third);
- goto out;
- }
- case 1: /* iBCS2 emulator entry point */
- ret = -EINVAL;
- if (!segment_eq(get_fs(), get_ds()))
- goto out;
- ret = sys_shmat (first, (char *) ptr, second, (ulong *) third);
- goto out;
- }
- case SHMDT:
- ret = sys_shmdt ((char *)ptr);
- goto out;
- case SHMGET:
- ret = sys_shmget (first, second, third);
- goto out;
- case SHMCTL:
- ret = sys_shmctl (first, second, (struct shmid_ds *) ptr);
- goto out;
- default:
- ret = -EINVAL;
- goto out;
+ 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);
}
- else
- ret = -EINVAL;
-out:
- unlock_kernel();
- return ret;
+ 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;
+ }
}
/* Fork a new task - this creates a new program thread.
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 038946e9c..26ecfa194 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -17,6 +17,7 @@
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/spinlock.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/uaccess.h>
@@ -132,7 +133,7 @@ static void dump_instr(unsigned long pc, int user)
printk ("pc not in code space\n");
}
-spinlock_t die_lock;
+spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
/*
* This function is protected against re-entrancy.
@@ -423,3 +424,13 @@ asmlinkage void __div0(void)
printk("Division by zero in kernel.\n");
__backtrace();
}
+
+void __init trap_init(void)
+{
+ extern void __trap_init(void);
+
+ __trap_init();
+#ifdef CONFIG_CPU_32
+ modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
+#endif
+}
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
index fd85107c3..e871f2615 100644
--- a/arch/arm/lib/backtrace.S
+++ b/arch/arm/lib/backtrace.S
@@ -83,28 +83,34 @@ ENTRY(c_backtrace)
#define reg r5
#define stack r6
-.Ldumpstm: stmfd sp!, {instr, reg, stack, lr}
+.Ldumpstm: stmfd sp!, {instr, reg, stack, r7, lr}
mov stack, r0
mov instr, r1
mov reg, #9
-
+ mov r7, #0
1: mov r3, #1
tst instr, r3, lsl reg
beq 2f
+ add r7, r7, #1
+ teq r7, #4
+ moveq r7, #0
+ moveq r3, #'\n'
+ movne r3, #' '
ldr r2, [stack], #-4
mov r1, reg
adr r0, .Lfp
bl SYMBOL_NAME(printk)
2: subs reg, reg, #1
bpl 1b
-
+ teq r7, #0
+ adrne r0, .Lcr
+ blne SYMBOL_NAME(printk)
mov r0, stack
- LOADREGS(fd, sp!, {instr, reg, stack, pc})
+ LOADREGS(fd, sp!, {instr, reg, stack, r7, pc})
-.Lfe: .ascii "Function entered at [<%p>] from [<%p>]\n"
- .byte 0
-.Lfp: .ascii " r%d = %p\n"
- .byte 0
+.Lfe: .asciz "Function entered at [<%p>] from [<%p>]\n"
+.Lfp: .asciz " r%d = %08X%c"
+.Lcr: .asciz "\n"
.align
.Ldsi: .word 0x00e92dd8 >> 2
.word 0x00e92d00 >> 2
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 229b4dcd7..17972e427 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -25,7 +25,7 @@
#include <asm/system.h>
#include <asm/segment.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/dma.h>
#include <asm/hardware.h>
#include <asm/setup.h>
@@ -168,6 +168,7 @@ void show_mem(void)
void __init paging_init(void)
{
void *zero_page, *bad_page, *bad_table;
+ unsigned int zone_size[3];
#ifdef CONFIG_CPU_32
#define TABLE_OFFSET (PTRS_PER_PTE)
@@ -189,7 +190,11 @@ void __init paging_init(void)
pagetable_init();
flush_tlb_all();
- free_area_init(max_low_pfn);
+ /*
+ * Initialise the zones and mem_map
+ */
+ zonesize_init(zone_size);
+ free_area_init(zone_size);
/*
* finish off the bad pages once
@@ -235,22 +240,23 @@ static inline void free_unused_mem_map(void)
*/
void __init mem_init(void)
{
- int codepages = 0;
- int reservedpages = 0;
- int datapages = 0;
- int initpages = 0, i, min_nr;
+ extern char __init_begin, __init_end, _text, _etext, _end;
+ unsigned int codepages, datapages, initpages;
+ int i;
- max_mapnr = max_low_pfn;
- high_memory = (void *)__va(max_low_pfn * PAGE_SIZE);
+ codepages = &_etext - &_text;
+ datapages = &_end - &_etext;
+ initpages = &__init_end - &__init_begin;
+
+ max_mapnr = max_low_pfn;
+ high_memory = (void *)__va(PHYS_OFFSET + max_low_pfn * PAGE_SIZE);
-#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
/* this will put all unused low memory onto the freelists */
totalram_pages += free_all_bootmem();
@@ -259,42 +265,28 @@ void __init mem_init(void)
* Since our memory may not be contiguous, calculate the
* real number of pages we have in this system
*/
+ printk("Memory:");
+
num_physpages = 0;
- for (i = 0; i < meminfo.nr_banks; i++)
+ for (i = 0; i < meminfo.nr_banks; i++) {
num_physpages += meminfo.bank[i].size >> PAGE_SHIFT;
+ printk(" %ldMB", meminfo.bank[i].size >> 20);
+ }
- printk ("Memory: %luk/%luM available (%dk code, %dk reserved, %dk data, %dk init)\n",
- (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
- num_physpages >> (20 - PAGE_SHIFT),
- codepages << (PAGE_SHIFT-10),
- reservedpages << (PAGE_SHIFT-10),
- datapages << (PAGE_SHIFT-10),
- initpages << (PAGE_SHIFT-10));
+ printk(" = %luMB total\n", num_physpages >> (20 - PAGE_SHIFT));
+ printk("Memory: %luKB available (%dK code, %dK data, %dK init)\n",
+ (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
+ codepages >> 10, datapages >> 10, initpages >> 10);
- /*
- * Correct freepages watermarks
- */
- i = nr_free_pages >> 7;
- if (PAGE_SIZE < 32768)
- min_nr = 10;
- else
- min_nr = 2;
- if (i < min_nr)
- i = min_nr;
- if (i > 256)
- i = 256;
- freepages.min = i;
- freepages.low = i * 2;
- freepages.high = i * 3;
-
-#ifdef CONFIG_CPU_26
- if (max_mapnr <= 128) {
+ if (PAGE_SIZE >= 16384 && num_physpages <= 128) {
extern int sysctl_overcommit_memory;
- /* On a machine this small we won't get anywhere without
- overcommit, so turn it on by default. */
+ /*
+ * On a machine this small we won't get
+ * anywhere without overcommit, so turn
+ * it on by default.
+ */
sysctl_overcommit_memory = 1;
}
-#endif
}
static inline void free_area(unsigned long addr, unsigned long end, char *s)
@@ -344,11 +336,24 @@ void free_initmem(void)
printk("\n");
}
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(mem_map + MAP_NR(start));
+ set_page_count(mem_map+MAP_NR(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
void si_meminfo(struct sysinfo *val)
{
val->totalram = totalram_pages;
val->sharedram = 0;
- val->freeram = nr_free_pages;
+ val->freeram = nr_free_pages();
val->bufferram = atomic_read(&buffermem_pages);
val->totalhigh = 0;
val->freehigh = 0;
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 141644ae2..fb3007f8a 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -32,7 +32,7 @@
#include <linux/vmalloc.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/io.h>
static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
@@ -136,7 +136,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
/*
* Ok, go for it..
*/
- area = get_vm_area(size);
+ area = get_vm_area(size, VM_IOREMAP);
if (!area)
return NULL;
addr = area->addr;
diff --git a/arch/arm/mm/map.h b/arch/arm/mm/map.h
index 0a3ee8b4d..b596c6479 100644
--- a/arch/arm/mm/map.h
+++ b/arch/arm/mm/map.h
@@ -19,6 +19,7 @@ struct map_desc {
extern struct map_desc io_desc[];
extern unsigned int io_desc_size;
+extern void zonesize_init(unsigned int *);
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 5ee95ea45..680a52948 100644
--- a/arch/arm/mm/mm-armo.c
+++ b/arch/arm/mm/mm-armo.c
@@ -11,6 +11,7 @@
#include <linux/bootmem.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/page.h>
#include <asm/arch/memory.h>
@@ -134,6 +135,20 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
}
/*
+ * Calculate the size of the DMA, normal and highmem zones.
+ * On 26-bit ARMs, we don't have any real DMA or highmem,
+ * so we allocate the whole memory as being DMA-capable.
+ */
+void __init zonesize_init(unsigned int *zone_size)
+{
+ int i;
+
+ zone_size[0] = max_low_pfn;
+ zone_size[1] = 0;
+ zone_size[2] = 0;
+}
+
+/*
* This contains the code to setup the memory map on an ARM2/ARM250/ARM3
* machine. This is both processor & architecture specific, and requires
* some more work to get it to fit into our separate processor and
@@ -147,7 +162,6 @@ void __init pagetable_init(void)
page_nr = max_low_pfn;
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));
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index 3df6c13b5..ee4750c62 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -11,6 +11,7 @@
#include <linux/bootmem.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/page.h>
#include <asm/io.h>
#include <asm/setup.h>
@@ -24,6 +25,31 @@ extern void free_page_2k(unsigned long page);
extern pte_t *get_bad_pte_table(void);
/*
+ * These are useful for identifing cache coherency
+ * problems by allowing the cache or the cache and
+ * writebuffer to be turned off. (Note: the write
+ * buffer should not be on and the cache off).
+ */
+static int __init nocache_setup(char *__unused)
+{
+ cr_alignment &= ~4;
+ cr_no_alignment &= ~4;
+ set_cr(cr_alignment);
+ return 1;
+}
+
+static int __init nowrite_setup(char *__unused)
+{
+ cr_alignment &= ~(8|4);
+ cr_no_alignment &= ~(8|4);
+ set_cr(cr_alignment);
+ return 1;
+}
+
+__setup("nocache", nocache_setup);
+__setup("nowb", nowrite_setup);
+
+/*
* need to get a 16k page for level 1
*/
pgd_t *get_pgd_slow(void)
@@ -178,7 +204,6 @@ alloc_init_page(unsigned long virt, unsigned long phys, int domain, int prot)
pte_t *ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE *
sizeof(pte_t));
- 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)));
@@ -266,6 +291,32 @@ static struct map_desc init_map[] __initdata = {
#define NR_INIT_MAPS (sizeof(init_map) / sizeof(init_map[0]))
+/*
+ * Calculate the size of the DMA, normal and highmem zones.
+ * On ARM, we don't have any problems with DMA, so all memory
+ * is allocated to the DMA zone. We also don't have any
+ * highmem either.
+ */
+void __init zonesize_init(unsigned int *zone_size)
+{
+ int i;
+
+ zone_size[0] = 0;
+ zone_size[1] = 0;
+ zone_size[2] = 0;
+
+ for (i = 0; i < meminfo.nr_banks; i++) {
+ if (meminfo.bank[i].size) {
+ unsigned int end;
+
+ end = (meminfo.bank[i].start - PHYS_OFFSET +
+ meminfo.bank[i].size) >> PAGE_SHIFT;
+ if (end > zone_size[0])
+ zone_size[0] = end;
+ }
+ }
+}
+
void __init pagetable_init(void)
{
unsigned long address = 0;
@@ -274,7 +325,7 @@ void __init pagetable_init(void)
/*
* Setup the above mappings
*/
- init_map[0].physical = PHYS_OFFSET;
+ init_map[0].physical = virt_to_phys(alloc_bootmem_low_pages(PAGE_SIZE));
init_map[5].physical = FLUSH_BASE_PHYS;
init_map[5].virtual = FLUSH_BASE;
#ifdef FLUSH_BASE_MINICACHE
@@ -284,8 +335,9 @@ void __init pagetable_init(void)
#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].physical = meminfo.bank[i].start;
+ init_map[i+1].virtual = meminfo.bank[i].start +
+ PAGE_OFFSET - PHYS_OFFSET;
init_map[i+1].length = meminfo.bank[i].size;
}
@@ -327,13 +379,15 @@ void __init create_memmap_holes(void)
{
unsigned int start_pfn, end_pfn = -1;
struct page *pg = NULL;
- unsigned int sz, i;
+ unsigned int i;
+
+#define PFN(x) (((x) - PHYS_OFFSET) >> PAGE_SHIFT)
for (i = 0; i < meminfo.nr_banks; i++) {
if (meminfo.bank[i].size == 0)
continue;
- start_pfn = meminfo.bank[i].start >> PAGE_SHIFT;
+ start_pfn = PFN(meminfo.bank[i].start);
/*
* subtle here - if we have a full bank, then
@@ -344,8 +398,8 @@ void __init create_memmap_holes(void)
set_bit(PG_skip, &pg->flags);
pg->next_hash = mem_map + start_pfn;
- start_pfn = PAGE_ALIGN(__pa(pg + 1));
- end_pfn = __pa(pg->next_hash) & PAGE_MASK;
+ start_pfn = PFN(PAGE_ALIGN(__pa(pg + 1)));
+ end_pfn = PFN(__pa(pg->next_hash) & PAGE_MASK);
if (end_pfn != start_pfn)
free_bootmem(start_pfn, end_pfn - start_pfn);
@@ -353,8 +407,7 @@ void __init create_memmap_holes(void)
pg = NULL;
}
- end_pfn = (meminfo.bank[i].start +
- meminfo.bank[i].size) >> PAGE_SHIFT;
+ end_pfn = PFN(meminfo.bank[i].start + meminfo.bank[i].size);
if (end_pfn != meminfo.end >> PAGE_SHIFT)
pg = mem_map + end_pfn;
@@ -364,27 +417,4 @@ void __init create_memmap_holes(void)
set_bit(PG_skip, &pg->flags);
pg->next_hash = NULL;
}
-
-#if 0
- /*
- * setup address validity map
- * - don't think this is used anymore?
- */
- 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/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S
index dcb5c10dc..36a9d8b28 100644
--- a/arch/arm/mm/proc-arm2,3.S
+++ b/arch/arm/mm/proc-arm2,3.S
@@ -270,9 +270,9 @@ _arm2_3_check_bugs:
bics pc, lr, #0x04000000 @ Clear FIQ disable bit
armvlsi_name: .asciz "ARM/VLSI"
-_arm2_name: .asciz "arm2"
-_arm250_name: .asciz "arm250"
-_arm3_name: .asciz "arm3"
+_arm2_name: .asciz "ARM 2"
+_arm250_name: .asciz "ARM 250"
+_arm3_name: .asciz "ARM 3"
.section ".text.init", #alloc, #execinstr
/*
diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S
index b085c3c4e..d453269d2 100644
--- a/arch/arm/mm/proc-arm6,7.S
+++ b/arch/arm/mm/proc-arm6,7.S
@@ -413,12 +413,12 @@ ENTRY(cpu_arm7_reset)
cpu_armvlsi_name:
.asciz "ARM/VLSI"
-cpu_arm6_name: .asciz "arm6"
+cpu_arm6_name: .asciz "ARM 6"
cpu_arm610_name:
- .asciz "arm610"
-cpu_arm7_name: .asciz "arm7"
+ .asciz "ARM 610"
+cpu_arm7_name: .asciz "ARM 7"
cpu_arm710_name:
- .asciz "arm710"
+ .asciz "ARM 710"
.align
.section ".text.init", #alloc, #execinstr
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index 266d960b5..2d57b1030 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -456,9 +456,9 @@ ENTRY(cpu_sa1100_reset)
cpu_manu_name: .asciz "Intel"
ENTRY(cpu_sa110_name)
- .asciz "sa110"
+ .asciz "StrongARM-110"
ENTRY(cpu_sa1100_name)
- .asciz "sa1100"
+ .asciz "StrongARM-1100"
.align
.section ".text.init", #alloc, #execinstr
diff --git a/arch/arm/mm/small_page.c b/arch/arm/mm/small_page.c
index ac303d45e..ee7f571a7 100644
--- a/arch/arm/mm/small_page.c
+++ b/arch/arm/mm/small_page.c
@@ -66,9 +66,9 @@ static struct order orders[] = {
#endif
};
-#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))
+#define USED_MAP(pg) ((pg)->index)
+#define TEST_AND_CLEAR_USED(pg,off) (test_and_clear_bit(off, &USED_MAP(pg)))
+#define SET_USED(pg,off) (set_bit(off, &USED_MAP(pg)))
static void add_page_to_queue(struct page *page, struct page **p)
{
diff --git a/arch/i386/boot/Makefile b/arch/i386/boot/Makefile
index de8cdced8..56a941a62 100644
--- a/arch/i386/boot/Makefile
+++ b/arch/i386/boot/Makefile
@@ -55,7 +55,7 @@ bbootsect: bbootsect.o
$(LD) -Ttext 0x0 -s -oformat binary $< -o $@
bbootsect.o: bbootsect.s
- $(AS) --defsym bootsect_kludge=0x220 -o $@ $<
+ $(AS) -o $@ $<
bbootsect.s: bootsect.S Makefile $(BOOT_INCL)
$(CPP) -D__BIG_KERNEL__ -traditional $(SVGA_MODE) $(RAMDISK) $< -o $@
diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S
index 58644810e..4a9d59908 100644
--- a/arch/i386/boot/bootsect.S
+++ b/arch/i386/boot/bootsect.S
@@ -247,7 +247,8 @@ die: jne die # es must be at 64kB boundary
xorw %bx, %bx # bx is starting address within segment
rp_read:
#ifdef __BIG_KERNEL__
- lcall bootsect_kludge # in setup.S
+ bootsect_kludge = 0x220 # 0x200 (size of bootsector) + 0x20 (offset
+ lcall bootsect_kludge # of bootsect_kludge in setup.S)
#else
movw %es, %ax
subw $SYSSEG, %ax
@@ -398,11 +399,9 @@ print_digit:
# don't have to worry about it later.
kill_motor:
- pushw %dx
movw $0x3f2, %dx
xorb %al, %al
outb %al, %dx
- popw %dx
ret
sectors: .word 0
diff --git a/arch/i386/boot/compressed/misc.c b/arch/i386/boot/compressed/misc.c
index 92ae6af45..8aac90800 100644
--- a/arch/i386/boot/compressed/misc.c
+++ b/arch/i386/boot/compressed/misc.c
@@ -9,10 +9,8 @@
* High loaded stuff by Hans Lermen & Werner Almesberger, Feb. 1996
*/
-#include <linux/mm.h>
-#include <asm/segment.h>
+#include <linux/vmalloc.h>
#include <asm/io.h>
-
/*
* gzip declarations
*/
diff --git a/arch/i386/boot/setup.S b/arch/i386/boot/setup.S
index 9c450bab8..cbfa7b3e8 100644
--- a/arch/i386/boot/setup.S
+++ b/arch/i386/boot/setup.S
@@ -125,7 +125,6 @@ ramdisk_image: .long 0 # address of loaded ramdisk image
ramdisk_size: .long 0 # its size in bytes
-.global bootsect_kludge # so that we can see it in bootsect.S
bootsect_kludge:
.word bootsect_helper, SETUPSEG
@@ -209,7 +208,7 @@ bad_sig:
addw $SYSSEG, %bx
movw %bx, %cs:start_sys_seg
# Move rest of setup code/data to here
- movw $4096, %di # four sectors loaded by LILO
+ movw $2048, %di # four sectors loaded by LILO
subw %si, %si
movw %cs, %ax # aka SETUPSEG
movw %ax, %es
@@ -456,7 +455,7 @@ no_psmouse:
xorw %bx, %bx
int $0x15 # ignore return code
movw $0x05303, %ax # 32 bit connect
- xorw %ebx, %ebx
+ xorw %bx, %bx
int $0x15
jc no_32_apm_bios # Ack, error.
@@ -783,7 +782,7 @@ bootsect_panic_mess:
empty_8042:
pushl %ecx
- movl $0xFFFFFF, %ecx
+ movl $0x00FFFFFF, %ecx
empty_8042_loop:
decl %ecx
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S
index 77d22bef1..745f47275 100644
--- a/arch/i386/boot/video.S
+++ b/arch/i386/boot/video.S
@@ -1008,7 +1008,7 @@ vesa_modes:
vesa1:
# gas version 2.9.1, using BFD version 2.9.1.0.23 buggers the next inst.
# XXX: lodsw %gs:(%si), %ax # Get next mode in the list
- .byte 0x66, 0x65, 0xAD
+ .byte 0x65, 0xAD # %gs seg prefix + lodsw
cmpw $0xffff, %ax # End of the table?
jz vesar
@@ -1278,7 +1278,7 @@ no_s3: movb $0x35, %al # restore CRT register 0x35
no_s31: xorw %bp, %bp # Detection failed
s3rest: movb %bh, %ah
movb $0x38, %al # restore old value of CRT register 0x38
- call outidx
+ jmp outidx
idS3: .byte 0x81, 0x82, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95
.byte 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa8, 0xb0
diff --git a/arch/i386/config.in b/arch/i386/config.in
index 03433d968..4a09997b2 100644
--- a/arch/i386/config.in
+++ b/arch/i386/config.in
@@ -95,8 +95,12 @@ else
define_bool CONFIG_PCI_DIRECT y
fi
fi
- bool 'MCA support' CONFIG_MCA
+fi
+source drivers/pci/Config.in
+
+if [ "$CONFIG_VISWS" != "y" ]; then
+ bool 'MCA support' CONFIG_MCA
fi
source drivers/pcmcia/Config.in
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 6aa8412c1..8d1e2a67f 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -51,6 +51,7 @@ CONFIG_PCI=y
CONFIG_PCI_GOANY=y
CONFIG_PCI_BIOS=y
CONFIG_PCI_DIRECT=y
+CONFIG_PCI_NAMES=y
# CONFIG_MCA is not set
#
@@ -169,6 +170,7 @@ CONFIG_BLK_DEV_SD=y
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
#
+CONFIG_SCSI_DEBUG_QUEUES=y
CONFIG_SCSI_MULTI_LUN=y
CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_LOGGING is not set
@@ -257,7 +259,6 @@ CONFIG_NET_ETHERNET=y
# CONFIG_NET_ISA is not set
CONFIG_NET_EISA=y
# CONFIG_PCNET32 is not set
-# CONFIG_ACENIC is not set
# CONFIG_APRICOT is not set
# CONFIG_CS89x0 is not set
# CONFIG_DE4X5 is not set
@@ -265,9 +266,16 @@ CONFIG_NET_EISA=y
# CONFIG_DGRS is not set
CONFIG_EEXPRESS_PRO100=y
# CONFIG_NE2K_PCI is not set
+# CONFIG_SIS900 is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -299,6 +307,7 @@ CONFIG_PCMCIA_PCNET=y
# CONFIG_PCMCIA_NMCLAN is not set
# CONFIG_PCMCIA_SMC91C92 is not set
# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_AIRONET4500_CS is not set
# CONFIG_PCMCIA_3C575 is not set
# CONFIG_PCMCIA_TULIP is not set
# CONFIG_PCMCIA_EPIC100 is not set
@@ -347,6 +356,11 @@ CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
# CONFIG_QIC02_TAPE is not set
#
@@ -360,11 +374,6 @@ CONFIG_PSMOUSE=y
# Video For Linux
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -373,6 +382,9 @@ CONFIG_PSMOUSE=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
+CONFIG_DRM=y
+CONFIG_DRM_TDFX=y
+# CONFIG_DRM_GAMMA is not set
#
# PCMCIA character device support
@@ -381,7 +393,7 @@ CONFIG_PSMOUSE=y
# CONFIG_PCMCIA_SERIAL_CB is not set
#
-# USB drivers - not for the faint of heart
+# Support for USB
#
# CONFIG_USB is not set
@@ -396,14 +408,12 @@ CONFIG_ACPI=y
# CONFIG_QUOTA is not set
CONFIG_AUTOFS_FS=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=y
# CONFIG_JOLIET is not set
-# CONFIG_UDF_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -412,6 +422,7 @@ CONFIG_DEVPTS_FS=y
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
# CONFIG_UFS_FS is not set
#
@@ -420,7 +431,6 @@ CONFIG_EXT2_FS=y
# CONFIG_CODA_FS 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
@@ -431,9 +441,6 @@ CONFIG_LOCKD=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c
index cdeaf9a35..564e6b42b 100644
--- a/arch/i386/kernel/apm.c
+++ b/arch/i386/kernel/apm.c
@@ -380,7 +380,7 @@ static u8 apm_bios_call(u32 func, u32 ebx_in, u32 ecx_in,
__asm__ __volatile__(APM_DO_ZERO_SEGS
"pushl %%edi\n\t"
"pushl %%ebp\n\t"
- "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
+ "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "; cld\n\t"
"setc %%al\n\t"
"popl %%ebp\n\t"
"popl %%edi\n\t"
@@ -413,7 +413,7 @@ static u8 apm_bios_call_simple(u32 func, u32 ebx_in, u32 ecx_in, u32 *eax)
__asm__ __volatile__(APM_DO_ZERO_SEGS
"pushl %%edi\n\t"
"pushl %%ebp\n\t"
- "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry) "\n\t"
+ "lcall %%cs:" SYMBOL_NAME_STR(apm_bios_entry)"; cld\n\t"
"setc %%bl\n\t"
"popl %%ebp\n\t"
"popl %%edi\n\t"
@@ -1193,7 +1193,7 @@ static int do_open(struct inode * inode, struct file * filp)
return 0;
}
-int apm_get_info(char *buf, char **start, off_t fpos, int length, int dummy)
+static int apm_get_info(char *buf, char **start, off_t fpos, int length)
{
char * p;
unsigned short bx;
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index 59e420749..4eef2d8c9 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -592,6 +592,10 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
.long SYMBOL_NAME(sys_vfork) /* 190 */
.long SYMBOL_NAME(sys_getrlimit)
+ .long SYMBOL_NAME(sys_mmap2)
+ .long SYMBOL_NAME(sys_truncate64)
+ .long SYMBOL_NAME(sys_ftruncate64)
+ /* 195 */
/*
* NOTE!! This doesn't have to be exact - we just have
@@ -599,6 +603,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-191
+ .rept NR_syscalls-194
.long SYMBOL_NAME(sys_ni_syscall)
.endr
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c
index b21a915aa..3c72c9cb5 100644
--- a/arch/i386/kernel/i386_ksyms.c
+++ b/arch/i386/kernel/i386_ksyms.c
@@ -23,6 +23,11 @@
extern void dump_thread(struct pt_regs *, struct user *);
extern int dump_fpu(elf_fpregset_t *);
+#ifdef __SMP__
+extern void FASTCALL( __write_lock_failed(rwlock_t *rw));
+extern void FASTCALL( __read_lock_failed(rwlock_t *rw));
+#endif
+
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_HD) || defined(CONFIG_BLK_DEV_IDE_MODULE) || defined(CONFIG_BLK_DEV_HD_MODULE)
extern struct drive_info_struct drive_info;
EXPORT_SYMBOL(drive_info);
@@ -92,6 +97,8 @@ EXPORT_SYMBOL(__cpu_logical_map);
EXPORT_SYMBOL(smp_num_cpus);
EXPORT_SYMBOL(cpu_present_map);
EXPORT_SYMBOL(cpu_online_map);
+EXPORT_SYMBOL_NOVERS(__write_lock_failed);
+EXPORT_SYMBOL_NOVERS(__read_lock_failed);
/* Global SMP irq stuff */
EXPORT_SYMBOL(synchronize_irq);
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index 9fb8bcd3a..5ed9255f6 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -940,7 +940,7 @@ void print_all_local_APICs (void)
print_local_APIC(NULL);
}
-static void __init init_sym_mode(void)
+static void __init enable_IO_APIC(void)
{
struct IO_APIC_reg_01 reg_01;
int i;
@@ -976,31 +976,15 @@ static void __init init_sym_mode(void)
clear_IO_APIC();
}
-static void clear_lapic_ints (void * dummy)
-{
- int maxlvt;
-
- maxlvt = get_maxlvt();
- apic_write_around(APIC_LVTT, 0x00010000);
- apic_write_around(APIC_LVT0, 0x00010000);
- apic_write_around(APIC_LVT1, 0x00010000);
- if (maxlvt >= 3)
- apic_write_around(APIC_LVTERR, 0x00010000);
- if (maxlvt >= 4)
- apic_write_around(APIC_LVTPC, 0x00010000);
-}
-
/*
* Not an __init, needed by the reboot code
*/
-void init_pic_mode(void)
+void disable_IO_APIC(void)
{
/*
- * Clear the IO-APIC and local APICs before rebooting:
+ * Clear the IO-APIC before rebooting:
*/
clear_IO_APIC();
- smp_call_function(clear_lapic_ints, NULL, 1, 1);
- clear_lapic_ints(NULL);
/*
* Put it back into PIC mode (has an effect only on
@@ -1379,8 +1363,10 @@ static inline void check_timer(void)
}
printk(" failed.\n");
- if (nmi_watchdog)
- printk("timer doesnt work through the IO-APIC - cannot activate NMI Watchdog!\n");
+ if (nmi_watchdog) {
+ printk("timer doesnt work through the IO-APIC - disabling NMI Watchdog!\n");
+ nmi_watchdog = 0;
+ }
printk("...trying to set up timer as Virtual Wire IRQ...");
@@ -1417,7 +1403,7 @@ static inline void check_timer(void)
void __init setup_IO_APIC(void)
{
- init_sym_mode();
+ enable_IO_APIC();
printk("ENABLING IO-APIC IRQs\n");
io_apic_irqs = ~PIC_IRQS;
diff --git a/arch/i386/kernel/irq.c b/arch/i386/kernel/irq.c
index 1bccad67b..041e44320 100644
--- a/arch/i386/kernel/irq.c
+++ b/arch/i386/kernel/irq.c
@@ -37,7 +37,7 @@
#include <asm/system.h>
#include <asm/io.h>
#include <asm/bitops.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/delay.h>
#include <asm/desc.h>
#include <asm/irq.h>
@@ -204,13 +204,8 @@ atomic_t global_bh_lock;
*/
static inline void check_smp_invalidate(int cpu)
{
- if (test_bit(cpu, &smp_invalidate_needed)) {
- struct mm_struct *mm = current->mm;
- clear_bit(cpu, &smp_invalidate_needed);
- if (mm)
- atomic_set_mask(1 << cpu, &mm->cpu_vm_mask);
- local_flush_tlb();
- }
+ if (test_bit(cpu, &smp_invalidate_needed))
+ do_flush_tlb_local();
}
static void show(char * str)
@@ -263,7 +258,7 @@ static inline void wait_on_bh(void)
* i thought that such things are guaranteed by design, since we use
* the 'LOCK' prefix.
*/
-#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 1
+#define SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND 0
#if SUSPECTED_CPU_OR_CHIPSET_BUG_WORKAROUND
# define SYNC_OTHER_CORES(x) udelay(x+1)
diff --git a/arch/i386/kernel/mca.c b/arch/i386/kernel/mca.c
index 86fc022e6..7061e55db 100644
--- a/arch/i386/kernel/mca.c
+++ b/arch/i386/kernel/mca.c
@@ -744,11 +744,13 @@ static int mca_read_proc(char *page, char **start, off_t off,
void __init mca_do_proc_init(void)
{
int i;
+ struct proc_dir_entry *proc_mca;
struct proc_dir_entry* node = NULL;
struct MCA_adapter *p;
if(mca_info == NULL) return; /* Should never happen */
+ proc_mca = proc_mkdir("mca", &proc_root);
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);
diff --git a/arch/i386/kernel/mtrr.c b/arch/i386/kernel/mtrr.c
index 9e612451c..1c1f6b74b 100644
--- a/arch/i386/kernel/mtrr.c
+++ b/arch/i386/kernel/mtrr.c
@@ -1446,12 +1446,6 @@ static int mtrr_ioctl (struct inode *inode, struct file *file,
return 0;
} /* End Function mtrr_ioctl */
-static int mtrr_open (struct inode *ino, struct file *filep)
-{
- MOD_INC_USE_COUNT;
- return 0;
-} /* End Function mtrr_open */
-
static int mtrr_close (struct inode *ino, struct file *file)
{
int i, max;
@@ -1482,7 +1476,7 @@ static struct file_operations mtrr_fops =
NULL, /* Poll */
mtrr_ioctl, /* IOctl */
NULL, /* MMAP */
- mtrr_open, /* Open */
+ NULL, /* Open */
NULL, /* Flush */
mtrr_close, /* Release */
NULL, /* Fsync */
@@ -1494,32 +1488,9 @@ static struct file_operations mtrr_fops =
static struct inode_operations proc_mtrr_inode_operations = {
&mtrr_fops, /* default property 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 */
};
-static struct proc_dir_entry proc_root_mtrr = {
- 0, 4, "mtrr",
- S_IFREG | S_IWUSR | S_IRUGO, 1, 0, 0,
- 0, &proc_mtrr_inode_operations
-};
+static struct proc_dir_entry *proc_root_mtrr;
static void compute_ascii (void)
{
@@ -1555,7 +1526,7 @@ static void compute_ascii (void)
ascii_buf_bytes += strlen (ascii_buffer + ascii_buf_bytes);
}
}
- proc_root_mtrr.size = ascii_buf_bytes;
+ proc_root_mtrr->size = ascii_buf_bytes;
} /* End Function compute_ascii */
#endif /* CONFIG_PROC_FS */
@@ -1826,9 +1797,9 @@ int __init mtrr_init(void)
# endif /* !__SMP__ */
# ifdef CONFIG_PROC_FS
- proc_register (&proc_root, &proc_root_mtrr);
-# endif
-
+ proc_root_mtrr = create_proc_entry("mtrr", S_IWUSR|S_IRUGO, &proc_root);
+ proc_root_mtrr->ops = &proc_mtrr_inode_operations;
+#endif
init_table ();
return 0;
} /* End Function mtrr_init */
diff --git a/arch/i386/kernel/pci-i386.c b/arch/i386/kernel/pci-i386.c
index 8e609ec36..746b21258 100644
--- a/arch/i386/kernel/pci-i386.c
+++ b/arch/i386/kernel/pci-i386.c
@@ -12,7 +12,7 @@
* Hannover, Germany
* hm@ix.de
*
- * Copyright 1997--1999 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ * Copyright 1997--1999 Martin Mares <mj@suse.cz>
*
* For more information, please consult the following manuals (look at
* http://www.pcisig.com/ for how to get them):
@@ -122,12 +122,12 @@ static int __init pcibios_assign_resource(struct pci_dev *dev, int i)
printk(KERN_ERR "PCI: I/O Region %s/%d too large (%ld bytes)\n", dev->slot_name, i, size);
return -EFBIG;
}
- if (allocate_resource(pr, r, size, 0x1000, ~0, 1024)) {
+ if (allocate_resource(pr, r, size, 0x1000, ~0, 1024, NULL, NULL)) {
printk(KERN_ERR "PCI: Allocation of I/O region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size);
return -EBUSY;
}
} else {
- if (allocate_resource(pr, r, size, 0x10000000, ~0, size)) {
+ if (allocate_resource(pr, r, size, 0x10000000, ~0, size, NULL, NULL)) {
printk(KERN_ERR "PCI: Allocation of memory region %s/%d (%ld bytes) failed\n", dev->slot_name, i, size);
return -EBUSY;
}
diff --git a/arch/i386/kernel/pci-pc.c b/arch/i386/kernel/pci-pc.c
index 61d13af55..9ee1d6355 100644
--- a/arch/i386/kernel/pci-pc.c
+++ b/arch/i386/kernel/pci-pc.c
@@ -1,7 +1,7 @@
/*
* Low-Level PCI Support for PC
*
- * (c) 1999 Martin Mares <mj@ucw.cz>
+ * (c) 1999 Martin Mares <mj@suse.cz>
*/
#include <linux/config.h>
@@ -342,7 +342,7 @@ static unsigned long bios32_service(unsigned long service)
unsigned long flags;
__save_flags(flags); __cli();
- __asm__("lcall (%%edi)"
+ __asm__("lcall (%%edi); cld"
: "=a" (return_code),
"=b" (address),
"=c" (length),
@@ -383,7 +383,7 @@ static int __init check_pcibios(void)
__save_flags(flags); __cli();
__asm__(
- "lcall (%%edi)\n\t"
+ "lcall (%%edi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -404,7 +404,7 @@ static int __init check_pcibios(void)
DBG("PCI: BIOS probe returned s=%02x hw=%02x ver=%02x.%02x l=%02x\n",
status, hw_mech, major_ver, minor_ver, last_bus);
if (status || signature != PCI_SIGNATURE) {
- printk (KERN_ERR "PCI: BIOS BUG #%x[%08x] found, report to <mj@ucw.cz>\n",
+ printk (KERN_ERR "PCI: BIOS BUG #%x[%08x] found, report to <mj@suse.cz>\n",
status, signature);
return 0;
}
@@ -427,7 +427,7 @@ static int __init pci_bios_find_device (unsigned short vendor, unsigned short de
unsigned short bx;
unsigned short ret;
- __asm__("lcall (%%edi)\n\t"
+ __asm__("lcall (%%edi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -448,7 +448,7 @@ static int pci_bios_read_config_byte(struct pci_dev *dev, int where, u8 *value)
unsigned long ret;
unsigned long bx = (dev->bus->number << 8) | dev->devfn;
- __asm__("lcall (%%esi)\n\t"
+ __asm__("lcall (%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -466,7 +466,7 @@ static int pci_bios_read_config_word(struct pci_dev *dev, int where, u16 *value)
unsigned long ret;
unsigned long bx = (dev->bus->number << 8) | dev->devfn;
- __asm__("lcall (%%esi)\n\t"
+ __asm__("lcall (%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -484,7 +484,7 @@ static int pci_bios_read_config_dword(struct pci_dev *dev, int where, u32 *value
unsigned long ret;
unsigned long bx = (dev->bus->number << 8) | dev->devfn;
- __asm__("lcall (%%esi)\n\t"
+ __asm__("lcall (%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -502,7 +502,7 @@ static int pci_bios_write_config_byte(struct pci_dev *dev, int where, u8 value)
unsigned long ret;
unsigned long bx = (dev->bus->number << 8) | dev->devfn;
- __asm__("lcall (%%esi)\n\t"
+ __asm__("lcall (%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -520,7 +520,7 @@ static int pci_bios_write_config_word(struct pci_dev *dev, int where, u16 value)
unsigned long ret;
unsigned long bx = (dev->bus->number << 8) | dev->devfn;
- __asm__("lcall (%%esi)\n\t"
+ __asm__("lcall (%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -538,7 +538,7 @@ static int pci_bios_write_config_dword(struct pci_dev *dev, int where, u32 value
unsigned long ret;
unsigned long bx = (dev->bus->number << 8) | dev->devfn;
- __asm__("lcall (%%esi)\n\t"
+ __asm__("lcall (%%esi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
@@ -594,7 +594,7 @@ static struct pci_ops * __init pci_find_bios(void)
if (sum != 0)
continue;
if (check->fields.revision != 0) {
- printk("PCI: unsupported BIOS32 revision %d at 0x%p, report to <mj@ucw.cz>\n",
+ printk("PCI: unsupported BIOS32 revision %d at 0x%p, report to <mj@suse.cz>\n",
check->fields.revision, check);
continue;
}
@@ -702,7 +702,7 @@ static struct irq_routing_table * __init pcibios_get_irq_routing_table(void)
__asm__("push %%es\n\t"
"push %%ds\n\t"
"pop %%es\n\t"
- "lcall (%%esi)\n\t"
+ "lcall (%%esi); cld\n\t"
"pop %%es\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
diff --git a/arch/i386/kernel/pci-visws.c b/arch/i386/kernel/pci-visws.c
index 8a954ce8b..2ba24c8b3 100644
--- a/arch/i386/kernel/pci-visws.c
+++ b/arch/i386/kernel/pci-visws.c
@@ -1,7 +1,7 @@
/*
* Low-Level PCI Support for SGI Visual Workstation
*
- * (c) 1999 Martin Mares <mj@ucw.cz>
+ * (c) 1999 Martin Mares <mj@suse.cz>
*/
#include <linux/config.h>
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 429c4eacd..4f9c94353 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -204,9 +204,11 @@ void machine_restart(char * __unused)
{
#if __SMP__
/*
- * turn off the IO-APIC, so we can do a clean reboot
+ * Stop all CPUs and turn off local APICs and the IO-APIC, so
+ * other OSs see a clean IRQ state.
*/
- init_pic_mode();
+ smp_send_stop();
+ disable_IO_APIC();
#endif
if(!reboot_thru_bios) {
@@ -460,7 +462,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
struct pt_regs * childregs;
childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p)) - 1;
- *childregs = *regs;
+ struct_cpy(childregs, regs);
childregs->eax = 0;
childregs->esp = esp;
@@ -473,7 +475,7 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
savesegment(gs,p->thread.gs);
unlazy_fpu(current);
- p->thread.i387 = current->thread.i387;
+ struct_cpy(&p->thread.i387, &current->thread.i387);
return 0;
}
diff --git a/arch/i386/kernel/semaphore.c b/arch/i386/kernel/semaphore.c
index cf556282d..c530eece0 100644
--- a/arch/i386/kernel/semaphore.c
+++ b/arch/i386/kernel/semaphore.c
@@ -2,7 +2,17 @@
* i386 semaphore implementation.
*
* (C) Copyright 1999 Linus Torvalds
+ *
+ * Portions Copyright 1999 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * rw semaphores implemented November 1999 by Benjamin LaHaise <bcrl@redhat.com>
*/
+#include <linux/config.h>
#include <linux/sched.h>
#include <asm/semaphore.h>
@@ -218,3 +228,226 @@ asm(
"popl %eax\n\t"
"ret"
);
+
+asm(
+"
+.align 4
+.globl __down_read_failed
+__down_read_failed:
+ pushl %edx
+ pushl %ecx
+ jnc 2f
+
+3: call down_read_failed_biased
+
+1: popl %ecx
+ popl %edx
+ ret
+
+2: call down_read_failed
+ " LOCK "subl $1,(%eax)
+ jns 1b
+ jnc 2b
+ jmp 3b
+"
+);
+
+asm(
+"
+.align 4
+.globl __down_write_failed
+__down_write_failed:
+ pushl %edx
+ pushl %ecx
+ jnc 2f
+
+3: call down_write_failed_biased
+
+1: popl %ecx
+ popl %edx
+ ret
+
+2: call down_write_failed
+ " LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax)
+ jz 1b
+ jnc 2b
+ jmp 3b
+"
+);
+
+struct rw_semaphore *FASTCALL(rwsem_wake_readers(struct rw_semaphore *sem));
+struct rw_semaphore *FASTCALL(rwsem_wake_writer(struct rw_semaphore *sem));
+
+struct rw_semaphore *FASTCALL(down_read_failed_biased(struct rw_semaphore *sem));
+struct rw_semaphore *FASTCALL(down_write_failed_biased(struct rw_semaphore *sem));
+struct rw_semaphore *FASTCALL(down_read_failed(struct rw_semaphore *sem));
+struct rw_semaphore *FASTCALL(down_write_failed(struct rw_semaphore *sem));
+
+struct rw_semaphore *down_read_failed_biased(struct rw_semaphore *sem)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ add_wait_queue(&sem->wait, &wait); /* put ourselves at the head of the list */
+
+ for (;;) {
+ if (sem->read_bias_granted && xchg(&sem->read_bias_granted, 0))
+ break;
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ if (!sem->read_bias_granted)
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ return sem;
+}
+
+struct rw_semaphore *down_write_failed_biased(struct rw_semaphore *sem)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ add_wait_queue_exclusive(&sem->write_bias_wait, &wait); /* put ourselves at the end of the list */
+
+ for (;;) {
+ if (sem->write_bias_granted && xchg(&sem->write_bias_granted, 0))
+ break;
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE);
+ if (!sem->write_bias_granted)
+ schedule();
+ }
+
+ remove_wait_queue(&sem->write_bias_wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ /* if the lock is currently unbiased, awaken the sleepers
+ * FIXME: this wakes up the readers early in a bit of a
+ * stampede -> bad!
+ */
+ if (atomic_read(&sem->count) >= 0)
+ wake_up(&sem->wait);
+
+ return sem;
+}
+
+/* Wait for the lock to become unbiased. Readers
+ * are non-exclusive. =)
+ */
+struct rw_semaphore *down_read_failed(struct rw_semaphore *sem)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ __up_read(sem); /* this takes care of granting the lock */
+
+ add_wait_queue(&sem->wait, &wait);
+
+ while (atomic_read(&sem->count) < 0) {
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE);
+ if (atomic_read(&sem->count) >= 0)
+ break;
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ return sem;
+}
+
+/* Wait for the lock to become unbiased. Since we're
+ * a writer, we'll make ourselves exclusive.
+ */
+struct rw_semaphore *down_write_failed(struct rw_semaphore *sem)
+{
+ struct task_struct *tsk = current;
+ DECLARE_WAITQUEUE(wait, tsk);
+
+ __up_write(sem); /* this takes care of granting the lock */
+
+ add_wait_queue_exclusive(&sem->wait, &wait);
+
+ while (atomic_read(&sem->count) < 0) {
+ set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE);
+ if (atomic_read(&sem->count) >= 0)
+ break; /* we must attempt to aquire or bias the lock */
+ schedule();
+ }
+
+ remove_wait_queue(&sem->wait, &wait);
+ tsk->state = TASK_RUNNING;
+
+ return sem;
+}
+
+asm(
+"
+.align 4
+.globl __rwsem_wake
+__rwsem_wake:
+ pushl %edx
+ pushl %ecx
+
+ jz 1f
+ call rwsem_wake_readers
+ jmp 2f
+
+1: call rwsem_wake_writer
+
+2: popl %ecx
+ popl %edx
+ ret
+"
+);
+
+/* Called when someone has done an up that transitioned from
+ * negative to non-negative, meaning that the lock has been
+ * granted to whomever owned the bias.
+ */
+struct rw_semaphore *rwsem_wake_readers(struct rw_semaphore *sem)
+{
+ if (xchg(&sem->read_bias_granted, 1))
+ BUG();
+ wake_up(&sem->wait);
+ return sem;
+}
+
+struct rw_semaphore *rwsem_wake_writer(struct rw_semaphore *sem)
+{
+ if (xchg(&sem->write_bias_granted, 1))
+ BUG();
+ wake_up(&sem->write_bias_wait);
+ return sem;
+}
+
+#if defined(CONFIG_SMP)
+asm(
+"
+.align 4
+.globl __write_lock_failed
+__write_lock_failed:
+ " LOCK "addl $" RW_LOCK_BIAS_STR ",(%eax)
+1: cmpl $" RW_LOCK_BIAS_STR ",(%eax)
+ jne 1b
+
+ " LOCK "subl $" RW_LOCK_BIAS_STR ",(%eax)
+ jnz __write_lock_failed
+ ret
+
+
+.align 4
+.globl __read_lock_failed
+__read_lock_failed:
+ lock ; incl (%eax)
+1: cmpl $1,(%eax)
+ js 1b
+
+ lock ; decl (%eax)
+ js __read_lock_failed
+ ret
+"
+);
+#endif
+
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index e10277255..646532f86 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -286,16 +286,9 @@ struct resource standard_io_resources[] = {
#define STANDARD_IO_RESOURCES (sizeof(standard_io_resources)/sizeof(struct resource))
-/* System RAM - interrupted by the 640kB-1M hole */
-#define code_resource (ram_resources[3])
-#define data_resource (ram_resources[4])
-static struct resource ram_resources[] = {
- { "System RAM", 0x000000, 0x09ffff, IORESOURCE_BUSY },
- { "System RAM", 0x100000, 0x100000, IORESOURCE_BUSY },
- { "Video RAM area", 0x0a0000, 0x0bffff, IORESOURCE_BUSY },
- { "Kernel code", 0x100000, 0 },
- { "Kernel data", 0, 0 }
-};
+static struct resource code_resource = { "Kernel code", 0x100000, 0 };
+static struct resource data_resource = { "Kernel data", 0, 0 };
+static struct resource vram_resource = { "Video RAM area", 0xa0000, 0xbffff, IORESOURCE_BUSY };
/* System ROM resources */
#define MAXROMS 6
@@ -449,6 +442,9 @@ void __init setup_memory_region(void)
case E820_ACPI:
printk("(ACPI data)\n");
break;
+ case E820_NVS:
+ printk("(ACPI NVS)\n");
+ break;
default: printk("type %lu\n", e820.map[i].type);
break;
}
@@ -634,7 +630,6 @@ void __init setup_arch(char **cmdline_p)
highstart_pfn = highend_pfn = max_pfn;
if (max_pfn > MAXMEM_PFN) {
highstart_pfn = MAXMEM_PFN;
- highend_pfn = max_pfn;
printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
pages_to_mb(highend_pfn - highstart_pfn));
}
@@ -645,11 +640,6 @@ void __init setup_arch(char **cmdline_p)
bootmap_size = init_bootmem(start_pfn, max_low_pfn);
/*
- * FIXME: what about high memory?
- */
- ram_resources[1].end = PFN_PHYS(max_low_pfn);
-
- /*
* Register fully available low RAM pages with the bootmem allocator.
*/
for (i = 0; i < e820.nr_map; i++) {
@@ -734,15 +724,36 @@ void __init setup_arch(char **cmdline_p)
#endif
/*
- * Request the standard RAM and ROM resources -
- * they eat up PCI memory space
+ * Request address space for all standard RAM and ROM resources
+ * and also for regions reported as reserved by the e820.
*/
- request_resource(&iomem_resource, ram_resources+0);
- request_resource(&iomem_resource, ram_resources+1);
- request_resource(&iomem_resource, ram_resources+2);
- request_resource(ram_resources+1, &code_resource);
- request_resource(ram_resources+1, &data_resource);
probe_roms();
+ for (i = 0; i < e820.nr_map; i++) {
+ struct resource *res;
+ if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
+ continue;
+ res = alloc_bootmem_low(sizeof(struct resource));
+ switch (e820.map[i].type) {
+ case E820_RAM: res->name = "System RAM"; break;
+ case E820_ACPI: res->name = "ACPI Tables"; break;
+ case E820_NVS: res->name = "ACPI Non-volatile Storage"; break;
+ default: res->name = "reserved";
+ }
+ res->start = e820.map[i].addr;
+ res->end = res->start + e820.map[i].size - 1;
+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
+ request_resource(&iomem_resource, res);
+ if (e820.map[i].type == E820_RAM) {
+ /*
+ * We dont't know which RAM region contains kernel data,
+ * so we try it repeatedly and let the resource manager
+ * test it.
+ */
+ request_resource(res, &code_resource);
+ request_resource(res, &data_resource);
+ }
+ }
+ request_resource(&iomem_resource, &vram_resource);
/* request I/O space for devices used on all i[345]86 PCs */
for (i = 0; i < STANDARD_IO_RESOURCES; i++)
@@ -1360,9 +1371,9 @@ int get_cpuinfo(char * buffer)
char *p = buffer;
int sep_bug;
static char *x86_cap_flags[] = {
- "fpu", "vme", "de", "pse", "tsc", "msr", "6", "mce",
- "cx8", "9", "10", "sep", "mtrr", "pge", "14", "cmov",
- "16", "17", "psn", "19", "20", "21", "22", "mmx",
+ "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+ "cx8", "apic", "10", "sep", "mtrr", "pge", "mca", "cmov",
+ "pat", "17", "psn", "19", "20", "21", "22", "mmx",
"24", "kni", "26", "27", "28", "29", "30", "31"
};
struct cpuinfo_x86 *c = cpu_data;
@@ -1408,15 +1419,14 @@ int get_cpuinfo(char * buffer)
case X86_VENDOR_AMD:
if (c->x86 == 5 && c->x86_model == 6)
x86_cap_flags[10] = "sep";
- x86_cap_flags[16] = "fcmov";
+ if (c->x86 < 6)
+ x86_cap_flags[16] = "fcmov";
+ x86_cap_flags[22] = "mmxext";
+ x86_cap_flags[30] = "3dnowext";
x86_cap_flags[31] = "3dnow";
break;
case X86_VENDOR_INTEL:
- x86_cap_flags[6] = "pae";
- x86_cap_flags[9] = "apic";
- x86_cap_flags[14] = "mca";
- x86_cap_flags[16] = "pat";
x86_cap_flags[17] = "pse36";
x86_cap_flags[18] = "psn";
x86_cap_flags[24] = "osfxsr";
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index cc9a992da..a973746b9 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -687,6 +687,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index e2253ccca..59af7034d 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -8,7 +8,6 @@
* later.
*/
-#include <linux/config.h>
#include <linux/init.h>
#include <linux/mm.h>
@@ -19,6 +18,7 @@
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
#include <asm/mtrr.h>
+#include <asm/pgalloc.h>
/*
* Some notes on processor bugs:
@@ -102,7 +102,8 @@
/* The 'big kernel lock' */
spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED;
-volatile unsigned long smp_invalidate_needed;
+volatile unsigned long smp_invalidate_needed; /* immediate flush required */
+unsigned int cpu_tlbbad[NR_CPUS]; /* flush before returning to user space */
/*
* the following functions deal with sending IPIs between CPUs.
@@ -319,13 +320,9 @@ static void flush_tlb_others(unsigned int cpumask)
/*
* Take care of "crossing" invalidates
*/
- if (test_bit(cpu, &smp_invalidate_needed)) {
- struct mm_struct *mm = current->mm;
- clear_bit(cpu, &smp_invalidate_needed);
- if (mm)
- atomic_set_mask(1 << cpu, &mm->cpu_vm_mask);
- local_flush_tlb();
- }
+ if (test_bit(cpu, &smp_invalidate_needed))
+ do_flush_tlb_local();
+
--stuck;
if (!stuck) {
printk("stuck on TLB IPI wait (CPU#%d)\n",cpu);
@@ -345,7 +342,7 @@ static void flush_tlb_others(unsigned int cpumask)
*/
void flush_tlb_current_task(void)
{
- unsigned long vm_mask = 1 << current->processor;
+ unsigned long vm_mask = 1 << smp_processor_id();
struct mm_struct *mm = current->mm;
unsigned long cpu_mask = mm->cpu_vm_mask & ~vm_mask;
@@ -356,7 +353,7 @@ void flush_tlb_current_task(void)
void flush_tlb_mm(struct mm_struct * mm)
{
- unsigned long vm_mask = 1 << current->processor;
+ unsigned long vm_mask = 1 << smp_processor_id();
unsigned long cpu_mask = mm->cpu_vm_mask & ~vm_mask;
mm->cpu_vm_mask = 0;
@@ -369,7 +366,7 @@ void flush_tlb_mm(struct mm_struct * mm)
void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
{
- unsigned long vm_mask = 1 << current->processor;
+ unsigned long vm_mask = 1 << smp_processor_id();
struct mm_struct *mm = vma->vm_mm;
unsigned long cpu_mask = mm->cpu_vm_mask & ~vm_mask;
@@ -381,12 +378,30 @@ void flush_tlb_page(struct vm_area_struct * vma, unsigned long va)
flush_tlb_others(cpu_mask);
}
-void flush_tlb_all(void)
+static inline void do_flush_tlb_all_local(void)
{
- flush_tlb_others(~(1 << current->processor));
local_flush_tlb();
+ if (!current->mm && current->active_mm) {
+ unsigned long cpu = smp_processor_id();
+
+ clear_bit(cpu, &current->active_mm->cpu_vm_mask);
+ cpu_tlbbad[cpu] = 1;
+ }
}
+static void flush_tlb_all_ipi(void* info)
+{
+ do_flush_tlb_all_local();
+}
+
+void flush_tlb_all(void)
+{
+ if (cpu_online_map ^ (1 << smp_processor_id()))
+ while (smp_call_function (flush_tlb_all_ipi,0,0,1) == -EBUSY)
+ mb();
+
+ do_flush_tlb_all_local();
+}
/*
* this function sends a 'reschedule' IPI to another CPU.
@@ -439,9 +454,6 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
if (down_trylock(&lock))
return -EBUSY;
- if (call_data) // temporary debugging check
- BUG();
-
call_data = &data;
data.func = func;
data.info = info;
@@ -478,7 +490,8 @@ static void stop_this_cpu (void * dummy)
* Remove this CPU:
*/
clear_bit(smp_processor_id(), &cpu_online_map);
-
+ __cli();
+ disable_local_APIC();
if (cpu_data[smp_processor_id()].hlt_works_ok)
for(;;) __asm__("hlt");
for (;;);
@@ -490,7 +503,14 @@ static void stop_this_cpu (void * dummy)
void smp_send_stop(void)
{
+ unsigned long flags;
+
+ __save_flags(flags);
+ __cli();
smp_call_function(stop_this_cpu, NULL, 1, 0);
+ disable_local_APIC();
+ __restore_flags(flags);
+
}
/*
@@ -513,15 +533,9 @@ asmlinkage void smp_reschedule_interrupt(void)
*/
asmlinkage void smp_invalidate_interrupt(void)
{
- struct task_struct *tsk = current;
- unsigned int cpu = tsk->processor;
+ if (test_bit(smp_processor_id(), &smp_invalidate_needed))
+ do_flush_tlb_local();
- if (test_and_clear_bit(cpu, &smp_invalidate_needed)) {
- struct mm_struct *mm = tsk->mm;
- if (mm)
- atomic_set_mask(1 << cpu, &mm->cpu_vm_mask);
- local_flush_tlb();
- }
ack_APIC_irq();
}
@@ -539,7 +553,7 @@ asmlinkage void smp_call_function_interrupt(void)
*/
atomic_inc(&call_data->started);
/*
- * At this point the structure may be out of scope unless wait==1
+ * At this point the info structure may be out of scope unless wait==1
*/
(*func)(info);
if (wait)
@@ -561,7 +575,7 @@ asmlinkage void smp_spurious_interrupt(void)
* This interrupt should never happen with our APIC/SMP architecture
*/
-static spinlock_t err_lock;
+static spinlock_t err_lock = SPIN_LOCK_UNLOCKED;
asmlinkage void smp_error_interrupt(void)
{
@@ -575,8 +589,27 @@ asmlinkage void smp_error_interrupt(void)
printk("... APIC ESR0: %08lx\n", v);
apic_write(APIC_ESR, 0);
- v = apic_read(APIC_ESR);
+ v |= apic_read(APIC_ESR);
printk("... APIC ESR1: %08lx\n", v);
+ /*
+ * Be a bit more verbose. (multiple bits can be set)
+ */
+ if (v & 0x01)
+ printk("... bit 0: APIC Send CS Error (hw problem).\n");
+ if (v & 0x02)
+ printk("... bit 1: APIC Receive CS Error (hw problem).\n");
+ if (v & 0x04)
+ printk("... bit 2: APIC Send Accept Error.\n");
+ if (v & 0x08)
+ printk("... bit 3: APIC Receive Accept Error.\n");
+ if (v & 0x10)
+ printk("... bit 4: Reserved!.\n");
+ if (v & 0x20)
+ printk("... bit 5: Send Illegal Vector (kernel bug).\n");
+ if (v & 0x40)
+ printk("... bit 6: Received Illegal Vector.\n");
+ if (v & 0x80)
+ printk("... bit 7: Illegal Register Address.\n");
ack_APIC_irq();
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 85f439978..811f00f38 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -44,6 +44,7 @@
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
#include <asm/mtrr.h>
+#include <asm/pgalloc.h>
/* Set if we find a B stepping CPU */
static int smp_b_stepping = 0;
@@ -649,10 +650,11 @@ void __init smp_alloc_memory(void)
void __init smp_store_cpu_info(int id)
{
- struct cpuinfo_x86 *c=&cpu_data[id];
+ struct cpuinfo_x86 *c = cpu_data + id;
*c = boot_cpu_data;
c->pte_quick = 0;
+ c->pmd_quick = 0;
c->pgd_quick = 0;
c->pgtable_cache_sz = 0;
identify_cpu(c);
@@ -706,7 +708,35 @@ int get_maxlvt(void)
return maxlvt;
}
-void __init setup_local_APIC(void)
+void disable_local_APIC (void)
+{
+ unsigned long value;
+ int maxlvt;
+
+ /*
+ * Disable APIC
+ */
+ value = apic_read(APIC_SPIV);
+ value &= ~(1<<8);
+ apic_write(APIC_SPIV,value);
+
+ /*
+ * Clean APIC state for other OSs:
+ */
+ value = apic_read(APIC_SPIV);
+ value &= ~(1<<8);
+ apic_write(APIC_SPIV,value);
+ maxlvt = get_maxlvt();
+ apic_write_around(APIC_LVTT, 0x00010000);
+ apic_write_around(APIC_LVT0, 0x00010000);
+ apic_write_around(APIC_LVT1, 0x00010000);
+ if (maxlvt >= 3)
+ apic_write_around(APIC_LVTERR, 0x00010000);
+ if (maxlvt >= 4)
+ apic_write_around(APIC_LVTPC, 0x00010000);
+}
+
+void __init setup_local_APIC (void)
{
unsigned long value, ver, maxlvt;
@@ -714,11 +744,24 @@ void __init setup_local_APIC(void)
__error_in_io_apic_c();
value = apic_read(APIC_SPIV);
- value = 0xf;
/*
* Enable APIC
*/
value |= (1<<8);
+
+ /*
+ * Some unknown Intel IO/APIC (or APIC) errata is biting us with
+ * certain networking cards. If high frequency interrupts are
+ * happening on a particular IOAPIC pin, plus the IOAPIC routing
+ * entry is masked/unmasked at a high rate as well then sooner or
+ * later IOAPIC line gets 'stuck', no more interrupts are received
+ * from the device. If focus CPU is disabled then the hang goes
+ * away, oh well :-(
+ *
+ * [ This bug can be reproduced easily with a level-triggered
+ * PCI Ne2000 networking cards and PII/PIII processors, dual
+ * BX chipset. ]
+ */
#if 0
/* Enable focus processor (bit==0) */
value &= ~(1<<9);
@@ -821,8 +864,7 @@ 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 = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
- memset((void *)apic_phys, 0, PAGE_SIZE);
+ apic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
apic_phys = __pa(apic_phys);
}
set_fixmap(FIX_APIC_BASE, apic_phys);
@@ -837,8 +879,7 @@ void __init init_smp_mappings(void)
if (smp_found_config) {
ioapic_phys = mp_ioapics[i].mpc_apicaddr;
} else {
- ioapic_phys = (unsigned long)alloc_bootmem_pages(PAGE_SIZE);
- memset((void *)ioapic_phys, 0, PAGE_SIZE);
+ ioapic_phys = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
ioapic_phys = __pa(ioapic_phys);
}
set_fixmap(idx,ioapic_phys);
diff --git a/arch/i386/kernel/sys_i386.c b/arch/i386/kernel/sys_i386.c
index 289220d91..8a0c6dbda 100644
--- a/arch/i386/kernel/sys_i386.c
+++ b/arch/i386/kernel/sys_i386.c
@@ -41,6 +41,43 @@ asmlinkage int sys_pipe(unsigned long * fildes)
return error;
}
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+ unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ int error = -EBADF;
+ struct file * file = NULL;
+
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ if (!(flags & MAP_ANONYMOUS)) {
+ file = fget(fd);
+ if (!file)
+ goto out;
+ }
+
+ down(&current->mm->mmap_sem);
+ lock_kernel();
+
+ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+
+ unlock_kernel();
+ up(&current->mm->mmap_sem);
+
+ if (file)
+ fput(file);
+out:
+ return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
/*
* Perform the select(nd, in, out, ex, tv) and mmap() system
* calls. Linux/i386 didn't use to be able to handle more than
@@ -59,32 +96,22 @@ struct mmap_arg_struct {
asmlinkage int old_mmap(struct mmap_arg_struct *arg)
{
- int error = -EFAULT;
- struct file * file = NULL;
struct mmap_arg_struct a;
+ int err = -EFAULT;
if (copy_from_user(&a, arg, sizeof(a)))
- return -EFAULT;
+ goto out;
- down(&current->mm->mmap_sem);
- lock_kernel();
- if (!(a.flags & MAP_ANONYMOUS)) {
- error = -EBADF;
- file = fget(a.fd);
- if (!file)
- goto out;
- }
- a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ err = -EINVAL;
+ if (a.offset & ~PAGE_MASK)
+ goto out;
- error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
- if (file)
- fput(file);
+ err = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
out:
- unlock_kernel();
- up(&current->mm->mmap_sem);
- return error;
+ return err;
}
+
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
struct sel_arg_struct {
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index d3f0d3109..903dcf15d 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -80,8 +80,7 @@ extern rwlock_t xtime_lock;
static inline unsigned long do_fast_gettimeoffset(void)
{
- register unsigned long eax asm("ax");
- register unsigned long edx asm("dx");
+ register unsigned long eax, edx;
/* Read the Time Stamp Counter */
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index f66f2363c..063e9fefb 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -35,6 +35,7 @@
#include <asm/desc.h>
#include <asm/smp.h>
+#include <asm/pgalloc.h>
#ifdef CONFIG_X86_VISWS_APIC
#include <asm/fixmap.h>
@@ -200,7 +201,7 @@ static void show_registers(struct pt_regs *regs)
printk("\n");
}
-spinlock_t die_lock;
+spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
void die(const char * str, struct pt_regs * regs, long err)
{
@@ -387,7 +388,7 @@ inline void nmi_watchdog_tick(struct pt_regs * regs)
alert_counter[cpu]++;
if (alert_counter[cpu] == 5*HZ) {
spin_lock(&nmi_print_lock);
- spin_unlock(&console_lock); // we are in trouble anyway
+ console_lock.lock = 0; // we are in trouble anyway
printk("NMI Watchdog detected LOCKUP on CPU%d, registers:\n", cpu);
show_registers(regs);
printk("console shuts up ...\n");
diff --git a/arch/i386/kernel/visws_apic.c b/arch/i386/kernel/visws_apic.c
index 6c767d0eb..be80cd628 100644
--- a/arch/i386/kernel/visws_apic.c
+++ b/arch/i386/kernel/visws_apic.c
@@ -104,7 +104,7 @@ static struct hw_interrupt_type cobalt_irq_type = {
/*
* Not an __init, needed by the reboot code
*/
-void init_pic_mode(void)
+void disable_IO_APIC(void)
{
/* Nop on Cobalt */
}
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index 3fd5262ac..5719ecaf1 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -14,7 +14,7 @@
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/io.h>
/*
diff --git a/arch/i386/lib/usercopy.c b/arch/i386/lib/usercopy.c
index 21d8fdf62..d591e44f1 100644
--- a/arch/i386/lib/usercopy.c
+++ b/arch/i386/lib/usercopy.c
@@ -5,6 +5,7 @@
* Copyright 1997 Andi Kleen <ak@muc.de>
* Copyright 1997 Linus Torvalds
*/
+#include <linux/config.h>
#include <asm/uaccess.h>
#include <asm/mmx.h>
diff --git a/arch/i386/mm/fault.c b/arch/i386/mm/fault.c
index b2a98859b..618b36544 100644
--- a/arch/i386/mm/fault.c
+++ b/arch/i386/mm/fault.c
@@ -19,7 +19,7 @@
#include <asm/system.h>
#include <asm/uaccess.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/hardirq.h>
extern void die(const char *,struct pt_regs *,long);
diff --git a/arch/i386/mm/init.c b/arch/i386/mm/init.c
index 7a05654d8..b99daee84 100644
--- a/arch/i386/mm/init.c
+++ b/arch/i386/mm/init.c
@@ -30,6 +30,7 @@
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/dma.h>
#include <asm/fixmap.h>
#include <asm/e820.h>
@@ -75,7 +76,7 @@ static pmd_t * get_bad_pmd_table(void)
pmd_t v;
int i;
- pmd_val(v) = _PAGE_TABLE + __pa(empty_bad_pte_table);
+ set_pmd(&v, __pmd(_PAGE_TABLE + __pa(empty_bad_pte_table)));
for (i = 0; i < PAGE_SIZE/sizeof(pmd_t); i++)
empty_bad_pmd_table[i] = v;
@@ -102,13 +103,13 @@ static pte_t * get_bad_pte_table(void)
void __handle_bad_pmd(pmd_t *pmd)
{
pmd_ERROR(*pmd);
- pmd_val(*pmd) = _PAGE_TABLE + __pa(get_bad_pte_table());
+ set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(get_bad_pte_table())));
}
void __handle_bad_pmd_kernel(pmd_t *pmd)
{
pmd_ERROR(*pmd);
- pmd_val(*pmd) = _KERNPG_TABLE + __pa(get_bad_pte_table());
+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(get_bad_pte_table())));
}
pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
@@ -119,10 +120,10 @@ pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset)
if (pmd_none(*pmd)) {
if (pte) {
clear_page(pte);
- pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte);
+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
return pte + offset;
}
- pmd_val(*pmd) = _KERNPG_TABLE + __pa(get_bad_pte_table());
+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(get_bad_pte_table())));
return NULL;
}
free_page((unsigned long)pte);
@@ -141,10 +142,10 @@ pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset)
if (pmd_none(*pmd)) {
if (pte) {
clear_page((void *)pte);
- pmd_val(*pmd) = _PAGE_TABLE + __pa(pte);
+ set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte)));
return (pte_t *)pte + offset;
}
- pmd_val(*pmd) = _PAGE_TABLE + __pa(get_bad_pte_table());
+ set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(get_bad_pte_table())));
return NULL;
}
free_page(pte);
@@ -267,7 +268,7 @@ void set_fixmap (enum fixed_addresses idx, unsigned long phys)
printk("Invalid set_fixmap\n");
return;
}
- set_pte_phys (address,phys);
+ set_pte_phys(address,phys);
}
static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t *pgd_base)
@@ -285,8 +286,7 @@ static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t
#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;
+ set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
if (pmd != pmd_offset(pgd, start))
BUG();
}
@@ -297,8 +297,7 @@ static void __init fixrange_init (unsigned long start, unsigned long end, pgd_t
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);
+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
if (pte != pte_offset(pmd, 0))
BUG();
}
@@ -327,8 +326,7 @@ static void __init pagetable_init(void)
vaddr = i*PGDIR_SIZE;
#if CONFIG_X86_PAE
pmd = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- memset((void*)pmd, 0, PAGE_SIZE);
- pgd_val(*pgd) = __pa(pmd) + 0x1;
+ set_pgd(pgd, __pgd(__pa(pmd) + 0x1));
#else
pmd = (pmd_t *)pgd;
#endif
@@ -347,13 +345,12 @@ static void __init pagetable_init(void)
set_in_cr4(X86_CR4_PGE);
__pe += _PAGE_GLOBAL;
}
- pmd_val(*pmd) = __pe;
+ set_pmd(pmd, __pmd(__pe));
continue;
}
pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE);
- memset((void*)pte, 0, PAGE_SIZE);
- pmd_val(*pmd) = _KERNPG_TABLE + __pa(pte);
+ set_pmd(pmd, __pmd(_KERNPG_TABLE + __pa(pte)));
if (pte != pte_offset(pmd, 0))
BUG();
@@ -379,7 +376,7 @@ static void __init pagetable_init(void)
* Permanent kmaps:
*/
vaddr = PKMAP_BASE;
- fixrange_init(vaddr, vaddr + 4*1024*1024, pgd_base);
+ fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, pgd_base);
pgd = swapper_pg_dir + __pgd_offset(vaddr);
pmd = pmd_offset(pgd, vaddr);
@@ -412,7 +409,11 @@ void __init zap_low_mappings (void)
* that case).
*/
for (i = 0; i < USER_PTRS_PER_PGD; i++)
- pgd_val(swapper_pg_dir[i]) = 0;
+#if CONFIG_X86_PAE
+ pgd_clear(swapper_pg_dir+i);
+#else
+ set_pgd(swapper_pg_dir+i, __pgd(0));
+#endif
flush_tlb_all();
}
@@ -448,13 +449,22 @@ void __init paging_init(void)
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];
-
+ unsigned int zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned int max_dma, high, low;
+
+ max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ low = max_low_pfn;
+ high = highend_pfn;
+
+ if (low < max_dma)
+ zones_size[ZONE_DMA] = low;
+ else {
+ zones_size[ZONE_DMA] = max_dma;
+ zones_size[ZONE_NORMAL] = low - max_dma;
+#ifdef CONFIG_HIGHMEM
+ zones_size[ZONE_HIGHMEM] = high - low;
+#endif
+ }
free_area_init(zones_size);
}
return;
@@ -514,13 +524,18 @@ static inline int page_is_ram (unsigned long pagenr)
int i;
for (i = 0; i < e820.nr_map; i++) {
- unsigned long addr, size;
+ unsigned long addr, end;
if (e820.map[i].type != E820_RAM) /* not usable memory */
continue;
+ /*
+ * !!!FIXME!!! Some BIOSen report areas as RAM that
+ * are not. Notably the 640->1Mb area. We need a sanity
+ * check here.
+ */
addr = (e820.map[i].addr+PAGE_SIZE-1) >> PAGE_SHIFT;
- size = e820.map[i].size >> PAGE_SHIFT;
- if ((pagenr >= addr) && (pagenr < addr+size))
+ end = (e820.map[i].addr+e820.map[i].size) >> PAGE_SHIFT;
+ if ((pagenr >= addr) && (pagenr < end))
return 1;
}
return 0;
@@ -528,15 +543,13 @@ static inline int page_is_ram (unsigned long pagenr)
void __init mem_init(void)
{
- int codepages = 0;
- int reservedpages = 0;
- int datapages = 0;
- int initpages = 0;
-#ifdef CONFIG_HIGHMEM
+ int codesize, reservedpages, datasize, initsize;
int tmp;
if (!mem_map)
BUG();
+
+#ifdef CONFIG_HIGHMEM
highmem_start_page = mem_map + highstart_pfn;
/* cache the highmem_mapnr */
highmem_mapnr = highstart_pfn;
@@ -552,6 +565,13 @@ void __init mem_init(void)
/* this will put all low memory onto the freelists */
totalram_pages += free_all_bootmem();
+ reservedpages = 0;
+ for (tmp = 0; tmp < max_low_pfn; tmp++)
+ /*
+ * Only count reserved RAM pages
+ */
+ if (page_is_ram(tmp) && PageReserved(mem_map+tmp))
+ reservedpages++;
#ifdef CONFIG_HIGHMEM
for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
struct page *page = mem_map + tmp;
@@ -568,19 +588,23 @@ void __init mem_init(void)
}
totalram_pages += totalhigh_pages;
#endif
+ codesize = (unsigned long) &_etext - (unsigned long) &_text;
+ datasize = (unsigned long) &_edata - (unsigned long) &_etext;
+ initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
+
printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data, %dk init, %ldk highmem)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
max_mapnr << (PAGE_SHIFT-10),
- codepages << (PAGE_SHIFT-10),
+ codesize >> 10,
reservedpages << (PAGE_SHIFT-10),
- datapages << (PAGE_SHIFT-10),
- initpages << (PAGE_SHIFT-10),
+ datasize >> 10,
+ initsize >> 10,
(unsigned long) (totalhigh_pages << (PAGE_SHIFT-10))
);
#if CONFIG_X86_PAE
if (!cpu_has_pae)
- panic("cannot execute a PAE-enabled kernel on a PAE-incapable CPU!");
+ panic("cannot execute a PAE-enabled kernel on a PAE-less CPU!");
#endif
if (boot_cpu_data.wp_works_ok < 0)
test_wp_bit();
@@ -611,6 +635,19 @@ void free_initmem(void)
printk ("Freeing unused kernel memory: %dk freed\n", (&__init_end - &__init_begin) >> 10);
}
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(mem_map + MAP_NR(start));
+ set_page_count(mem_map+MAP_NR(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
void si_meminfo(struct sysinfo *val)
{
val->totalram = totalram_pages;
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index d69455310..cb4427672 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -10,6 +10,7 @@
#include <linux/vmalloc.h>
#include <asm/io.h>
+#include <asm/pgalloc.h>
static inline void remap_area_pte(pte_t * pte, unsigned long address, unsigned long size,
unsigned long phys_addr, unsigned long flags)
@@ -118,8 +119,18 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
/*
* Don't allow anybody to remap normal RAM that we're using..
*/
- if (phys_addr < virt_to_phys(high_memory))
- return NULL;
+ if (phys_addr < virt_to_phys(high_memory)) {
+ char *t_addr, *t_end;
+ int i;
+
+ t_addr = __va(phys_addr);
+ t_end = t_addr + (size - 1);
+
+ for(i = MAP_NR(t_addr); i < MAP_NR(t_end); i++) {
+ if(!PageReserved(mem_map + i))
+ return NULL;
+ }
+ }
/*
* Mappings have to be page-aligned
@@ -131,7 +142,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
/*
* Ok, go for it..
*/
- area = get_vm_area(size);
+ area = get_vm_area(size, VM_IOREMAP);
if (!area)
return NULL;
addr = area->addr;
diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c
index eabc6bc9c..471e9a85f 100644
--- a/arch/m68k/atari/stram.c
+++ b/arch/m68k/atari/stram.c
@@ -649,6 +649,7 @@ static int __init swap_init(unsigned long start_mem, unsigned long swap_data)
/* now swapping to this device ok */
p->pages = j + k;
+ swap_list_lock();
nr_swap_pages += j;
p->flags = SWP_WRITEOK;
@@ -666,6 +667,7 @@ static int __init swap_init(unsigned long start_mem, unsigned long swap_data)
} else {
swap_info[prev].next = p - swap_info;
}
+ swap_list_unlock();
printk( KERN_INFO "Using %dk (%d pages) of ST-RAM as swap space.\n",
p->pages << 2, p->pages );
@@ -924,6 +926,9 @@ static int unswap_by_read(unsigned short *map, unsigned long max,
DPRINTK("unswap: map[i=%lu]=%u nr_swap=%u\n",
i, map[i], nr_swap_pages);
+ swap_device_lock(stram_swap_info);
+ map[i]++;
+ swap_device_unlock(stram_swap_info);
/* Get a page for the entry, using the existing
swap cache page if there is one. Otherwise,
get a clean page and read the swap into it. */
@@ -945,18 +950,24 @@ static int unswap_by_read(unsigned short *map, unsigned long max,
stat_swap_force++;
#endif
}
- else if (map[i])
+ else {
+ swap_free(entry);
return -ENOMEM;
+ }
}
DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%u\n",
i, map[i], nr_swap_pages );
+ swap_list_lock();
+ swap_device_lock(stram_swap_info);
map[i] = SWAP_MAP_BAD;
if (stram_swap_info->lowest_bit == i)
stram_swap_info->lowest_bit++;
if (stram_swap_info->highest_bit == i)
stram_swap_info->highest_bit--;
--nr_swap_pages;
+ swap_device_unlock(stram_swap_info);
+ swap_list_unlock();
}
return 0;
@@ -1022,6 +1033,8 @@ static void free_stram_region( unsigned long offset, unsigned long n_pages )
return;
}
+ swap_list_lock();
+ swap_device_lock(stram_swap_info);
/* un-reserve the freed pages */
for( ; n_pages > 0; ++offset, --n_pages ) {
if (map[offset] != SWAP_MAP_BAD)
@@ -1038,6 +1051,8 @@ static void free_stram_region( unsigned long offset, unsigned long n_pages )
if (stram_swap_info->prio > swap_info[swap_list.next].prio)
swap_list.next = swap_list.head;
nr_swap_pages += n_pages;
+ swap_device_unlock(stram_swap_info);
+ swap_list_unlock();
}
diff --git a/arch/m68k/config.in b/arch/m68k/config.in
index 4888b4b48..2d6095694 100644
--- a/arch/m68k/config.in
+++ b/arch/m68k/config.in
@@ -124,6 +124,7 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
fi
fi
+source drivers/pci/Config.in
endmenu
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index f35dd94c5..81014d9c8 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -1093,6 +1093,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGIOT: case SIGFPE: case SIGSEGV:
+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */
diff --git a/arch/m68k/kernel/sun3-head.S b/arch/m68k/kernel/sun3-head.S
index fa17d83a9..66834855d 100644
--- a/arch/m68k/kernel/sun3-head.S
+++ b/arch/m68k/kernel/sun3-head.S
@@ -1,4 +1,3 @@
-#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/page.h>
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c
index a85da4e10..1387f594b 100644
--- a/arch/m68k/kernel/sys_m68k.c
+++ b/arch/m68k/kernel/sys_m68k.c
@@ -44,6 +44,43 @@ asmlinkage int sys_pipe(unsigned long * fildes)
return error;
}
+/* common code for old and new mmaps */
+static inline long do_mmap2(
+ unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ int error = -EBADF;
+ struct file * file = NULL;
+
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+ if (!(flags & MAP_ANONYMOUS)) {
+ file = fget(fd);
+ if (!file)
+ goto out;
+ }
+
+ down(&current->mm->mmap_sem);
+ lock_kernel();
+
+ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+
+ unlock_kernel();
+ up(&current->mm->mmap_sem);
+
+ if (file)
+ fput(file);
+out:
+ return error;
+}
+
+asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, unsigned long pgoff)
+{
+ return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
/*
* Perform the select(nd, in, out, ex, tv) and mmap() system
* calls. Linux/m68k cloned Linux/i386, which didn't use to be able to
@@ -62,13 +99,49 @@ struct mmap_arg_struct {
asmlinkage int old_mmap(struct mmap_arg_struct *arg)
{
- int error;
- struct file * file = NULL;
struct mmap_arg_struct a;
+ int error = -EFAULT;
+
+ if (copy_from_user(&a, arg, sizeof(a)))
+ goto out;
+
+ error = -EINVAL;
+ if (a.offset & ~PAGE_MASK)
+ goto out;
+
+ a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+ error = do_mmap2(file, a.addr, a.len, a.prot, a.flags, a.offset >> PAGE_SHIFT);
+out:
+ return error;
+}
+
+struct mmap_arg_struct64 {
+ __u32 addr;
+ __u32 len;
+ __u32 prot;
+ __u32 flags;
+ __u64 offset; /* 64 bits */
+ __u32 fd;
+};
+
+asmlinkage long sys_mmap64(struct mmap_arg_struct64 *arg)
+{
+ int error = -EFAULT;
+ struct file * file = NULL;
+ struct mmap_arg_struct64 a;
+ unsigned long pgoff;
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
+ if ((long)a.offset & ~PAGE_MASK)
+ return -EINVAL;
+
+ pgoff = a.offset >> PAGE_SHIFT;
+ if ((a.offset >> PAGE_SHIFT) != pgoff)
+ return -EINVAL;
+
down(&current->mm->mmap_sem);
lock_kernel();
if (!(a.flags & MAP_ANONYMOUS)) {
@@ -79,7 +152,7 @@ asmlinkage int old_mmap(struct mmap_arg_struct *arg)
}
a.flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- error = do_mmap(file, a.addr, a.len, a.prot, a.flags, a.offset);
+ error = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, pgoff);
if (file)
fput(file);
out:
@@ -88,7 +161,6 @@ out:
return error;
}
-
extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
struct sel_arg_struct {
@@ -103,7 +175,7 @@ asmlinkage int old_select(struct sel_arg_struct *arg)
if (copy_from_user(&a, arg, sizeof(a)))
return -EFAULT;
- /* sys_select() does the appropriate kernel locking */
+ /* sys_select() does the appropriate kernel locking */
return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
}
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c
index 26a0518db..21969ce6f 100644
--- a/arch/m68k/mac/iop.c
+++ b/arch/m68k/mac/iop.c
@@ -51,6 +51,9 @@
* IOP hasn't died.
* o Some of the IOP manager routines need better error checking and
* return codes. Nothing major, just prettying up.
+ *
+ * + share the stuff you were smoking when you wrote the iop_get_proc_info()
+ * for case when CONFIG_PROC_FS is undefined.
*/
/*
@@ -125,9 +128,10 @@
int iop_scc_present,iop_ism_present;
#ifdef CONFIG_PROC_FS
-static int iop_get_proc_info(char *, char **, off_t, int, int);
+static int iop_get_proc_info(char *, char **, off_t, int);
#else
-static int iop_get_proc_info(char *, char **, off_t, int, int) {}
+/* What the bloody hell is THAT ??? */
+static int iop_get_proc_info(char *, char **, off_t, int) {}
#endif /* CONFIG_PROC_FS */
/* structure for tracking channel listeners */
@@ -670,7 +674,7 @@ int iop_dump_one_iop(char *buf, int iop_num, char *iop_name)
return len;
}
-int iop_get_proc_info(char *buf, char **start, off_t pos, int count, int wr)
+static int iop_get_proc_info(char *buf, char **start, off_t pos, int count)
{
int len, cnt;
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index 0068effa5..a795d82ed 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -115,7 +115,6 @@
* the SCC ourselves and only call the handler for the appopriate channel.
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c
index 122659555..45825b113 100644
--- a/arch/m68k/mac/psc.c
+++ b/arch/m68k/mac/psc.c
@@ -13,7 +13,6 @@
* they aren't actually interrupt lines but data lines (to the DSP?)
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/mm.h>
diff --git a/arch/m68k/math-emu/fp_entry.S b/arch/m68k/math-emu/fp_entry.S
index f2e699c8c..55088e8e8 100644
--- a/arch/m68k/math-emu/fp_entry.S
+++ b/arch/m68k/math-emu/fp_entry.S
@@ -35,6 +35,7 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/entry.h>
diff --git a/arch/m68k/math-emu/fp_util.S b/arch/m68k/math-emu/fp_util.S
index 7356a4a55..a909d813b 100644
--- a/arch/m68k/math-emu/fp_util.S
+++ b/arch/m68k/math-emu/fp_util.S
@@ -35,6 +35,7 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <linux/config.h>
#include "fp_emu.h"
/*
diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index 60912a5b7..86041c373 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -39,7 +39,7 @@
static inline struct vm_struct *get_io_area(unsigned long size)
{
- return get_vm_area(size);
+ return get_vm_area(size, VM_IOREMAP);
}
diff --git a/arch/m68k/sun3/prom/console.c b/arch/m68k/sun3/prom/console.c
index cf5cdc24e..5ec12de10 100644
--- a/arch/m68k/sun3/prom/console.c
+++ b/arch/m68k/sun3/prom/console.c
@@ -5,7 +5,6 @@
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
diff --git a/arch/m68k/sun3/prom/misc.c b/arch/m68k/sun3/prom/misc.c
index 97036f37d..1d19e8d49 100644
--- a/arch/m68k/sun3/prom/misc.c
+++ b/arch/m68k/sun3/prom/misc.c
@@ -5,7 +5,6 @@
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 687b51556..99f57b65f 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -6,7 +6,6 @@
* for more details.
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
diff --git a/arch/mips/baget/irq.c b/arch/mips/baget/irq.c
index 8302faf5a..cd12ea66a 100644
--- a/arch/mips/baget/irq.c
+++ b/arch/mips/baget/irq.c
@@ -5,7 +5,7 @@
* Code (mostly sleleton and comments) derived from DECstation IRQ
* handling.
*
- * $Id: irq.c,v 1.4 1999/10/09 00:00:57 ralf Exp $
+ * $Id: irq.c,v 1.5 1999/12/04 03:58:59 ralf Exp $
*/
#include <linux/errno.h>
#include <linux/init.h>
@@ -182,7 +182,7 @@ static void do_IRQ(int irq, struct pt_regs * regs)
int do_random, cpu;
cpu = smp_processor_id();
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[cpu][irq]++;
mask_irq(irq);
@@ -204,7 +204,7 @@ static void do_IRQ(int irq, struct pt_regs * regs)
printk("do_IRQ: Unregistered IRQ (0x%X) occured\n", irq);
}
unmask_irq(irq);
- hardirq_exit(cpu);
+ irq_exit(cpu);
/* unmasking and bottom half handling is done magically for us. */
}
diff --git a/arch/mips/config.in b/arch/mips/config.in
index c6a6bd704..8cfe976e9 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.36 2000/01/27 23:45:24 ralf Exp $
+# $Id: config.in,v 1.37 2000/01/29 01:41:59 ralf Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
@@ -124,6 +124,10 @@ define_bool CONFIG_BINFMT_ELF y
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
bool 'Networking support' CONFIG_NET
+
+source drivers/pci/Config.in
+source drivers/pcmcia/Config.in
+
bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
bool 'Sysctl support' CONFIG_SYSCTL
@@ -141,6 +145,8 @@ if [ "$CONFIG_MODULES" = "y" ]; then
bool ' Kernel module loader' CONFIG_KMOD
fi
+source drivers/pci/Config.in
+
endmenu
if [ "$CONFIG_DECSTATION" = "y" ]; then
diff --git a/arch/mips/dec/irq.c b/arch/mips/dec/irq.c
index c60047a41..b6841cb55 100644
--- a/arch/mips/dec/irq.c
+++ b/arch/mips/dec/irq.c
@@ -4,7 +4,7 @@
* Copyright (C) 1992 Linus Torvalds
* Copyright (C) 1994, 1995, 1996, 1997 Ralf Baechle
*
- * $Id: irq.c,v 1.4 1999/10/09 00:00:57 ralf Exp $
+ * $Id: irq.c,v 1.5 1999/12/04 03:58:59 ralf Exp $
*/
#include <linux/errno.h>
#include <linux/init.h>
@@ -127,7 +127,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
int do_random, cpu;
cpu = smp_processor_id();
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[cpu][irq]++;
mask_irq(irq);
@@ -147,7 +147,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs *regs)
unmask_irq(irq);
__cli();
}
- hardirq_exit(cpu);
+ irq_exit(cpu);
/* unmasking and bottom half handling is done magically for us. */
}
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index 48c4298cb..d64e49531 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -47,6 +47,11 @@ CONFIG_FORWARD_KEYBOARD=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
CONFIG_NET=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
CONFIG_SYSCTL=y
@@ -201,6 +206,11 @@ CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
# CONFIG_QIC02_TAPE is not set
#
@@ -214,11 +224,6 @@ CONFIG_PSMOUSE=y
# Video For Linux
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -228,14 +233,11 @@ CONFIG_PSMOUSE=y
#
# CONFIG_FTAPE is not set
# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_AGP is not set
#
-# PCMCIA character device support
-#
-# CONFIG_PCMCIA_SERIAL_CS is not set
-
-#
-# USB drivers - not for the faint of heart
+# Support for USB
#
# CONFIG_USB is not set
@@ -260,7 +262,6 @@ CONFIG_AUTOFS_FS=y
# CONFIG_EFS_FS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
-# CONFIG_UDF_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -269,6 +270,7 @@ CONFIG_PROC_FS=y
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
# CONFIG_UFS_FS is not set
#
@@ -278,7 +280,7 @@ CONFIG_EXT2_FS=y
CONFIG_NFS_FS=y
CONFIG_ROOT_NFS=y
CONFIG_NFSD=y
-# CONFIG_NFSD_SUN is not set
+# CONFIG_NFSD_V3 is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
# CONFIG_SMB_FS is not set
@@ -289,9 +291,6 @@ CONFIG_LOCKD=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
CONFIG_SGI_PARTITION=y
# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 080e08cfb..b0225f750 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -1,4 +1,4 @@
-/* $Id: irixelf.c,v 1.22 1999/10/09 00:00:58 ralf Exp $
+/* $Id: irixelf.c,v 1.23 2000/01/29 01:41:59 ralf Exp $
*
* irixelf.c: Code to load IRIX ELF executables which conform to
* the MIPS ABI.
@@ -31,7 +31,7 @@
#include <linux/elfcore.h>
#include <asm/uaccess.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/mipsregs.h>
#include <asm/prctl.h>
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 88cdb7bf5..92d125137 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.17 1999/12/04 03:59:00 ralf Exp $
+/* $Id: irq.c,v 1.18 2000/01/26 00:07:44 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
@@ -146,7 +146,7 @@ asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs)
int do_random, cpu;
cpu = smp_processor_id();
- hardirq_enter(cpu);
+ irq_enter(cpu);
if (irq >= 16)
goto out;
@@ -174,7 +174,7 @@ asmlinkage void i8259_do_irq(int irq, struct pt_regs *regs)
unmask_irq (irq);
out:
- hardirq_exit(cpu);
+ irq_exit(cpu);
}
/*
@@ -190,7 +190,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
int do_random, cpu;
cpu = smp_processor_id();
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[cpu][irq]++;
action = *(irq + irq_action);
@@ -208,7 +208,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
add_interrupt_randomness(irq);
__cli();
}
- hardirq_exit(cpu);
+ irq_exit(cpu);
/* unmasking and bottom half handling is done magically for us. */
}
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c
index 74d7373d4..57e9bedfb 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.22 1999/12/04 03:59:00 ralf Exp $
+/* $Id: mips_ksyms.c,v 1.23 2000/01/29 01:41:59 ralf Exp $
*
* Export MIPS-specific functions needed for loadable modules.
*
@@ -22,7 +22,7 @@
#include <asm/floppy.h>
#include <asm/io.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/sgi/sgihpc.h>
#include <asm/softirq.h>
#include <asm/uaccess.h>
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 92df924a5..5142258a3 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.22 1999/09/28 22:25:48 ralf Exp $
+/* $Id: signal.c,v 1.23 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
@@ -618,7 +618,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- case SIGBUS:
+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index fbf2539c5..0f5124280 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -1,4 +1,4 @@
-/* $Id: syscall.c,v 1.11 1999/10/09 00:00:58 ralf Exp $
+/* $Id: syscall.c,v 1.12 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
@@ -55,32 +55,48 @@ out:
return res;
}
-asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, int prot,
- int flags, int fd, off_t offset)
+/* common code for old and new mmaps */
+static inline long
+do_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+ unsigned long flags, unsigned long fd, unsigned long pgoff)
{
+ int error = -EBADF;
struct file * file = NULL;
- unsigned long error = -EFAULT;
- down(&current->mm->mmap_sem);
- lock_kernel();
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
if (!(flags & MAP_ANONYMOUS)) {
- error = -EBADF;
file = fget(fd);
if (!file)
goto out;
}
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
- error = do_mmap(file, addr, len, prot, flags, offset);
- if (file)
- fput(file);
-out:
+ down(&current->mm->mmap_sem);
+ lock_kernel();
+
+ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+
unlock_kernel();
up(&current->mm->mmap_sem);
+ if (file)
+ fput(file);
+out:
return error;
}
+asmlinkage unsigned long old_mmap(unsigned long addr, size_t len, int prot,
+ int flags, int fd, off_t offset)
+{
+ return do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+}
+
+asmlinkage long
+sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot,
+ unsigned long flags, unsigned long fd, unsigned long pgoff)
+{
+ return do_mmap2(addr, len, prot, flags, fd, pgoff);
+}
+
asmlinkage int sys_fork(struct pt_regs regs)
{
int res;
diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h
index 7dd03b640..be6f4691a 100644
--- a/arch/mips/kernel/syscalls.h
+++ b/arch/mips/kernel/syscalls.h
@@ -1,4 +1,4 @@
-/* $Id: syscalls.h,v 1.18 1999/10/09 00:00:58 ralf Exp $
+/* $Id: syscalls.h,v 1.19 2000/01/29 01:41:59 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_old_getrlimit, 2)
+SYS(sys_getrlimit, 2)
SYS(sys_getrusage, 2)
SYS(sys_gettimeofday, 2)
SYS(sys_settimeofday, 2)
@@ -105,7 +105,7 @@ SYS(sys_uselib, 1)
SYS(sys_swapon, 2)
SYS(sys_reboot, 3)
SYS(old_readdir, 3)
-SYS(sys_mmap, 6) /* 4090 */
+SYS(old_mmap, 6) /* 4090 */
SYS(sys_munmap, 2)
SYS(sys_truncate, 2)
SYS(sys_ftruncate, 2)
@@ -225,4 +225,6 @@ SYS(sys_sigaltstack, 0)
SYS(sys_sendfile, 3)
SYS(sys_ni_syscall, 0)
SYS(sys_ni_syscall, 0)
-SYS(sys_getrlimit, 2) /* 4210 */
+SYS(sys_mmap2, 6) /* 4210 */
+SYS(sys_truncate64, 2)
+SYS(sys_ftruncate64, 2)
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c
index db3a04665..acec2b569 100644
--- a/arch/mips/kernel/sysirix.c
+++ b/arch/mips/kernel/sysirix.c
@@ -1,4 +1,4 @@
-/* $Id: sysirix.c,v 1.21 1999/10/09 00:00:58 ralf Exp $
+/* $Id: sysirix.c,v 1.22 1999/12/04 03:59:00 ralf Exp $
*
* sysirix.c: IRIX system call emulation.
*
@@ -1103,21 +1103,20 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
struct file *file = NULL;
unsigned long retval;
- down(&current->mm->mmap_sem);
lock_kernel();
- if(!(flags & MAP_ANONYMOUS)) {
- if(!(file = fget(fd))) {
+ if (!(flags & MAP_ANONYMOUS)) {
+ if (!(file = fget(fd))) {
retval = -EBADF;
goto out;
}
/* Ok, bad taste hack follows, try to think in something else
* when reading this. */
- if (flags & IRIX_MAP_AUTOGROW){
+ if (flags & IRIX_MAP_AUTOGROW) {
unsigned long old_pos;
long max_size = offset + len;
- if (max_size > file->f_dentry->d_inode->i_size){
+ if (max_size > file->f_dentry->d_inode->i_size) {
old_pos = sys_lseek (fd, max_size - 1, 0);
sys_write (fd, "", 1);
sys_lseek (fd, old_pos, 0);
@@ -1133,7 +1132,6 @@ asmlinkage unsigned long irix_mmap32(unsigned long addr, size_t len, int prot,
out:
unlock_kernel();
- up(&current->mm->mmap_sem);
return retval;
}
@@ -1693,10 +1691,9 @@ sys_mmap(unsigned long addr, size_t len, int prot, int flags, int fd,
asmlinkage int irix_mmap64(struct pt_regs *regs)
{
int len, prot, flags, fd, off1, off2, error, base = 0;
- unsigned long addr, *sp;
- struct file *file;
+ unsigned long addr, pgoff, *sp;
+ struct file *file = NULL;
- down(&current->mm->mmap_sem);
lock_kernel();
if (regs->regs[2] == 1000)
base = 1;
@@ -1721,34 +1718,46 @@ asmlinkage int irix_mmap64(struct pt_regs *regs)
__get_user(off1, &sp[2]);
__get_user(off2, &sp[3]);
}
- if (off1) {
- error = -EINVAL;
+
+ if (off1 & PAGE_MASK) {
+ error = -EOVERFLOW;
goto out;
}
+ pgoff = (off1 << (32 - PAGE_SHIFT)) | (off2 >> PAGE_SHIFT);
+
if (!(flags & MAP_ANONYMOUS)) {
- if(!(file = fcheck(fd))) {
+ if (!(file = fcheck(fd))) {
error = -EBADF;
goto out;
}
- /* Ok, bad taste hack follows, try to think in something else when reading this */
- if (flags & IRIX_MAP_AUTOGROW){
+ /* Ok, bad taste hack follows, try to think in something else
+ when reading this */
+ if (flags & IRIX_MAP_AUTOGROW) {
unsigned long old_pos;
long max_size = off2 + len;
- if (max_size > file->f_dentry->d_inode->i_size){
+ if (max_size > file->f_dentry->d_inode->i_size) {
old_pos = sys_lseek (fd, max_size - 1, 0);
sys_write (fd, "", 1);
sys_lseek (fd, old_pos, 0);
}
}
}
-
- error = sys_mmap(addr, (size_t) len, prot, flags, fd, off2);
+
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
+
+ down(&current->mm->mmap_sem);
+ error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+ up(&current->mm->mmap_sem);
+
+ if (file)
+ fput(file);
out:
unlock_kernel();
+
return error;
}
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index a6416c4ca..cfcfc9c8b 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.13 1999/10/09 00:00:58 ralf Exp $
+/* $Id: fault.c,v 1.14 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
@@ -21,7 +21,7 @@
#include <linux/version.h>
#include <asm/hardirq.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#include <asm/softirq.h>
#include <asm/system.h>
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index afd1c6b70..8420085e0 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.23 2000/01/27 23:45:25 ralf Exp $
+/* $Id: init.c,v 1.24 2000/01/29 01:41:59 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
@@ -33,6 +33,7 @@
#include <asm/jazzdma.h>
#include <asm/system.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#ifdef CONFIG_SGI_IP22
#include <asm/sgialib.h>
#endif
@@ -249,15 +250,22 @@ extern char __init_begin, __init_end;
void __init paging_init(void)
{
- unsigned int zones_size[2];
+ unsigned int zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned long max_dma, low;
/* 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];
+ max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ low = max_low_pfn;
+
+ if (low < max_dma)
+ zones_size[ZONE_DMA] = low;
+ else {
+ zones_size[ZONE_DMA] = max_dma;
+ zones_size[ZONE_NORMAL] = low - max_dma;
+ }
free_area_init(zones_size);
}
@@ -287,7 +295,7 @@ void __init mem_init(void)
datasize = (unsigned long) &_edata - (unsigned long) &_fdata;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
- printk("Memory: %uk/%luk available (%ldk kernel code, %ldk reserved, "
+ printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
"%ldk data, %ldk init)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
ram << (PAGE_SHIFT-10),
@@ -297,6 +305,19 @@ void __init mem_init(void)
initsize >> 10);
}
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(mem_map + MAP_NR(start));
+ set_page_count(mem_map+MAP_NR(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
extern char __init_begin, __init_end;
extern void prom_free_prom_memory(void);
diff --git a/arch/mips/mm/umap.c b/arch/mips/mm/umap.c
index 3ca4424eb..2024e9dce 100644
--- a/arch/mips/mm/umap.c
+++ b/arch/mips/mm/umap.c
@@ -26,7 +26,7 @@
#include <linux/swap.h>
#include <asm/system.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/page.h>
static inline void
diff --git a/arch/mips/sgi/kernel/indy_int.c b/arch/mips/sgi/kernel/indy_int.c
index 971cbdcea..916b0873a 100644
--- a/arch/mips/sgi/kernel/indy_int.c
+++ b/arch/mips/sgi/kernel/indy_int.c
@@ -1,4 +1,4 @@
-/* $Id: indy_int.c,v 1.15 1999/10/21 00:23:05 ralf Exp $
+/* $Id: indy_int.c,v 1.16 1999/12/04 03:59:00 ralf Exp $
*
* indy_int.c: Routines for generic manipulation of the INT[23] ASIC
* found on INDY workstations..
@@ -272,7 +272,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
int do_random, cpu;
cpu = smp_processor_id();
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[0][irq]++;
printk("Got irq %d, press a key.", irq);
@@ -308,7 +308,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
add_interrupt_randomness(irq);
__cli();
}
- hardirq_exit(cpu);
+ irq_exit(cpu);
/* unmasking and bottom half handling is done magically for us. */
}
@@ -451,10 +451,10 @@ void indy_local0_irqdispatch(struct pt_regs *regs)
/* if action == NULL, then we do have a handler for the irq */
if ( action == NULL ) { goto no_handler; }
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[0][irq + 16]++;
action->handler(irq, action->dev_id, regs);
- hardirq_exit(cpu);
+ irq_exit(cpu);
goto end;
no_handler:
@@ -489,10 +489,10 @@ void indy_local1_irqdispatch(struct pt_regs *regs)
/* if action == NULL, then we do have a handler for the irq */
if ( action == NULL ) { goto no_handler; }
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[0][irq + 24]++;
action->handler(irq, action->dev_id, regs);
- hardirq_exit(cpu);
+ irq_exit(cpu);
goto end;
no_handler:
@@ -507,13 +507,13 @@ void indy_buserror_irq(struct pt_regs *regs)
int cpu = smp_processor_id();
int irq = 6;
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[0][irq]++;
printk("Got a bus error IRQ, shouldn't happen yet\n");
show_regs(regs);
printk("Spinning...\n");
while(1);
- hardirq_exit(cpu);
+ irq_exit(cpu);
}
/* Misc. crap just to keep the kernel linking... */
diff --git a/arch/mips/sgi/kernel/indy_timer.c b/arch/mips/sgi/kernel/indy_timer.c
index 00c1c3c68..3306cdc25 100644
--- a/arch/mips/sgi/kernel/indy_timer.c
+++ b/arch/mips/sgi/kernel/indy_timer.c
@@ -1,4 +1,4 @@
-/* $Id: indy_timer.c,v 1.16 2000/01/17 23:32:46 ralf Exp $
+/* $Id: indy_timer.c,v 1.17 2000/01/21 22:34:03 ralf Exp $
*
* indy_timer.c: Setting up the clock on the INDY 8254 controller.
*
@@ -269,12 +269,12 @@ void indy_8254timer_irq(void)
int cpu = smp_processor_id();
int irq = 4;
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[0][irq]++;
printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
prom_getchar();
prom_imode();
- hardirq_exit(cpu);
+ irq_exit(cpu);
}
void do_gettimeofday(struct timeval *tv)
diff --git a/arch/mips64/config.in b/arch/mips64/config.in
index dafaf16c8..c1c3d59cf 100644
--- a/arch/mips64/config.in
+++ b/arch/mips64/config.in
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.9 2000/01/29 01:41:59 ralf Exp $
+# $Id: config.in,v 1.10 2000/01/31 21:57:09 kanoj Exp $
#
# For a description of the syntax of this configuration file,
# see the Configure script.
@@ -72,6 +72,10 @@ fi
bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
bool 'Networking support' CONFIG_NET
+
+source drivers/pci/Config.in
+source drivers/pcmcia/Config.in
+
bool 'System V IPC' CONFIG_SYSVIPC
bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
bool 'Sysctl support' CONFIG_SYSCTL
@@ -90,6 +94,8 @@ if [ "$CONFIG_MODULES" = "y" ]; then
bool 'Kernel module loader' CONFIG_KMOD
fi
+source drivers/pci/Config.in
+
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'Support for frame buffer devices (EXPERIMENTAL)' CONFIG_FB
fi
diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig
index 2c16a969c..5d6d9f3d5 100644
--- a/arch/mips64/defconfig
+++ b/arch/mips64/defconfig
@@ -35,6 +35,12 @@ CONFIG_CPU_R10000=y
# CONFIG_MIPS_INSANE_LARGE is not set
# CONFIG_CPU_LITTLE_ENDIAN is not set
CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_SYSCTL is not set
@@ -47,6 +53,7 @@ CONFIG_BINFMT_ELF32=y
# Loadable module support
#
# CONFIG_MODULES is not set
+CONFIG_PCI_NAMES=y
#
# Block devices
@@ -205,6 +212,12 @@ CONFIG_SGI_IOC3_ETH=y
# CONFIG_NET_ISA is not set
# CONFIG_NET_EISA is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
@@ -227,11 +240,6 @@ CONFIG_SGI_IOC3_ETH=y
# CONFIG_WAN is not set
#
-# PCMCIA network device support
-#
-# CONFIG_NET_PCMCIA is not set
-
-#
# Amateur Radio support
#
# CONFIG_HAMRADIO is not set
@@ -281,11 +289,6 @@ CONFIG_SERIAL_CONSOLE=y
# Video For Linux
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -294,9 +297,11 @@ CONFIG_SERIAL_CONSOLE=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
#
-# USB drivers - not for the faint of heart
+# Support for USB
#
# CONFIG_USB is not set
@@ -306,14 +311,12 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
-# CONFIG_UDF_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -321,6 +324,7 @@ CONFIG_PROC_FS=y
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
# CONFIG_UFS_FS is not set
#
@@ -340,9 +344,6 @@ CONFIG_LOCKD=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
CONFIG_SGI_PARTITION=y
# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
diff --git a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22
index fb7026b19..ebd6cb9d1 100644
--- a/arch/mips64/defconfig-ip22
+++ b/arch/mips64/defconfig-ip22
@@ -32,6 +32,11 @@ CONFIG_CPU_R5000=y
#
# CONFIG_CPU_LITTLE_ENDIAN is not set
CONFIG_NET=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_SYSCTL is not set
@@ -130,6 +135,12 @@ CONFIG_NETDEVICES=y
# Ethernet (10 or 100Mbit)
#
# CONFIG_NET_ETHERNET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
@@ -150,11 +161,6 @@ CONFIG_NETDEVICES=y
# Wan interfaces
#
# CONFIG_WAN is not set
-
-#
-# PCMCIA network device support
-#
-# CONFIG_NET_PCMCIA is not set
CONFIG_SGISEEQ=y
#
@@ -194,6 +200,11 @@ CONFIG_VT_CONSOLE=y
#
# CONFIG_BUSMOUSE is not set
# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
# CONFIG_QIC02_TAPE is not set
#
@@ -207,11 +218,6 @@ CONFIG_VT_CONSOLE=y
# Video For Linux
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -220,13 +226,11 @@ CONFIG_VT_CONSOLE=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
#
-# PCMCIA character device support
-#
-
-#
-# USB drivers - not for the faint of heart
+# Support for USB
#
# CONFIG_USB is not set
@@ -236,14 +240,12 @@ CONFIG_VT_CONSOLE=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
-# CONFIG_UDF_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -251,6 +253,7 @@ CONFIG_PROC_FS=y
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
# CONFIG_UFS_FS is not set
#
@@ -270,9 +273,6 @@ CONFIG_LOCKD=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
CONFIG_SGI_PARTITION=y
# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27
index 2c16a969c..5d6d9f3d5 100644
--- a/arch/mips64/defconfig-ip27
+++ b/arch/mips64/defconfig-ip27
@@ -35,6 +35,12 @@ CONFIG_CPU_R10000=y
# CONFIG_MIPS_INSANE_LARGE is not set
# CONFIG_CPU_LITTLE_ENDIAN is not set
CONFIG_NET=y
+CONFIG_PCI_NAMES=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_SYSCTL is not set
@@ -47,6 +53,7 @@ CONFIG_BINFMT_ELF32=y
# Loadable module support
#
# CONFIG_MODULES is not set
+CONFIG_PCI_NAMES=y
#
# Block devices
@@ -205,6 +212,12 @@ CONFIG_SGI_IOC3_ETH=y
# CONFIG_NET_ISA is not set
# CONFIG_NET_EISA is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_PLIP is not set
# CONFIG_PPP is not set
@@ -227,11 +240,6 @@ CONFIG_SGI_IOC3_ETH=y
# CONFIG_WAN is not set
#
-# PCMCIA network device support
-#
-# CONFIG_NET_PCMCIA is not set
-
-#
# Amateur Radio support
#
# CONFIG_HAMRADIO is not set
@@ -281,11 +289,6 @@ CONFIG_SERIAL_CONSOLE=y
# Video For Linux
#
# CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -294,9 +297,11 @@ CONFIG_SERIAL_CONSOLE=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
#
-# USB drivers - not for the faint of heart
+# Support for USB
#
# CONFIG_USB is not set
@@ -306,14 +311,12 @@ CONFIG_SERIAL_CONSOLE=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
# CONFIG_AFFS_FS is not set
-# CONFIG_HFS_FS is not set
# CONFIG_FAT_FS is not set
# CONFIG_MSDOS_FS is not set
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_ISO9660_FS is not set
# CONFIG_JOLIET is not set
-# CONFIG_UDF_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_NTFS_FS is not set
# CONFIG_HPFS_FS is not set
@@ -321,6 +324,7 @@ CONFIG_PROC_FS=y
# CONFIG_ROMFS_FS is not set
CONFIG_EXT2_FS=y
# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
# CONFIG_UFS_FS is not set
#
@@ -340,9 +344,6 @@ CONFIG_LOCKD=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
CONFIG_SGI_PARTITION=y
# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
diff --git a/arch/mips64/kernel/mips64_ksyms.c b/arch/mips64/kernel/mips64_ksyms.c
index d0647e4c5..4fc755e39 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.5 2000/01/17 23:32:46 ralf Exp $
+/* $Id: mips64_ksyms.c,v 1.6 2000/01/29 01:41:59 ralf Exp $
*
* Export MIPS64-specific functions needed for loadable modules.
*
@@ -23,7 +23,7 @@
#include <asm/floppy.h>
#include <asm/io.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/softirq.h>
#include <asm/uaccess.h>
diff --git a/arch/mips64/kernel/scall_o32.S b/arch/mips64/kernel/scall_o32.S
index f33a4afb2..f7490a4be 100644
--- a/arch/mips64/kernel/scall_o32.S
+++ b/arch/mips64/kernel/scall_o32.S
@@ -1,4 +1,4 @@
-/* $Id: scall_o32.S,v 1.3 2000/01/17 23:32:46 ralf Exp $
+/* $Id: scall_o32.S,v 1.4 2000/01/29 01:41:59 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
@@ -402,6 +402,9 @@ illegal_syscall:
sys sys_ni_syscall 0
sys sys_ni_syscall 0
sys sys_getrlimit 2 /* 4210 */
+ sys sys_mmap2 6
+ sys sys_truncate64 2
+ sys sys_ftruncate64 2
.endm
.macro sys function, nargs
diff --git a/arch/mips64/kernel/setup.c b/arch/mips64/kernel/setup.c
index 35e5cb1dd..b42271b47 100644
--- a/arch/mips64/kernel/setup.c
+++ b/arch/mips64/kernel/setup.c
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.3 1999/10/19 20:51:46 ralf Exp $
+/* $Id: setup.c,v 1.6 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
@@ -93,7 +93,6 @@ unsigned char aux_device_present;
extern int _end;
extern void load_mmu(void);
-extern char empty_zero_page[PAGE_SIZE];
static char command_line[CL_SIZE] = { 0, };
char saved_command_line[CL_SIZE];
diff --git a/arch/mips64/kernel/signal.c b/arch/mips64/kernel/signal.c
index bc21e4d4c..7823efb3b 100644
--- a/arch/mips64/kernel/signal.c
+++ b/arch/mips64/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.5 1999/10/19 20:51:46 ralf Exp $
+/* $Id: signal.c,v 1.4 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
@@ -22,7 +22,7 @@
#include <asm/asm.h>
#include <asm/bitops.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/stackframe.h>
#include <asm/uaccess.h>
#include <asm/ucontext.h>
@@ -618,7 +618,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
- case SIGBUS:
+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */
diff --git a/arch/mips64/kernel/syscall.c b/arch/mips64/kernel/syscall.c
index 8273d5285..67d84f874 100644
--- a/arch/mips64/kernel/syscall.c
+++ b/arch/mips64/kernel/syscall.c
@@ -1,4 +1,4 @@
-/* $Id: syscall.c,v 1.1 1999/12/04 03:59:00 ralf Exp $
+/* $Id: syscall.c,v 1.2 2000/01/29 01:41:59 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
@@ -25,7 +25,7 @@
#include <asm/ipc.h>
#include <asm/cachectl.h>
#include <asm/offset.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/ptrace.h>
#include <asm/signal.h>
#include <asm/stackframe.h>
diff --git a/arch/mips64/mm/fault.c b/arch/mips64/mm/fault.c
index b7091a83d..772aa0475 100644
--- a/arch/mips64/mm/fault.c
+++ b/arch/mips64/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.5 1999/11/23 17:12:50 ralf Exp $
+/* $Id: fault.c,v 1.4 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
@@ -22,7 +22,7 @@
#include <linux/version.h>
#include <asm/hardirq.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/mmu_context.h>
#include <asm/softirq.h>
#include <asm/system.h>
diff --git a/arch/mips64/mm/init.c b/arch/mips64/mm/init.c
index 06b047ef9..e788d3b36 100644
--- a/arch/mips64/mm/init.c
+++ b/arch/mips64/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.9 2000/01/27 23:45:25 ralf Exp $
+/* $Id: init.c,v 1.10 2000/01/29 01:41:59 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
@@ -32,6 +32,7 @@
#include <asm/dma.h>
#include <asm/system.h>
#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#ifdef CONFIG_SGI_IP22
#include <asm/sgialib.h>
#endif
@@ -343,15 +344,23 @@ extern char __init_begin, __init_end;
void __init paging_init(void)
{
- unsigned int zones_size[2];
+ unsigned int zones_size[MAX_NR_ZONES] = {0, 0, 0};
+ unsigned long max_dma, low;
/* 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);
- zones_size[0] = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
- zones_size[1] = max_low_pfn - zones_size[0];
+ max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
+ low = max_low_pfn;
+
+ if (low < max_dma)
+ zones_size[ZONE_DMA] = low;
+ else {
+ zones_size[ZONE_DMA] = max_dma;
+ zones_size[ZONE_NORMAL] = low - max_dma;
+ }
free_area_init(zones_size);
}
@@ -381,7 +390,7 @@ void __init mem_init(void)
datasize = (unsigned long) &_edata - (unsigned long) &_fdata;
initsize = (unsigned long) &__init_end - (unsigned long) &__init_begin;
- printk("Memory: %uk/%luk available (%ldk kernel code, %ldk reserved, "
+ printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
"%ldk data, %ldk init)\n",
(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
ram << (PAGE_SHIFT-10),
@@ -391,6 +400,19 @@ void __init mem_init(void)
initsize >> 10);
}
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(mem_map + MAP_NR(start));
+ set_page_count(mem_map+MAP_NR(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
extern char __init_begin, __init_end;
extern void prom_free_prom_memory(void);
diff --git a/arch/mips64/mm/umap.c b/arch/mips64/mm/umap.c
index 5fefe091d..b8ae542cc 100644
--- a/arch/mips64/mm/umap.c
+++ b/arch/mips64/mm/umap.c
@@ -1,4 +1,4 @@
-/* $Id: umap.c,v 1.3 2000/01/27 01:05:24 ralf Exp $
+/* $Id: umap.c,v 1.4 2000/01/29 01:41:59 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
@@ -21,7 +21,7 @@
#include <linux/swap.h>
#include <asm/system.h>
-#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
#include <asm/page.h>
static inline void
diff --git a/arch/mips64/sgi-ip22/ip22-int.c b/arch/mips64/sgi-ip22/ip22-int.c
index 765c90da1..420e47fc7 100644
--- a/arch/mips64/sgi-ip22/ip22-int.c
+++ b/arch/mips64/sgi-ip22/ip22-int.c
@@ -1,4 +1,4 @@
-/* $Id: ip22-int.c,v 1.4 1999/11/19 20:35:23 ralf Exp $
+/* $Id: ip22-int.c,v 1.3 1999/12/04 03:59:01 ralf Exp $
*
* indy_int.c: Routines for generic manipulation of the INT[23] ASIC
* found on INDY workstations..
@@ -272,7 +272,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
int do_random, cpu;
cpu = smp_processor_id();
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[0][irq]++;
printk("Got irq %d, press a key.", irq);
@@ -308,7 +308,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
add_interrupt_randomness(irq);
__cli();
}
- hardirq_exit(cpu);
+ irq_exit(cpu);
/* unmasking and bottom half handling is done magically for us. */
}
@@ -433,10 +433,10 @@ void indy_local0_irqdispatch(struct pt_regs *regs)
action = local_irq_action[irq];
}
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[0][irq + 16]++;
action->handler(irq, action->dev_id, regs);
- hardirq_exit(cpu);
+ irq_exit(cpu);
}
void indy_local1_irqdispatch(struct pt_regs *regs)
@@ -457,10 +457,10 @@ void indy_local1_irqdispatch(struct pt_regs *regs)
irq = lc1msk_to_irqnr[mask];
action = local_irq_action[irq];
}
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[0][irq + 24]++;
action->handler(irq, action->dev_id, regs);
- hardirq_exit(cpu);
+ irq_exit(cpu);
}
void indy_buserror_irq(struct pt_regs *regs)
@@ -468,13 +468,13 @@ void indy_buserror_irq(struct pt_regs *regs)
int cpu = smp_processor_id();
int irq = 6;
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[0][irq]++;
printk("Got a bus error IRQ, shouldn't happen yet\n");
show_regs(regs);
printk("Spinning...\n");
while(1);
- hardirq_exit(cpu);
+ irq_exit(cpu);
}
/* Misc. crap just to keep the kernel linking... */
diff --git a/arch/mips64/sgi-ip22/ip22-timer.c b/arch/mips64/sgi-ip22/ip22-timer.c
index c5e038b72..cda6076e2 100644
--- a/arch/mips64/sgi-ip22/ip22-timer.c
+++ b/arch/mips64/sgi-ip22/ip22-timer.c
@@ -1,4 +1,4 @@
-/* $Id: ip22-timer.c,v 1.3 1999/10/19 20:51:52 ralf Exp $
+/* $Id: ip22-timer.c,v 1.5 2000/01/21 22:34:03 ralf Exp $
*
* indy_timer.c: Setting up the clock on the INDY 8254 controller.
*
@@ -267,12 +267,12 @@ void indy_8254timer_irq(void)
int cpu = smp_processor_id();
int irq = 4;
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[0][irq]++;
printk("indy_8254timer_irq: Whoops, should not have gotten this IRQ\n");
prom_getchar();
ArcEnterInteractiveMode();
- hardirq_exit(cpu);
+ irq_exit(cpu);
}
void do_gettimeofday(struct timeval *tv)
diff --git a/arch/mips64/sgi-ip27/ip27-irq.c b/arch/mips64/sgi-ip27/ip27-irq.c
index 0b936017d..a7869a602 100644
--- a/arch/mips64/sgi-ip27/ip27-irq.c
+++ b/arch/mips64/sgi-ip27/ip27-irq.c
@@ -1,4 +1,4 @@
-/* $Id$
+/* $Id: ip27-irq.c,v 1.4 2000/01/31 19:48:11 kanoj Exp $
*
* ip27-irq.c: Highlevel interrupt handling for IP27 architecture.
*
@@ -88,7 +88,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
int do_random, cpu;
cpu = smp_processor_id();
- hardirq_enter(cpu);
+ irq_enter(cpu);
kstat.irqs[cpu][irq]++;
action = *(irq + irq_action);
@@ -106,7 +106,7 @@ asmlinkage void do_IRQ(int irq, struct pt_regs * regs)
add_interrupt_randomness(irq);
__cli();
}
- hardirq_exit(cpu);
+ irq_exit(cpu);
/* unmasking and bottom half handling is done magically for us. */
}
diff --git a/arch/mips64/sgi-ip27/ip27-pci.c b/arch/mips64/sgi-ip27/ip27-pci.c
index c92230662..45e9cd649 100644
--- a/arch/mips64/sgi-ip27/ip27-pci.c
+++ b/arch/mips64/sgi-ip27/ip27-pci.c
@@ -172,7 +172,6 @@ void __init
pcibios_fixup_bus(struct pci_bus *b)
{
unsigned short command;
- struct list_head *ln;
struct pci_dev *dev;
pci_fixup_irqs(pci_swizzle, pci_map_irq);
@@ -183,8 +182,7 @@ pcibios_fixup_bus(struct pci_bus *b)
* stop working if we program the controllers as not having
* PCI_COMMAND_MEMORY, so we have to fudge the mem_flags.
*/
- for (ln=b->devices.next; ln != &b->devices; ln=ln->next) {
- dev = pci_dev_b(ln);
+ for (dev = b->devices; dev; dev = dev->sibling) {
if (PCI_FUNC(dev->devfn) == 0) {
if ((PCI_SLOT(dev->devfn) == 0) ||
(PCI_SLOT(dev->devfn) == 1)) {
diff --git a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c
index acdc7c11d..c975513f0 100644
--- a/arch/ppc/8xx_io/commproc.c
+++ b/arch/ppc/8xx_io/commproc.c
@@ -21,7 +21,6 @@
* applications that require more DP ram, we can expand the boundaries
* but then we have to be careful of any downloaded microcode.
*/
-#include <linux/config.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
diff --git a/arch/ppc/8xx_io/commproc.h b/arch/ppc/8xx_io/commproc.h
index 373db5fef..7e7e9896d 100644
--- a/arch/ppc/8xx_io/commproc.h
+++ b/arch/ppc/8xx_io/commproc.h
@@ -18,6 +18,7 @@
#ifndef __CPM_8XX__
#define __CPM_8XX__
+#include <linux/config.h>
#include <asm/8xx_immap.h>
/* CPM Command register.
diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c
index 879b326a7..26beffc40 100644
--- a/arch/ppc/8xx_io/enet.c
+++ b/arch/ppc/8xx_io/enet.c
@@ -22,6 +22,7 @@
* small packets.
*
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c
index aa45d4d27..f0036981e 100644
--- a/arch/ppc/8xx_io/fec.c
+++ b/arch/ppc/8xx_io/fec.c
@@ -16,6 +16,7 @@
* small packets.
*
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile
index 82bdb59ed..8a6db08e2 100644
--- a/arch/ppc/Makefile
+++ b/arch/ppc/Makefile
@@ -21,11 +21,15 @@ endif
ASFLAGS =
LINKFLAGS = -T arch/ppc/vmlinux.lds -Ttext $(KERNELLOAD) -Bstatic
CFLAGSINC = -D__KERNEL__ -I$(TOPDIR)/include -D__powerpc__
-CFLAGS := $(CFLAGS) -I$(HPATH) -D__powerpc__ -fsigned-char -msoft-float \
- -pipe -fno-builtin -ffixed-r2 -Wno-uninitialized -mmultiple \
- -mstring
+CFLAGS := $(CFLAGS) -I$(HPATH) -D__powerpc__ -fsigned-char \
+ -msoft-float -pipe -fno-builtin -ffixed-r2 -Wno-uninitialized \
+ -mmultiple -mstring
CPP = $(CC) -E $(CFLAGS)
+ifdef CONFIG_4xx
+CFLAGS := $(CFLAGS) -mcpu=403
+endif
+
ifdef CONFIG_8xx
CFLAGS := $(CFLAGS) -mcpu=860 -I../8xx_io
endif
@@ -34,10 +38,14 @@ ifdef CONFIG_PPC64
CFLAGS := $(CFLAGS) -Wa,-mppc64bridge #-mpowerpc64
endif
-ifndef CONFIG_8xx
-HEAD := arch/ppc/kernel/head.o
+ifdef CONFIG_4xx
+ HEAD := arch/ppc/kernel/head_4xx.o
else
-HEAD := arch/ppc/kernel/head_8xx.o
+ ifdef CONFIG_8xx
+ HEAD := arch/ppc/kernel/head_8xx.o
+ else
+ HEAD := arch/ppc/kernel/head.o
+ endif
endif
ARCH_SUBDIRS = arch/ppc/kernel arch/ppc/mm arch/ppc/lib
@@ -60,6 +68,7 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
MAKECOFFBOOT = $(MAKE) -C arch/$(ARCH)/coffboot
MAKECHRPBOOT = $(MAKE) -C arch/$(ARCH)/chrpboot
MAKEMBXBOOT = $(MAKE) -C arch/$(ARCH)/mbxboot
+MAKETREEBOOT = $(MAKE) -C arch/$(ARCH)/treeboot
ifdef CONFIG_8xx
SUBDIRS += arch/ppc/8xx_io
@@ -77,11 +86,18 @@ checks:
BOOT_TARGETS = zImage znetboot.initrd zImage.initrd
+ifdef CONFIG_4xx
+$(BOOT_TARGETS): $(CHECKS) vmlinux
+ @$(MAKETREEBOOT) $@
+endif
+
ifdef CONFIG_8xx
$(BOOT_TARGETS): $(CHECKS) vmlinux
@$(MAKECOFFBOOT) $@
@$(MAKEMBXBOOT) $@
-else
+endif
+
+ifdef CONFIG_6xx
$(BOOT_TARGETS): $(CHECKS) vmlinux
@$(MAKECOFFBOOT) $@
@$(MAKEBOOT) $@
@@ -108,33 +124,36 @@ endif
@$(MAKECHRPBOOT) $@
endif
-gemini_config:
+.PHONY: clean_config
+clean_config:
rm -f .config arch/ppc/defconfig
- ln -s gemini_defconfig arch/ppc/defconfig
-pmac_config:
- rm -f .config arch/ppc/defconfig
- ln -s pmac_defconfig arch/ppc/defconfig
+gemini_config: clean_config
+ ln -s configs/gemini_defconfig arch/ppc/defconfig
-prep_config:
- rm -f .config arch/ppc/defconfig
- ln -s prep_defconfig arch/ppc/defconfig
+pmac_config: clean_config
+ ln -s configs/pmac_defconfig arch/ppc/defconfig
-chrp_config:
- rm -f .config arch/ppc/defconfig
- ln -s chrp_defconfig arch/ppc/defconfig
+prep_config: clean_config
+ ln -s configs/prep_defconfig arch/ppc/defconfig
-common_config:
- rm -f .config arch/ppc/defconfig
- ln -s common_defconfig arch/ppc/defconfig
+chrp_config: clean_config
+ ln -s configs/chrp_defconfig arch/ppc/defconfig
-mbx_config:
- rm -f .config arch/ppc/defconfig
- ln -s mbx_defconfig arch/ppc/defconfig
+common_config: clean_config
+ ln -s configs/common_defconfig arch/ppc/defconfig
-apus_config:
- rm -f .config arch/ppc/defconfig
- ln -s apus_defconfig arch/ppc/defconfig
+mbx_config: clean_config
+ ln -s configs/mbx_defconfig arch/ppc/defconfig
+
+apus_config: clean_config
+ ln -s configs/apus_defconfig arch/ppc/defconfig
+
+oak_config: clean_config
+ ln -s configs/oak_defconfig arch/ppc/defconfig
+
+walnut_config: clean_config
+ ln -s configs/walnut_defconfig arch/ppc/defconfig
tags:
etags */*.c include/{asm,linux}/*.h arch/ppc/kernel/*.{c,h}
@@ -145,6 +164,7 @@ archclean:
@$(MAKEBOOT) clean
@$(MAKECHRPBOOT) clean
@$(MAKEMBXBOOT) clean
+ @$(MAKETREEBOOT) clean
archmrproper:
diff --git a/arch/ppc/amiga/ints.c b/arch/ppc/amiga/ints.c
index 80c63f7ab..938476267 100644
--- a/arch/ppc/amiga/ints.c
+++ b/arch/ppc/amiga/ints.c
@@ -5,7 +5,6 @@
* Needed to drive the m68k emulating IRQ hardware on the PowerUp boards.
*/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/kernel_stat.h>
diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile
index 41a8a915f..96b6ba306 100644
--- a/arch/ppc/boot/Makefile
+++ b/arch/ppc/boot/Makefile
@@ -134,7 +134,7 @@ znetboot.initrd : zImage.initrd
cp zImage.initrd $(TFTPIMAGE)
clean:
- rm -f vmlinux* zvmlinux* mkprep zImage*
+ rm -f vmlinux* zvmlinux* mkprep zImage* sImage*
fastdep:
$(TOPDIR)/scripts/mkdep *.[Sch] > .depend
diff --git a/arch/ppc/boot/head.S b/arch/ppc/boot/head.S
index 79377a2ac..cc9339c8e 100644
--- a/arch/ppc/boot/head.S
+++ b/arch/ppc/boot/head.S
@@ -112,14 +112,6 @@ start_ldr:
cmpi 0,r2,0
bne 00b
- /* r4,r5 have initrd_start, size */
- lis r2,initrd_start@h
- ori r2,r2,initrd_start@l
- lwz r4,0(r2)
- lis r2,initrd_end@h
- ori r2,r2,initrd_end@l
- lwz r5,0(r2)
-
/* tell kernel we're prep */
/*
* get start address of kernel code which is stored as a coff
diff --git a/arch/ppc/boot/misc.c b/arch/ppc/boot/misc.c
index 6724a8130..d25f732b8 100644
--- a/arch/ppc/boot/misc.c
+++ b/arch/ppc/boot/misc.c
@@ -16,6 +16,7 @@
#include <linux/config.h>
#include <asm/page.h>
#include <asm/processor.h>
+#include <asm/bootinfo.h>
#include <asm/mmu.h>
#if defined(CONFIG_SERIAL_CONSOLE)
#include "ns16550.h"
@@ -518,17 +519,39 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum,
*cp = 0;
puts("\n");
- /* mappings on early boot can only handle 16M */
- if ( (int)(cmd_line[0]) > (16<<20))
- puts("cmd_line located > 16M\n");
- if ( (int)hold_residual > (16<<20))
- puts("hold_residual located > 16M\n");
- if ( initrd_start > (16<<20))
- puts("initrd_start located > 16M\n");
-
puts("Uncompressing Linux...");
gunzip(0, 0x400000, zimage_start, &zimage_size);
puts("done.\n");
+
+ {
+ struct bi_record *rec;
+
+ rec = (struct bi_record *)PAGE_ALIGN(zimage_size);
+
+ rec->tag = BI_FIRST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_BOOTLOADER_ID;
+ memcpy( (void *)rec->data, "prepboot", 9);
+ rec->size = sizeof(struct bi_record) + 8 + 1;
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_MACHTYPE;
+ rec->data[0] = _MACH_prep;
+ rec->data[1] = 1;
+ rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_CMD_LINE;
+ memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1);
+ rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1;
+ rec = (struct bi_record *)((ulong)rec + rec->size);
+
+ rec->tag = BI_LAST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+ }
puts("Now booting the kernel\n");
return (unsigned long)hold_residual;
}
diff --git a/arch/ppc/chrpboot/main.c b/arch/ppc/chrpboot/main.c
index 80db69a7b..bf506552a 100644
--- a/arch/ppc/chrpboot/main.c
+++ b/arch/ppc/chrpboot/main.c
@@ -8,6 +8,10 @@
*/
#include "../coffboot/nonstdio.h"
#include "../coffboot/zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#define __KERNEL__
+#include <asm/page.h>
extern void *finddevice(const char *);
extern int getprop(void *, const char *, void *, int);
@@ -71,6 +75,30 @@ chrpboot(int a1, int a2, void *prom)
sa = (unsigned long)PROG_START;
printf("start address = 0x%x\n\r", sa);
+ {
+ struct bi_record *rec;
+
+ rec = (struct bi_record *)PAGE_ALIGN((unsigned long)dst+len);
+
+ rec->tag = BI_FIRST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_BOOTLOADER_ID;
+ sprintf( (char *)rec->data, "chrpboot");
+ rec->size = sizeof(struct bi_record) + strlen("chrpboot") + 1;
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_MACHTYPE;
+ rec->data[0] = _MACH_chrp;
+ rec->data[1] = 1;
+ rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_LAST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+ }
(*(void (*)())sa)(0, 0, prom, a1, a2);
printf("returned?\n\r");
diff --git a/arch/ppc/chrpboot/string.S b/arch/ppc/chrpboot/string.S
deleted file mode 100644
index ba83591b7..000000000
--- a/arch/ppc/chrpboot/string.S
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * String handling functions for PowerPC.
- *
- * Copyright (C) 1996 Paul Mackerras.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version
- * 2 of the License, or (at your option) any later version.
- */
-#define r0 0
-#define r3 3
-#define r4 4
-#define r5 5
-#define r6 6
-#define r7 7
-#define r8 8
-
- .globl strcpy
-strcpy:
- addi r5,r3,-1
- addi r4,r4,-1
-1: lbzu r0,1(r4)
- cmpwi 0,r0,0
- stbu r0,1(r5)
- bne 1b
- blr
-
- .globl strncpy
-strncpy:
- cmpwi 0,r5,0
- beqlr
- mtctr r5
- addi r6,r3,-1
- addi r4,r4,-1
-1: lbzu r0,1(r4)
- cmpwi 0,r0,0
- stbu r0,1(r6)
- bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */
- blr
-
- .globl strcat
-strcat:
- addi r5,r3,-1
- addi r4,r4,-1
-1: lbzu r0,1(r5)
- cmpwi 0,r0,0
- bne 1b
- addi r5,r5,-1
-1: lbzu r0,1(r4)
- cmpwi 0,r0,0
- stbu r0,1(r5)
- bne 1b
- blr
-
- .globl strcmp
-strcmp:
- addi r5,r3,-1
- addi r4,r4,-1
-1: lbzu r3,1(r5)
- cmpwi 1,r3,0
- lbzu r0,1(r4)
- subf. r3,r0,r3
- beqlr 1
- beq 1b
- blr
-
- .globl strlen
-strlen:
- addi r4,r3,-1
-1: lbzu r0,1(r4)
- cmpwi 0,r0,0
- bne 1b
- subf r3,r3,r4
- blr
-
- .globl memset
-memset:
- rlwimi r4,r4,8,16,23
- rlwimi r4,r4,16,0,15
- addi r6,r3,-4
- cmplwi 0,r5,4
- blt 7f
- stwu r4,4(r6)
- beqlr
- andi. r0,r6,3
- add r5,r0,r5
- subf r6,r0,r6
- rlwinm r0,r5,32-2,2,31
- mtctr r0
- bdz 6f
-1: stwu r4,4(r6)
- bdnz 1b
-6: andi. r5,r5,3
-7: cmpwi 0,r5,0
- beqlr
- mtctr r5
- addi r6,r6,3
-8: stbu r4,1(r6)
- bdnz 8b
- blr
-
- .globl bcopy
-bcopy:
- mr r6,r3
- mr r3,r4
- mr r4,r6
- b memcpy
-
- .globl memmove
-memmove:
- cmplw 0,r3,r4
- bgt backwards_memcpy
- /* fall through */
-
- .globl memcpy
-memcpy:
- rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
- addi r6,r3,-4
- addi r4,r4,-4
- beq 2f /* if less than 8 bytes to do */
- andi. r0,r6,3 /* get dest word aligned */
- mtctr r7
- bne 5f
-1: lwz r7,4(r4)
- lwzu r8,8(r4)
- stw r7,4(r6)
- stwu r8,8(r6)
- bdnz 1b
- andi. r5,r5,7
-2: cmplwi 0,r5,4
- blt 3f
- lwzu r0,4(r4)
- addi r5,r5,-4
- stwu r0,4(r6)
-3: cmpwi 0,r5,0
- beqlr
- mtctr r5
- addi r4,r4,3
- addi r6,r6,3
-4: lbzu r0,1(r4)
- stbu r0,1(r6)
- bdnz 4b
- blr
-5: subfic r0,r0,4
- mtctr r0
-6: lbz r7,4(r4)
- addi r4,r4,1
- stb r7,4(r6)
- addi r6,r6,1
- bdnz 6b
- subf r5,r0,r5
- rlwinm. r7,r5,32-3,3,31
- beq 2b
- mtctr r7
- b 1b
-
- .globl backwards_memcpy
-backwards_memcpy:
- rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */
- add r6,r3,r5
- add r4,r4,r5
- beq 2f
- andi. r0,r6,3
- mtctr r7
- bne 5f
-1: lwz r7,-4(r4)
- lwzu r8,-8(r4)
- stw r7,-4(r6)
- stwu r8,-8(r6)
- bdnz 1b
- andi. r5,r5,7
-2: cmplwi 0,r5,4
- blt 3f
- lwzu r0,-4(r4)
- subi r5,r5,4
- stwu r0,-4(r6)
-3: cmpwi 0,r5,0
- beqlr
- mtctr r5
-4: lbzu r0,-1(r4)
- stbu r0,-1(r6)
- bdnz 4b
- blr
-5: mtctr r0
-6: lbzu r7,-1(r4)
- stbu r7,-1(r6)
- bdnz 6b
- subf r5,r0,r5
- rlwinm. r7,r5,32-3,3,31
- beq 2b
- mtctr r7
- b 1b
-
- .globl memcmp
-memcmp:
- cmpwi 0,r5,0
- blelr
- mtctr r5
- addi r6,r3,-1
- addi r4,r4,-1
-1: lbzu r3,1(r6)
- lbzu r0,1(r4)
- subf. r3,r0,r3
- bdnzt 2,1b
- blr
diff --git a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile
index 81e21f3e3..a7ed94074 100644
--- a/arch/ppc/coffboot/Makefile
+++ b/arch/ppc/coffboot/Makefile
@@ -9,25 +9,26 @@ CC = $(CROSS_COMPILE)gcc
LD = $(CROSS_COMPILE)ld
CFLAGS = -O -fno-builtin -I$(TOPDIR)/include
OBJCOPY = $(CROSS_COMPILE)objcopy
-OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment \
- --add-section=image=vmlinux.gz
-LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
+OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
+COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
+CHRP_LD_ARGS = -Ttext 0x00400000
GZ = gzip -9
-OBJS = crt0.o start.o main.o misc.o string.o zlib.o
+COFFOBJS = coffcrt0.o start.o coffmain.o misc.o string.o zlib.o image.o
+CHRPOBJS = crt0.o start.o chrpmain.o misc.o string.o zlib.o image.o
LIBS = $(TOPDIR)/lib/lib.a
-ifeq ($(CONFIG_ALL_PPC),y)
-# yes, we want to build pmac stuff
-CONFIG_PMAC = y
-endif
-
ifeq ($(CONFIG_PPC64),y)
MSIZE=.64
else
MSIZE=
endif
+ifeq ($(CONFIG_ALL_PPC),y)
+# yes, we want to build pmac stuff
+CONFIG_PMAC = y
+endif
+
ifeq ($(CONFIG_SMP),y)
TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE)
else
@@ -38,34 +39,58 @@ ifeq ($(CONFIG_PMAC),y)
hack-coff: hack-coff.c
$(HOSTCC) $(HOSTCFLAGS) -o hack-coff hack-coff.c
+znetboot: vmlinux.coff zImage
+ cp vmlinux.coff $(TFTPIMAGE)
+
+znetboot.initrd: vmlinux.coff.initrd
+ cp vmlinux.coff.initrd $(TFTPIMAGE)
+
floppy: zImage
# mount -t hfs /dev/fd0 /mnt
# cp vmlinux.coff /mnt
# umount /mnt
-znetboot: vmlinux.coff
- cp vmlinux.coff $(TFTPIMAGE)
+coffboot: $(COFFOBJS) no_initrd.o ld.script
+ $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) no_initrd.o $(LIBS)
-znetboot.initrd: vmlinux.coff.initrd
- cp vmlinux.coff.initrd $(TFTPIMAGE)
+coffboot.initrd: $(COFFOBJS) initrd.o ld.script
+ $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) initrd.o $(LIBS)
-coffboot: $(OBJS) ld.script
- $(LD) -o coffboot $(LD_ARGS) $(OBJS) $(LIBS)
+piggyback: piggyback.c
+ $(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c
-zImage: vmlinux.coff
+mknote: mknote.c
+ $(HOSTCC) $(HOSTCFLAGS) -o mknote mknote.c
-zImage.initrd: vmlinux.coff.initrd
+image.o: piggyback vmlinux.gz
+ ./piggyback image < vmlinux.gz | $(AS) -o image.o
-vmlinux.coff: coffboot hack-coff vmlinux.gz
+initrd.o: ramdisk.image.gz piggyback
+ ./piggyback initrd < ramdisk.image.gz | $(AS) -o initrd.o
+
+vmlinux.coff: coffboot hack-coff
$(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@
./hack-coff $@
ln -sf vmlinux.coff zImage
-vmlinux.coff.initrd: coffboot hack-coff vmlinux.gz ramdisk.image.gz
- $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=ramdisk.image.gz \
- coffboot $@
+vmlinux.coff.initrd: coffboot.initrd hack-coff
+ $(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@
./hack-coff $@
+vmlinux.elf: $(CHRPOBJS) no_initrd.o mknote
+ $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) no_initrd.o $(LIBS)
+ ./mknote > note
+ $(OBJCOPY) $@ $@ --add-section=.note=note -R .comment
+
+vmlinux.elf.initrd: $(CHRPOBJS) initrd.o mknote
+ $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) initrd.o $(LIBS)
+ ./mknote > note
+ $(OBJCOPY) $@ $@ --add-section=.note=note -R .comment
+
+zImage: vmlinux.coff vmlinux.elf
+
+zImage.initrd: vmlinux.coff.initrd vmlinux.elf.initrd
+
else
znetboot: vmlinux.gz
diff --git a/arch/ppc/coffboot/chrpmain.c b/arch/ppc/coffboot/chrpmain.c
new file mode 100644
index 000000000..fc5648944
--- /dev/null
+++ b/arch/ppc/coffboot/chrpmain.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "nonstdio.h"
+#include "zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#define __KERNEL__
+#include <asm/page.h>
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+void make_bi_recs(unsigned long);
+void gunzip(void *, int, unsigned char *, int *);
+void stop_imac_ethernet(void);
+void stop_imac_usb(void);
+
+#define get_16be(x) (*(unsigned short *)(x))
+#define get_32be(x) (*(unsigned *)(x))
+
+#define RAM_START 0x00000000
+#define RAM_END (8<<20)
+
+#define PROG_START 0x00010000
+
+char *avail_ram;
+char *end_avail;
+
+extern char _end[];
+extern char image_data[];
+extern int image_len;
+extern char initrd_data[];
+extern int initrd_len;
+
+
+boot(int a1, int a2, void *prom)
+{
+ int ns, oh, i;
+ unsigned sa, len;
+ void *dst;
+ unsigned char *im;
+ unsigned initrd_start, initrd_size;
+ extern char _start;
+
+ printf("chrpboot starting: loaded at 0x%x\n", &_start);
+ if (initrd_len) {
+ initrd_size = initrd_len;
+ initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+ a1 = initrd_start;
+ a2 = initrd_size;
+ claim(initrd_start, RAM_END - initrd_start, 0);
+ printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", initrd_start,
+ initrd_data,initrd_size);
+ memcpy((char *)initrd_start, initrd_data, initrd_size);
+ }
+ im = image_data;
+ len = image_len;
+ /* claim 3MB starting at PROG_START */
+ claim(PROG_START, 3 << 20, 0);
+ dst = (void *) PROG_START;
+ if (im[0] == 0x1f && im[1] == 0x8b) {
+ /* claim 512kB for scratch space */
+ avail_ram = (char *) claim(0, 512 << 10, 0x10);
+ end_avail = avail_ram + (512 << 10);
+ printf("avail_ram = %x\n", avail_ram);
+ printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+ gunzip(dst, 3 << 20, im, &len);
+ printf("done %u bytes\n", len);
+ } else {
+ memmove(dst, im, len);
+ }
+
+ flush_cache(dst, len);
+ stop_imac_ethernet();
+ stop_imac_usb();
+ make_bi_recs((unsigned long) dst + len);
+
+ sa = (unsigned long)PROG_START;
+ printf("start address = 0x%x\n", sa);
+
+ (*(void (*)())sa)(0, 0, prom, a1, a2);
+
+ printf("returned?\n");
+
+ pause();
+}
+
+void make_bi_recs(unsigned long addr)
+{
+ struct bi_record *rec;
+
+ rec = (struct bi_record *)PAGE_ALIGN(addr);
+
+ rec->tag = BI_FIRST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_BOOTLOADER_ID;
+ sprintf( (char *)rec->data, "coffboot");
+ rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_MACHTYPE;
+ rec->data[0] = _MACH_Pmac;
+ rec->data[1] = 1;
+ rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_LAST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+}
+
+#define eieio() asm volatile("eieio");
+
+void stop_imac_ethernet(void)
+{
+ void *macio, *enet;
+ unsigned int macio_addr[5], enet_reg[6];
+ int len;
+ volatile unsigned int *dbdma;
+
+ macio = finddevice("/pci/mac-io");
+ enet = finddevice("/pci/mac-io/ethernet");
+ if (macio == NULL || enet == NULL)
+ return;
+ len = getprop(macio, "assigned-addresses", macio_addr, sizeof(macio_addr));
+ if (len != sizeof(macio_addr))
+ return;
+ len = getprop(enet, "reg", enet_reg, sizeof(enet_reg));
+ if (len != sizeof(enet_reg))
+ return;
+ printf("macio base %x, dma at %x & %x\n",
+ macio_addr[2], enet_reg[2], enet_reg[4]);
+
+ /* hope this is mapped... */
+ dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[2]);
+ *dbdma = 0x80; /* clear the RUN bit */
+ eieio();
+ dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[4]);
+ *dbdma = 0x80; /* clear the RUN bit */
+ eieio();
+}
+
+void stop_imac_usb(void)
+{
+ void *usb;
+ unsigned int usb_addr[5];
+ int len;
+ volatile unsigned int *usb_ctrl;
+
+ usb = finddevice("/pci/usb");
+ if (usb == NULL)
+ return;
+ len = getprop(usb, "assigned-addresses", usb_addr, sizeof(usb_addr));
+ if (len != sizeof(usb_addr))
+ return;
+ printf("usb base %x\n", usb_addr[2]);
+
+ usb_ctrl = (volatile unsigned int *) (usb_addr[2] + 8);
+ *usb_ctrl = 0x01000000; /* cpu_to_le32(1) */
+ eieio();
+}
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+ void *p = avail_ram;
+
+ size *= items;
+ size = (size + 7) & -8;
+ avail_ram += size;
+ if (avail_ram > end_avail) {
+ printf("oops... out of memory\n");
+ pause();
+ }
+ return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+}
+
+#define HEAD_CRC 2
+#define EXTRA_FIELD 4
+#define ORIG_NAME 8
+#define COMMENT 0x10
+#define RESERVED 0xe0
+
+#define DEFLATED 8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+ z_stream s;
+ int r, i, flags;
+
+ /* skip header */
+ i = 10;
+ flags = src[3];
+ if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+ printf("bad gzipped data\n");
+ exit();
+ }
+ if ((flags & EXTRA_FIELD) != 0)
+ i = 12 + src[10] + (src[11] << 8);
+ if ((flags & ORIG_NAME) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & COMMENT) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & HEAD_CRC) != 0)
+ i += 2;
+ if (i >= *lenp) {
+ printf("gunzip: ran out of data in header\n");
+ exit();
+ }
+
+ s.zalloc = zalloc;
+ s.zfree = zfree;
+ r = inflateInit2(&s, -MAX_WBITS);
+ if (r != Z_OK) {
+ printf("inflateInit2 returned %d\n", r);
+ exit();
+ }
+ s.next_in = src + i;
+ s.avail_in = *lenp - i;
+ s.next_out = dst;
+ s.avail_out = dstlen;
+ r = inflate(&s, Z_FINISH);
+ if (r != Z_OK && r != Z_STREAM_END) {
+ printf("inflate returned %d msg: %s\n", r, s.msg);
+ exit();
+ }
+ *lenp = s.next_out - (unsigned char *) dst;
+ inflateEnd(&s);
+}
diff --git a/arch/ppc/coffboot/coffcrt0.S b/arch/ppc/coffboot/coffcrt0.S
new file mode 100644
index 000000000..43ae4e0ec
--- /dev/null
+++ b/arch/ppc/coffboot/coffcrt0.S
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+ .text
+ .globl _start
+_start:
+ .long __start,0,0
+
+ .globl __start
+__start:
+ lis 9,_start@h
+ lis 8,_etext@ha
+ addi 8,8,_etext@l
+1: dcbf 0,9
+ icbi 0,9
+ addi 9,9,0x20
+ cmplwi 0,9,8
+ blt 1b
+ b start
diff --git a/arch/ppc/coffboot/coffmain.c b/arch/ppc/coffboot/coffmain.c
new file mode 100644
index 000000000..2bb4ea31d
--- /dev/null
+++ b/arch/ppc/coffboot/coffmain.c
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "nonstdio.h"
+#include "zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#define __KERNEL__
+#include <asm/page.h>
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+extern char *claim(unsigned, unsigned, unsigned);
+void make_bi_recs(unsigned long);
+void gunzip(void *, int, unsigned char *, int *);
+
+#define get_16be(x) (*(unsigned short *)(x))
+#define get_32be(x) (*(unsigned *)(x))
+
+#define RAM_START 0xc0000000
+#define PROG_START RAM_START
+#define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */
+
+char *avail_ram;
+char *end_avail;
+
+extern char _start[], _end[];
+extern char image_data[];
+extern int image_len;
+extern char initrd_data[];
+extern int initrd_len;
+
+
+boot(int a1, int a2, void *prom)
+{
+ int ns, oh, i;
+ unsigned sa, len;
+ void *dst;
+ unsigned char *im;
+ unsigned initrd_start, initrd_size;
+
+ printf("coffboot starting: loaded at 0x%x\n", _start);
+ setup_bats(RAM_START);
+ if (initrd_len) {
+ initrd_size = initrd_len;
+ initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+ a1 = initrd_start;
+ a2 = initrd_size;
+ claim(initrd_start - RAM_START, RAM_END - initrd_start, 0);
+ printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n",
+ initrd_start, initrd_data, initrd_size);
+ memcpy((char *)initrd_start, initrd_data, initrd_size);
+ }
+ im = image_data;
+ len = image_len;
+ /* claim 3MB starting at 0 */
+ claim(0, 3 << 20, 0);
+ dst = (void *) RAM_START;
+ if (im[0] == 0x1f && im[1] == 0x8b) {
+ /* claim 512kB for scratch space */
+ avail_ram = claim(0, 512 << 10, 0x10) + RAM_START;
+ end_avail = avail_ram + (512 << 10);
+ printf("avail_ram = %x\n", avail_ram);
+ printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+ gunzip(dst, 3 << 20, im, &len);
+ printf("done %u bytes\n", len);
+ } else {
+ memmove(dst, im, len);
+ }
+
+ flush_cache(dst, len);
+ make_bi_recs((unsigned long)dst + len);
+
+ sa = (unsigned long)PROG_START;
+ printf("start address = 0x%x\n", sa);
+
+#if 0
+ pause();
+#endif
+ (*(void (*)())sa)(a1, a2, prom);
+
+ printf("returned?\n");
+
+ pause();
+}
+
+void make_bi_recs(unsigned long addr)
+{
+ struct bi_record *rec;
+
+ rec = (struct bi_record *)PAGE_ALIGN(addr);
+
+ rec->tag = BI_FIRST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_BOOTLOADER_ID;
+ sprintf( (char *)rec->data, "coffboot");
+ rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_MACHTYPE;
+ rec->data[0] = _MACH_Pmac;
+ rec->data[1] = 1;
+ rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_LAST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+}
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+ void *p = avail_ram;
+
+ size *= items;
+ size = (size + 7) & -8;
+ avail_ram += size;
+ if (avail_ram > end_avail) {
+ printf("oops... out of memory\n");
+ pause();
+ }
+ return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+}
+
+#define HEAD_CRC 2
+#define EXTRA_FIELD 4
+#define ORIG_NAME 8
+#define COMMENT 0x10
+#define RESERVED 0xe0
+
+#define DEFLATED 8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+ z_stream s;
+ int r, i, flags;
+
+ /* skip header */
+ i = 10;
+ flags = src[3];
+ if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+ printf("bad gzipped data\n");
+ exit();
+ }
+ if ((flags & EXTRA_FIELD) != 0)
+ i = 12 + src[10] + (src[11] << 8);
+ if ((flags & ORIG_NAME) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & COMMENT) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & HEAD_CRC) != 0)
+ i += 2;
+ if (i >= *lenp) {
+ printf("gunzip: ran out of data in header\n");
+ exit();
+ }
+
+ s.zalloc = zalloc;
+ s.zfree = zfree;
+ r = inflateInit2(&s, -MAX_WBITS);
+ if (r != Z_OK) {
+ printf("inflateInit2 returned %d\n", r);
+ exit();
+ }
+ s.next_in = src + i;
+ s.avail_in = *lenp - i;
+ s.next_out = dst;
+ s.avail_out = dstlen;
+ r = inflate(&s, Z_FINISH);
+ if (r != Z_OK && r != Z_STREAM_END) {
+ printf("inflate returned %d msg: %s\n", r, s.msg);
+ exit();
+ }
+ *lenp = s.next_out - (unsigned char *) dst;
+ inflateEnd(&s);
+}
diff --git a/arch/ppc/coffboot/crt0.S b/arch/ppc/coffboot/crt0.S
index 43ae4e0ec..c43340594 100644
--- a/arch/ppc/coffboot/crt0.S
+++ b/arch/ppc/coffboot/crt0.S
@@ -9,10 +9,6 @@
.text
.globl _start
_start:
- .long __start,0,0
-
- .globl __start
-__start:
lis 9,_start@h
lis 8,_etext@ha
addi 8,8,_etext@l
diff --git a/arch/ppc/coffboot/main.c b/arch/ppc/coffboot/main.c
index b3a310e17..56d29b84f 100644
--- a/arch/ppc/coffboot/main.c
+++ b/arch/ppc/coffboot/main.c
@@ -9,6 +9,10 @@
#include "nonstdio.h"
#include "rs6000.h"
#include "zlib.h"
+#include <asm/bootinfo.h>
+#include <asm/processor.h>
+#define __KERNEL__
+#include <asm/page.h>
extern void *finddevice(const char *);
extern int getprop(void *, const char *, void *, int);
@@ -106,6 +110,31 @@ coffboot(int a1, int a2, void *prom)
#if 0
pause();
#endif
+ {
+ struct bi_record *rec;
+
+ rec = (struct bi_record *)PAGE_ALIGN((unsigned long)dst+len);
+
+ rec->tag = BI_FIRST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_BOOTLOADER_ID;
+ sprintf( (char *)rec->data, "coffboot");
+ rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1;
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_MACHTYPE;
+ rec->data[0] = _MACH_Pmac;
+ rec->data[1] = 1;
+ rec->size = sizeof(struct bi_record) + sizeof(unsigned long);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+
+ rec->tag = BI_LAST;
+ rec->size = sizeof(struct bi_record);
+ rec = (struct bi_record *)((unsigned long)rec + rec->size);
+ }
+
(*(void (*)())sa)(a1, a2, prom);
printf("returned?\n");
@@ -165,7 +194,6 @@ void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
printf("gunzip: ran out of data in header\n");
exit();
}
-printf("done 1\n");
s.zalloc = zalloc;
s.zfree = zfree;
r = inflateInit2(&s, -MAX_WBITS);
@@ -177,14 +205,11 @@ printf("done 1\n");
s.avail_in = *lenp - i;
s.next_out = dst;
s.avail_out = dstlen;
-printf("doing inflate\n");
r = inflate(&s, Z_FINISH);
-printf("done inflate\n");
if (r != Z_OK && r != Z_STREAM_END) {
printf("inflate returned %d\n", r);
exit();
}
*lenp = s.next_out - (unsigned char *) dst;
-printf("doing end\n");
inflateEnd(&s);
}
diff --git a/arch/ppc/coffboot/misc.S b/arch/ppc/coffboot/misc.S
index df542a522..7defc69e8 100644
--- a/arch/ppc/coffboot/misc.S
+++ b/arch/ppc/coffboot/misc.S
@@ -14,23 +14,26 @@
*/
.globl setup_bats
setup_bats:
- mr 4,3
- mfpvr 3
- rlwinm 3,3,16,16,31 /* r3 = 1 for 601, 4 for 604 */
- cmpi 0,3,1
+ mfpvr 5
+ rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */
+ cmpi 0,5,1
+ li 0,0
bne 4f
- ori 4,4,4 /* set up BAT registers for 601 */
- li 5,0x7f
- mtibatu 3,4
- mtibatl 3,5
- isync
- blr
-4: ori 4,4,0xfe /* set up BAT registers for 604 */
- li 5,2
- mtdbatl 3,5
- mtdbatu 3,4
- mtibatl 3,5
- mtibatu 3,4
+ mtibatl 3,0 /* invalidate BAT first */
+ ori 3,3,4 /* set up BAT registers for 601 */
+ li 4,0x7f
+ mtibatu 3,3
+ mtibatl 3,4
+ b 5f
+4: mtdbatu 3,0 /* invalidate BATs first */
+ mtibatu 3,0
+ ori 3,3,0xff /* set up BAT registers for 604 */
+ li 4,2
+ mtdbatl 3,4
+ mtdbatu 3,3
+ mtibatl 3,4
+ mtibatu 3,3
+5: sync
isync
blr
diff --git a/arch/ppc/coffboot/mknote.c b/arch/ppc/coffboot/mknote.c
new file mode 100644
index 000000000..120cc1d89
--- /dev/null
+++ b/arch/ppc/coffboot/mknote.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) Cort Dougan 1999.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Generate a note section as per the CHRP specification.
+ *
+ */
+
+#include <stdio.h>
+
+#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
+
+int main(void)
+{
+/* header */
+ /* namesz */
+ PL(strlen("PowerPC")+1);
+ /* descrsz */
+ PL(6*4);
+ /* type */
+ PL(0x1275);
+ /* name */
+ printf("PowerPC"); printf("%c", 0);
+
+/* descriptor */
+ /* real-mode */
+ PL(0xffffffff);
+ /* real-base */
+ PL(0x00c00000);
+ /* real-size */
+ PL(0xffffffff);
+ /* virt-base */
+ PL(0xffffffff);
+ /* virt-size */
+ PL(0xffffffff);
+ /* load-base */
+ PL(0x4000);
+ return 0;
+}
diff --git a/arch/ppc/coffboot/no_initrd.c b/arch/ppc/coffboot/no_initrd.c
new file mode 100644
index 000000000..ed5dcdb1f
--- /dev/null
+++ b/arch/ppc/coffboot/no_initrd.c
@@ -0,0 +1,2 @@
+char initrd_data[1];
+int initrd_len = 0;
diff --git a/arch/ppc/coffboot/piggyback.c b/arch/ppc/coffboot/piggyback.c
new file mode 100644
index 000000000..172025802
--- /dev/null
+++ b/arch/ppc/coffboot/piggyback.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+extern long ce_exec_config[];
+
+main(int argc, char *argv[])
+{
+ int i, cnt, pos, len;
+ unsigned int cksum, val;
+ unsigned char *lp;
+ unsigned char buf[8192];
+ if (argc != 2)
+ {
+ fprintf(stderr, "usage: %s name <in-file >out-file\n",
+ argv[0]);
+ exit(1);
+ }
+ fprintf(stdout, "#\n");
+ fprintf(stdout, "# Miscellaneous data structures:\n");
+ fprintf(stdout, "# WARNING - this file is automatically generated!\n");
+ fprintf(stdout, "#\n");
+ fprintf(stdout, "\n");
+ fprintf(stdout, "\t.data\n");
+ fprintf(stdout, "\t.globl %s_data\n", argv[1]);
+ fprintf(stdout, "%s_data:\n", argv[1]);
+ pos = 0;
+ cksum = 0;
+ while ((len = read(0, buf, sizeof(buf))) > 0)
+ {
+ cnt = 0;
+ lp = (unsigned char *)buf;
+ len = (len + 3) & ~3; /* Round up to longwords */
+ for (i = 0; i < len; i += 4)
+ {
+ if (cnt == 0)
+ {
+ fprintf(stdout, "\t.long\t");
+ }
+ fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
+ val = *(unsigned long *)lp;
+ cksum ^= val;
+ lp += 4;
+ if (++cnt == 4)
+ {
+ cnt = 0;
+ fprintf(stdout, " # %x \n", pos+i-12);
+ fflush(stdout);
+ } else
+ {
+ fprintf(stdout, ",");
+ }
+ }
+ if (cnt)
+ {
+ fprintf(stdout, "0\n");
+ }
+ pos += len;
+ }
+ fprintf(stdout, "\t.globl %s_len\n", argv[1]);
+ fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos);
+ fflush(stdout);
+ fclose(stdout);
+ fprintf(stderr, "cksum = %x\n", cksum);
+ exit(0);
+}
+
diff --git a/arch/ppc/coffboot/start.c b/arch/ppc/coffboot/start.c
index 1f11edbec..6fc1fc1fb 100644
--- a/arch/ppc/coffboot/start.c
+++ b/arch/ppc/coffboot/start.c
@@ -33,7 +33,7 @@ start(int a1, int a2, void *promptr)
if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
exit();
- coffboot(a1, a2, promptr);
+ boot(a1, a2, promptr);
for (;;)
exit();
}
@@ -62,6 +62,25 @@ write(void *handle, void *ptr, int nb)
return args.actual;
}
+int writestring(void *f, char *ptr, int nb)
+{
+ int w = 0, i;
+ char *ret = "\r";
+
+ for (i = 0; i < nb; ++i) {
+ if (ptr[i] == '\n') {
+ if (i > w) {
+ write(f, ptr + w, i - w);
+ w = i;
+ }
+ write(f, ret, 1);
+ }
+ }
+ if (w < nb)
+ write(f, ptr + w, nb - w);
+ return nb;
+}
+
int
read(void *handle, void *ptr, int nb)
{
@@ -130,6 +149,29 @@ finddevice(const char *name)
return args.phandle;
}
+void *
+claim(unsigned int virt, unsigned int size, unsigned int align)
+{
+ struct prom_args {
+ char *service;
+ int nargs;
+ int nret;
+ unsigned int virt;
+ unsigned int size;
+ unsigned int align;
+ void *ret;
+ } args;
+
+ args.service = "claim";
+ args.nargs = 3;
+ args.nret = 1;
+ args.virt = virt;
+ args.size = size;
+ args.align = align;
+ (*prom)(&args);
+ return args.ret;
+}
+
int
getprop(void *phandle, const char *name, void *buf, int buflen)
{
@@ -161,9 +203,7 @@ putc(int c, void *f)
{
char ch = c;
- if (c == '\n')
- putc('\r', f);
- return write(f, &ch, 1) == 1? c: -1;
+ return writestring(f, &ch, 1) == 1? c: -1;
}
int
@@ -177,7 +217,7 @@ fputs(char *str, void *f)
{
int n = strlen(str);
- return write(f, str, n) == n? 0: -1;
+ return writestring(f, str, n) == n? 0: -1;
}
int
@@ -190,7 +230,7 @@ readchar()
case 1:
return ch;
case -1:
- printk("read(stdin) returned -1\r\n");
+ printk("read(stdin) returned -1\n");
return -1;
}
}
@@ -264,7 +304,7 @@ printk(char *fmt, ...)
va_start(args, fmt);
n = vsprintf(sprint_buf, fmt, args);
va_end(args);
- write(stdout, sprint_buf, n);
+ writestring(stdout, sprint_buf, n);
}
int
@@ -276,6 +316,6 @@ printf(char *fmt, ...)
va_start(args, fmt);
n = vsprintf(sprint_buf, fmt, args);
va_end(args);
- write(stdout, sprint_buf, n);
+ writestring(stdout, sprint_buf, n);
return n;
}
diff --git a/arch/ppc/config.in b/arch/ppc/config.in
index 325935ffe..279d81438 100644
--- a/arch/ppc/config.in
+++ b/arch/ppc/config.in
@@ -12,35 +12,49 @@ endmenu
mainmenu_option next_comment
comment 'Platform support'
define_bool CONFIG_PPC y
-choice 'Processor type' \
- "6xx/7xx CONFIG_6xx \
- 630/Power3(64-Bit) CONFIG_PPC64 \
- 82xx CONFIG_82xx \
- 8xx CONFIG_8xx" 6xx/7xx
+choice 'Processor Type' \
+ "6xx/7xx CONFIG_6xx \
+ 4xx CONFIG_4xx \
+ 630/Power3(64-Bit) CONFIG_PPC64 \
+ 82xx CONFIG_82xx \
+ 8xx CONFIG_8xx" 6xx/7xx
+
+if [ "$CONFIG_4xx" = "y" ]; then
+ choice 'Machine Type' \
+ "Oak CONFIG_OAK \
+ Walnut CONFIG_WALNUT" Oak
+fi
if [ "$CONFIG_8xx" = "y" ]; then
- choice 'Processor Model' \
- "821 CONFIG_MPC821 \
- 823 CONFIG_MPC823 \
- 850 CONFIG_MPC850 \
- 855 CONFIG_MPC855 \
- 860 CONFIG_MPC860 \
- 860T CONFIG_MPC860T" 860
define_bool CONFIG_SERIAL_CONSOLE y
- choice 'Machine Type' \
- "RPX-Lite CONFIG_RPXLITE \
- RPX-Classic CONFIG_RPXCLASSIC \
- BSE-IP CONFIG_BSEIP \
- MBX CONFIG_MBX \
- WinCept CONFIG_WINCEPT" RPX-Lite
-else
- choice 'Machine Type' \
- "PowerMac CONFIG_PMAC \
- PReP/MTX CONFIG_PREP \
- CHRP CONFIG_CHRP \
- PowerMac/PReP/CHRP CONFIG_ALL_PPC \
- Gemini CONFIG_GEMINI \
- APUS CONFIG_APUS" PowerMac
+
+ choice 'Processor Model' \
+ "821 CONFIG_MPC821 \
+ 823 CONFIG_MPC823 \
+ 850 CONFIG_MPC850 \
+ 855 CONFIG_MPC855 \
+ 860 CONFIG_MPC860 \
+ 860T CONFIG_MPC860T" 860
+
+ choice 'Machine Type' \
+ "RPX-Lite CONFIG_RPXLITE \
+ RPX-Classic CONFIG_RPXCLASSIC \
+ BSE-IP CONFIG_BSEIP \
+ MBX CONFIG_MBX \
+ WinCept CONFIG_WINCEPT" RPX-Lite
+fi
+if [ "$CONFIG_6xx" = "y" ]; then
+ choice 'Machine Type' \
+ "PowerMac CONFIG_PMAC \
+ PReP/MTX CONFIG_PREP \
+ CHRP CONFIG_CHRP \
+ PowerMac/PReP/CHRP CONFIG_ALL_PPC \
+ Gemini CONFIG_GEMINI \
+ APUS CONFIG_APUS" PowerMac
+fi
+
+if [ "$CONFIG_PPC64" = "y" ]; then
+ define_bool CONFIG_ALL_PPC y
fi
bool 'Symmetric multi-processing support' CONFIG_SMP
@@ -52,12 +66,8 @@ if [ "$CONFIG_ALL_PPC" != "y" ];then
define_bool CONFIG_MACH_SPECIFIC y
fi
-if [ "$CONFIG_8xx" = "y" ]; then
+if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then
bool 'Math emulation' CONFIG_MATH_EMULATION
-else
- if [ "$CONFIG_PPC64" != "y" ];then
- define_bool CONFIG_6xx y
- fi
fi
endmenu
@@ -75,12 +85,12 @@ comment 'General setup'
if [ "$CONFIG_APUS" = "y" ]; then
define_bool CONFIG_PCI n
-else
- if [ "$CONFIG_8xx" = "y" ]; then
+else if [ "$CONFIG_OAK" = "y" ]; then
+ define_bool CONFIG_PCI n
+else if [ "$CONFIG_8xx" = "y" ]; then
bool 'QSpan PCI' CONFIG_PCI
- else
+else
define_bool CONFIG_PCI y
- fi
fi
bool 'Networking support' CONFIG_NET
@@ -96,6 +106,8 @@ define_bool CONFIG_BINFMT_ELF y
define_bool CONFIG_KERNEL_ELF y
tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+source drivers/pci/Config.in
+
source drivers/pcmcia/Config.in
source drivers/parport/Config.in
diff --git a/arch/ppc/apus_defconfig b/arch/ppc/configs/apus_defconfig
index f86dbd55e..f86dbd55e 100644
--- a/arch/ppc/apus_defconfig
+++ b/arch/ppc/configs/apus_defconfig
diff --git a/arch/ppc/chrp_defconfig b/arch/ppc/configs/chrp_defconfig
index 48e305f44..48e305f44 100644
--- a/arch/ppc/chrp_defconfig
+++ b/arch/ppc/configs/chrp_defconfig
diff --git a/arch/ppc/common_defconfig b/arch/ppc/configs/common_defconfig
index 8b232d723..977626274 100644
--- a/arch/ppc/common_defconfig
+++ b/arch/ppc/configs/common_defconfig
@@ -12,6 +12,7 @@ CONFIG_EXPERIMENTAL=y
#
CONFIG_PPC=y
CONFIG_6xx=y
+# CONFIG_4xx is not set
# CONFIG_PPC64 is not set
# CONFIG_82xx is not set
# CONFIG_8xx is not set
@@ -22,7 +23,7 @@ CONFIG_ALL_PPC=y
# CONFIG_GEMINI is not set
# CONFIG_APUS is not set
# CONFIG_SMP is not set
-CONFIG_6xx=y
+# CONFIG_ALTIVEC is not set
#
# Loadable module support
@@ -34,11 +35,13 @@ CONFIG_KMOD=y
#
# General setup
#
+# CONFIG_PCI is not set
CONFIG_PCI=y
CONFIG_NET=y
CONFIG_SYSCTL=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
# CONFIG_BINFMT_MISC is not set
@@ -271,9 +274,7 @@ CONFIG_BMAC=y
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_YELLOWFIN is not set
# CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
# CONFIG_DM9102 is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
@@ -281,7 +282,6 @@ CONFIG_BMAC=y
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
@@ -292,12 +292,20 @@ CONFIG_DE4X5=y
# CONFIG_LNE390 is not set
# CONFIG_NE3210 is not set
# CONFIG_NE2K_PCI is not set
+# CONFIG_SIS900 is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_ES3210 is not set
# CONFIG_EPIC100 is not set
# CONFIG_ZNET is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -356,6 +364,7 @@ CONFIG_PPP=y
#
CONFIG_FB=y
CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
# CONFIG_FB_CLGEN is not set
# CONFIG_FB_PM2 is not set
CONFIG_FB_OF=y
@@ -367,13 +376,13 @@ 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_MILLENIUM=y
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_ATY128=y
+CONFIG_FB_3DFX=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FBCON_ADVANCED is not set
CONFIG_FBCON_CFB8=y
@@ -414,6 +423,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=y
# CONFIG_RTC is not set
@@ -438,9 +451,40 @@ CONFIG_NVRAM=y
# CONFIG_DRM is not set
#
-# USB drivers - not for the faint of heart
+# Support for USB
+#
+CONFIG_USB=y
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+CONFIG_USB_OHCI=y
+CONFIG_USB_OHCI_DEBUG=y
+# CONFIG_USB_OHCI_HCD is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEBUG_ISOC=y
+CONFIG_USB_PROC=y
+# CONFIG_USB_EZUSB is not set
+
+#
+# USB Devices
#
-# CONFIG_USB is not set
+CONFIG_USB_HUB=y
+CONFIG_USB_MOUSE=y
+CONFIG_USB_HP_SCANNER=m
+CONFIG_USB_KBD=y
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_CPIA is not set
+# CONFIG_USB_DC2XX is not set
+CONFIG_USB_SCSI=m
+CONFIG_USB_SCSI_DEBUG=y
#
# Filesystems
@@ -449,11 +493,9 @@ CONFIG_NVRAM=y
CONFIG_AUTOFS_FS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_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_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
@@ -466,7 +508,6 @@ 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
@@ -488,44 +529,9 @@ CONFIG_LOCKD=y
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
-CONFIG_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
+# CONFIG_NLS is not set
#
# Sound
diff --git a/arch/ppc/gemini_defconfig b/arch/ppc/configs/gemini_defconfig
index cebd77dfe..b3129c7a5 100644
--- a/arch/ppc/gemini_defconfig
+++ b/arch/ppc/configs/gemini_defconfig
@@ -3,24 +3,19 @@
#
#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+
+#
# Platform support
#
CONFIG_PPC=y
CONFIG_6xx=y
+# CONFIG_4xx is not set
# 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
@@ -28,24 +23,34 @@ CONFIG_6xx=y
CONFIG_GEMINI=y
# CONFIG_APUS is not set
# CONFIG_SMP is not set
+# CONFIG_ALTIVEC 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 is not set
CONFIG_PCI=y
CONFIG_NET=y
CONFIG_SYSCTL=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
# CONFIG_BINFMT_MISC is not set
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
# CONFIG_PARPORT is not set
# CONFIG_VGA_CONSOLE is not set
# CONFIG_FB is not set
@@ -83,6 +88,7 @@ CONFIG_KERNEL_ELF=y
# CONFIG_BLK_DEV_MD is not set
# CONFIG_BLK_DEV_RAM is not set
# CONFIG_BLK_DEV_XD is not set
+# CONFIG_BLK_DEV_DAC960 is not set
CONFIG_PARIDE_PARPORT=y
# CONFIG_PARIDE is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
@@ -181,12 +187,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
@@ -238,10 +243,11 @@ CONFIG_NCR885E=y
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
# CONFIG_YELLOWFIN is not set
-# CONFIG_ACENIC is not set
+# CONFIG_RTL8139 is not set
+# CONFIG_DM9102 is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
# CONFIG_NET_ISA is not set
# CONFIG_NET_EISA is not set
# CONFIG_NET_POCKET is not set
@@ -249,10 +255,14 @@ CONFIG_NCR885E=y
# CONFIG_HIPPI is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
# CONFIG_NET_RADIO is not set
#
-# Token ring devices
+# Token Ring driver support
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
@@ -262,10 +272,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,10 +294,14 @@ CONFIG_NCR885E=y
#
#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
# Character devices
#
-CONFIG_VT=y
-CONFIG_VT_CONSOLE=y
+# CONFIG_VT is not set
CONFIG_SERIAL=y
CONFIG_SERIAL_CONSOLE=y
# CONFIG_SERIAL_EXTENDED is not set
@@ -301,15 +312,13 @@ CONFIG_UNIX98_PTY_COUNT=256
#
# Mice
#
-CONFIG_BUSMOUSE=y
-# CONFIG_ATIXL_BUSMOUSE is not set
-# CONFIG_LOGIBUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
-CONFIG_MOUSE=y
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
+# 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
@@ -331,18 +340,10 @@ 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
#
-# USB drivers - not for the faint of heart
+# Support for USB
#
# CONFIG_USB is not set
@@ -354,6 +355,7 @@ CONFIG_PSMOUSE=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_EFS_FS is not set
CONFIG_ISO9660_FS=y
@@ -387,9 +389,6 @@ CONFIG_EXT2_FS=y
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
diff --git a/arch/ppc/mbx_defconfig b/arch/ppc/configs/mbx_defconfig
index 7080efb3e..7080efb3e 100644
--- a/arch/ppc/mbx_defconfig
+++ b/arch/ppc/configs/mbx_defconfig
diff --git a/arch/ppc/configs/oak_defconfig b/arch/ppc/configs/oak_defconfig
new file mode 100644
index 000000000..1c2daf125
--- /dev/null
+++ b/arch/ppc/configs/oak_defconfig
@@ -0,0 +1,293 @@
+#
+# Default configuration for the IBM PowerPC 403 "Oak" evaluation boards.
+#
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_4xx=y
+# CONFIG_6xx is not set
+# CONFIG_PPC64 is not set
+# CONFIG_82xx is not set
+# CONFIG_8xx is not set
+CONFIG_403=y
+# CONFIG_405 is not set
+CONFIG_OAK=y
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+# CONFIG_MATH_EMULATION is not set
+
+#
+# General setup
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+# CONFIG_PCI is not set
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+CONFIG_BINFMT_MISC=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+# CONFIG_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_TOTALMP is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_MOTOROLA_HOTSWAP is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_CPQ_DA is not set
+
+#
+# Additional Block Devices
+#
+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 is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+CONFIG_SYN_COOKIES=y
+
+#
+# (it is safe to leave these untouched)
+#
+# CONFIG_SKB_LARGE is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# 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_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_EISA is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring driver support
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+
+#
+# USB drivers - not for the faint of heart
+#
+# CONFIG_USB is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=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
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff --git a/arch/ppc/pmac_defconfig b/arch/ppc/configs/pmac_defconfig
index 514843d00..514843d00 100644
--- a/arch/ppc/pmac_defconfig
+++ b/arch/ppc/configs/pmac_defconfig
diff --git a/arch/ppc/prep_defconfig b/arch/ppc/configs/prep_defconfig
index 01c314cb3..01c314cb3 100644
--- a/arch/ppc/prep_defconfig
+++ b/arch/ppc/configs/prep_defconfig
diff --git a/arch/ppc/configs/walnut_defconfig b/arch/ppc/configs/walnut_defconfig
new file mode 100644
index 000000000..66edd11b6
--- /dev/null
+++ b/arch/ppc/configs/walnut_defconfig
@@ -0,0 +1,293 @@
+#
+# Default configuration for the IBM PowerPC 405GP "Walnut" evaluation board.
+#
+
+#
+# Platform support
+#
+CONFIG_PPC=y
+CONFIG_4xx=y
+# CONFIG_6xx is not set
+# CONFIG_PPC64 is not set
+# CONFIG_82xx is not set
+# CONFIG_8xx is not set
+CONFIG_403=y
+# CONFIG_405 is not set
+CONFIG_OAK=y
+# CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
+# CONFIG_MATH_EMULATION is not set
+
+#
+# General setup
+#
+# CONFIG_EXPERIMENTAL is not set
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+CONFIG_PCI=y
+CONFIG_NET=y
+CONFIG_SYSCTL=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_BINFMT_ELF=y
+CONFIG_KERNEL_ELF=y
+CONFIG_BINFMT_MISC=y
+
+#
+# PCMCIA/CardBus support
+#
+# CONFIG_PCMCIA is not set
+# CONFIG_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_TOTALMP is not set
+# CONFIG_BOOTX_TEXT is not set
+# CONFIG_MOTOROLA_HOTSWAP is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+# CONFIG_ISAPNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_IDE is not set
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_ONLY is not set
+# CONFIG_BLK_CPQ_DA is not set
+
+#
+# Additional Block Devices
+#
+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 is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# Networking options
+#
+# CONFIG_PACKET is not set
+# CONFIG_NETLINK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_FILTER is not set
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+CONFIG_IP_ALIAS=y
+CONFIG_SYN_COOKIES=y
+
+#
+# (it is safe to leave these untouched)
+#
+# CONFIG_SKB_LARGE is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_MACE is not set
+# CONFIG_BMAC is not set
+# 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_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_EISA is not set
+# CONFIG_NET_POCKET is not set
+# CONFIG_FDDI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring driver support
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Old CD-ROM drivers (not SCSI, not IDE)
+#
+# CONFIG_CD_NO_IDESCSI is not set
+
+#
+# Console drivers
+#
+
+#
+# Frame-buffer support
+#
+# CONFIG_FB is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+# CONFIG_QIC02_TAPE is not set
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+
+#
+# Joystick support
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+
+#
+# USB drivers - not for the faint of heart
+#
+# CONFIG_USB is not set
+
+#
+# Filesystems
+#
+# CONFIG_QUOTA is not set
+CONFIG_AUTOFS_FS=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
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+CONFIG_ROMFS_FS=y
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MAC_PARTITION=y
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_KGDB is not set
+# CONFIG_XMON is not set
diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig
index 8b232d723..2a3aac0f7 100644
--- a/arch/ppc/defconfig
+++ b/arch/ppc/defconfig
@@ -12,6 +12,7 @@ CONFIG_EXPERIMENTAL=y
#
CONFIG_PPC=y
CONFIG_6xx=y
+# CONFIG_4xx is not set
# CONFIG_PPC64 is not set
# CONFIG_82xx is not set
# CONFIG_8xx is not set
@@ -22,7 +23,7 @@ CONFIG_ALL_PPC=y
# CONFIG_GEMINI is not set
# CONFIG_APUS is not set
# CONFIG_SMP is not set
-CONFIG_6xx=y
+# CONFIG_ALTIVEC is not set
#
# Loadable module support
@@ -35,10 +36,12 @@ CONFIG_KMOD=y
# General setup
#
CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
CONFIG_NET=y
CONFIG_SYSCTL=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
# CONFIG_BINFMT_MISC is not set
@@ -271,9 +274,7 @@ CONFIG_BMAC=y
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_NET_VENDOR_RACAL is not set
-# CONFIG_YELLOWFIN is not set
# CONFIG_RTL8139 is not set
-# CONFIG_SIS900 is not set
# CONFIG_DM9102 is not set
# CONFIG_AT1700 is not set
# CONFIG_DEPCA is not set
@@ -281,7 +282,6 @@ CONFIG_BMAC=y
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
@@ -292,12 +292,20 @@ CONFIG_DE4X5=y
# CONFIG_LNE390 is not set
# CONFIG_NE3210 is not set
# CONFIG_NE2K_PCI is not set
+# CONFIG_SIS900 is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
# CONFIG_ES3210 is not set
# CONFIG_EPIC100 is not set
# CONFIG_ZNET is not set
# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -356,6 +364,7 @@ CONFIG_PPP=y
#
CONFIG_FB=y
CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
# CONFIG_FB_CLGEN is not set
# CONFIG_FB_PM2 is not set
CONFIG_FB_OF=y
@@ -367,13 +376,13 @@ 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_MILLENIUM=y
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_ATY128=y
+CONFIG_FB_3DFX=y
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FBCON_ADVANCED is not set
CONFIG_FBCON_CFB8=y
@@ -414,6 +423,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=y
# CONFIG_RTC is not set
@@ -438,9 +451,40 @@ CONFIG_NVRAM=y
# CONFIG_DRM is not set
#
-# USB drivers - not for the faint of heart
+# Support for USB
+#
+CONFIG_USB=y
+
+#
+# USB Controllers
+#
+# CONFIG_USB_UHCI is not set
+CONFIG_USB_OHCI=y
+CONFIG_USB_OHCI_DEBUG=y
+# CONFIG_USB_OHCI_HCD is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEBUG_ISOC=y
+CONFIG_USB_PROC=y
+# CONFIG_USB_EZUSB is not set
+
+#
+# USB Devices
#
-# CONFIG_USB is not set
+CONFIG_USB_HUB=y
+CONFIG_USB_MOUSE=y
+CONFIG_USB_HP_SCANNER=m
+CONFIG_USB_KBD=y
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_CPIA is not set
+# CONFIG_USB_DC2XX is not set
+CONFIG_USB_SCSI=m
+CONFIG_USB_SCSI_DEBUG=y
#
# Filesystems
@@ -449,11 +493,9 @@ CONFIG_NVRAM=y
CONFIG_AUTOFS_FS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_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_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
# CONFIG_EFS_FS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET is not set
@@ -466,7 +508,6 @@ 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
@@ -488,44 +529,9 @@ CONFIG_LOCKD=y
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MAC_PARTITION=y
CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
-CONFIG_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
+# CONFIG_NLS is not set
#
# Sound
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 3677276b5..a41473fa5 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -12,7 +12,17 @@
O_TARGET := kernel.o
OX_OBJS := ppc_ksyms.o setup.o
-KHEAD := head.o
+
+
+ifeq ($(CONFIG_4xx),y)
+ KHEAD := head_4xx.o
+else
+ ifeq ($(CONFIG_8xx),y)
+ KHEAD := head_8xx.o
+ else
+ KHEAD := head.o
+ endif
+endif
ifdef CONFIG_ALL_PPC
CONFIG_PMAC=y
@@ -47,48 +57,50 @@ ifdef CONFIG_SMP
O_OBJS += smp.o
endif
-ifeq ($(CONFIG_8xx),y)
-KHEAD := head_8xx.o
-O_OBJS += m8xx_setup.o ppc8xx_pic.o
-ifndef CONFIG_MATH_EMULATION
-O_OBJS += softemu8xx.o
-endif
-ifdef CONFIG_PCI
-O_OBJS += qspan_pci.c
+ifeq ($(CONFIG_OAK),y)
+ O_OBJS += oak_setup.o
endif
-ifdef CONFIG_MBX
-O_OBJS += i8259.o
+
+ifeq ($(CONFIG_8xx),y)
+ O_OBJS += m8xx_setup.o ppc8xx_pic.o
+ ifndef CONFIG_MATH_EMULATION
+ O_OBJS += softemu8xx.o
+ endif
+ ifdef CONFIG_PCI
+ O_OBJS += qspan_pci.c
+ endif
+ ifdef CONFIG_MBX
+ O_OBJS += i8259.o
+ endif
endif
-else
-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
+ O_OBJS += pmac_nvram.o
endif
-
-ifeq ($(CONFIG_PREP), y)
-O_OBJS += prep_pci.o prep_setup.o prep_nvram.o prep_time.o residual.o
+ifeq ($(CONFIG_6xx),y)
+ O_OBJS += open_pic.o indirect_pci.o
endif
-
-ifeq ($(CONFIG_PMAC), y)
+ifeq ($(CONFIG_APUS),y)
+ O_OBJS += apus_setup.o
endif
-
-ifeq ($(CONFIG_PMAC), y)
+ifeq ($(CONFIG_PMAC),y)
+ O_OBJS += pmac_pic.o pmac_setup.o pmac_time.o feature.o pmac_pci.o prom.o
endif
-
-ifdef CONFIG_APUS
-O_OBJS += apus_setup.o
+ifeq ($(CONFIG_CHRP),y)
+ O_OBJS += chrp_pci.o pmac_pci.o chrp_setup.o i8259.o \
+ chrp_time.o pmac_time.o prom.o
endif
+ifeq ($(CONFIG_PREP),y)
+ O_OBJS += prep_pci.o i8259.o prep_setup.o prep_nvram.o prep_time.o residual.o
+endif
+ifeq ($(CONFIG_GEMINI),y)
+ O_OBJS += gemini_prom.o gemini_pci.o gemini_setup.o
endif
all: $(KHEAD) kernel.o
head.o: head.S ppc_defs.h
-
+head_4xx.o: head_4xx.S ppc_defs.h
head_8xx.o: head_8xx.S ppc_defs.h
ppc_defs.h: mk_defs.c ppc_defs.head \
@@ -98,7 +110,7 @@ ppc_defs.h: mk_defs.c ppc_defs.head \
$(TOPDIR)/include/asm/ptrace.h
$(CC) $(CFLAGS) -S mk_defs.c
cp ppc_defs.head ppc_defs.h
- grep '^#define' mk_defs.s >>ppc_defs.h
+ grep '^#define' mk_defs.s >> ppc_defs.h
rm mk_defs.s
find_name : find_name.c
diff --git a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c
index 6a20863c5..7f6340261 100644
--- a/arch/ppc/kernel/align.c
+++ b/arch/ppc/kernel/align.c
@@ -1,9 +1,13 @@
/*
* align.c - handle alignment exceptions for the Power PC.
*
- * Paul Mackerras August 1996.
- * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au).
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Copyright (c) 1998-1999 TiVo, Inc.
+ * PowerPC 403GCX modifications.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * PowerPC 403GCX/405GP modifications.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <asm/ptrace.h>
@@ -16,6 +20,13 @@ struct aligninfo {
unsigned char flags;
};
+#if defined(CONFIG_4xx)
+#define OPCD(inst) (((inst) & 0xFC000000) >> 26)
+#define RS(inst) (((inst) & 0x03E00000) >> 21)
+#define RA(inst) (((inst) & 0x001F0000) >> 16)
+#define IS_DFORM(code) ((code) >= 32 && (code) <= 47)
+#endif
+
#define INVALID { 0, 0 }
#define LD 1 /* load */
@@ -170,6 +181,9 @@ int
fix_alignment(struct pt_regs *regs)
{
int instr, nb, flags;
+#if defined(CONFIG_4xx)
+ int opcode, f1, f2, f3;
+#endif
int i, t;
int reg, areg;
unsigned char *addr;
@@ -180,13 +194,42 @@ fix_alignment(struct pt_regs *regs)
unsigned char v[8];
} data;
+#if defined(CONFIG_4xx)
+ /* The 4xx-family processors have no DSISR register,
+ * so we emulate it.
+ */
+
+ instr = *((unsigned int *)regs->nip);
+ opcode = OPCD(instr);
+ reg = RS(instr);
+ areg = RA(instr);
+
+ if (IS_DFORM(opcode)) {
+ f1 = 0;
+ f2 = (instr & 0x04000000) >> 26;
+ f3 = (instr & 0x78000000) >> 27;
+ } else {
+ f1 = (instr & 0x00000006) >> 1;
+ f2 = (instr & 0x00000040) >> 6;
+ f3 = (instr & 0x00000780) >> 7;
+ }
+
+ instr = ((f1 << 5) | (f2 << 4) | f3);
+#else
+ reg = (regs->dsisr >> 5) & 0x1f; /* source/dest register */
+ areg = regs->dsisr & 0x1f; /* register to update */
instr = (regs->dsisr >> 10) & 0x7f;
+#endif
nb = aligninfo[instr].len;
if (nb == 0)
return 0; /* too hard or invalid instruction bits */
flags = aligninfo[instr].flags;
- addr = (unsigned char *) regs->dar;
- reg = (regs->dsisr >> 5) & 0x1f; /* source/dest register */
+
+ /* For the 4xx-family processors, the 'dar' field of the
+ * pt_regs structure is overloaded and is really from the DEAR.
+ */
+
+ addr = (unsigned char *)regs->dar;
/* Verify the address of the operand */
if (user_mode(regs)) {
@@ -280,7 +323,6 @@ fix_alignment(struct pt_regs *regs)
}
if (flags & U) {
- areg = regs->dsisr & 0x1f; /* register to update */
regs->gpr[areg] = regs->dar;
}
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index 6133f32ca..5ed04344e 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -386,13 +386,13 @@ _GLOBAL(fake_interrupt)
mtlr r0
blr
-#ifndef CONFIG_8xx
+
/*
* PROM code for specific machines follows. Put it
* here so it's easy to add arch-specific sections later.
* -- Cort
*/
-
+#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
/*
* On CHRP, the Run-Time Abstraction Services (RTAS) have to be
* called with the MMU off.
@@ -432,4 +432,4 @@ enter_rtas:
mtspr SRR0,r8
mtspr SRR1,r9
rfi /* return to caller */
-#endif /* CONFIG_8xx */
+#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */
diff --git a/arch/ppc/kernel/gemini_prom.S b/arch/ppc/kernel/gemini_prom.S
index 095f50e8f..f91e992f4 100644
--- a/arch/ppc/kernel/gemini_prom.S
+++ b/arch/ppc/kernel/gemini_prom.S
@@ -23,6 +23,7 @@
*
*/
+_GLOBAL(prom_init)
_GLOBAL(gemini_prom_init)
#ifdef __SMP__
/* Since the MMU's on, get stuff in rom space that we'll need */
diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c
index aee01f105..57ea34687 100644
--- a/arch/ppc/kernel/gemini_setup.c
+++ b/arch/ppc/kernel/gemini_setup.c
@@ -36,7 +36,6 @@
void gemini_setup_pci_ptrs(void);
-static int l2_printed = 0;
static unsigned char gemini_switch_map = 0;
static char *gemini_board_families[] = {
"VGM", "VSS", "KGM", "VGR", "KSS"
@@ -178,10 +177,8 @@ void __init gemini_setup_arch(void)
/* take special pains to map the MPIC, since it isn't mapped yet */
gemini_openpic_init();
-
/* start the L2 */
gemini_init_l2();
-
}
@@ -219,7 +216,6 @@ gemini_get_clock_speed(void)
return clock;
}
-
#define L2CR_PIPE_LATEWR (0x01800000) /* late-write SRAM */
#define L2CR_L2CTL (0x00100000) /* RAM control */
#define L2CR_INST_DISABLE (0x00400000) /* disable for insn's */
@@ -259,18 +255,17 @@ void __init gemini_init_l2(void)
probably always going to be late-write". --Dan */
if (reg & 0xc0) {
- if (!l2_printed) {
- printk("Enabling 750 L2 cache: %dKb\n",
- (128 << ((reg & 0xc0)>>6)));
- l2_printed=1;
- }
-
+ printk("Enabling 750 L2 cache: %dKb\n",
+ (128 << ((reg & 0xc0)>>6)));
/* take the size given */
cache = (((reg>>6) & 0x3)<<28);
}
else
+ {
+ printk("Enabling 750 L2 cache: 1M\n");
/* default of 1Mb */
cache = 0x3<<28;
+ }
reg &= 0x3;
@@ -278,6 +273,7 @@ void __init gemini_init_l2(void)
things. If found, tune it down to 1:1.5. -- Dan */
if (!reg) {
+printk("3\n");
speed = gemini_get_clock_speed();
if (speed >= 300) {
@@ -297,7 +293,10 @@ void __init gemini_init_l2(void)
write-through. This is fixed in IBM's 3.1 rev (I'm told), but
for now, always make 2.x versions use L2 write-through. --Dan */
if (((_get_PVR()>>8) & 0xf) <= 2)
+ {
cache |= L2CR_L2WT;
+ printk("L2 cache: Enabling Write-Through due to 750 Errata.\n");
+ }
#endif
cache |= L2CR_PIPE_LATEWR|L2CR_L2CTL|L2CR_INST_DISABLE;
_set_L2CR(0);
@@ -332,7 +331,7 @@ void __init gemini_init_IRQ(void)
/* gemini has no 8259 */
open_pic.irq_offset = 0;
- for( i=0; i < OPENPIC_VEC_SPURIOUS; i++ )
+ for( i=0; i < NR_IRQS; i++ )
irq_desc[i].ctl = &open_pic;
openpic_init(1);
#ifdef __SMP__
@@ -480,6 +479,39 @@ void __init gemini_calibrate_decr(void)
count_period_den = freq / 1000000;
}
+int gemini_get_irq( struct pt_regs *regs )
+{
+ int irq;
+
+ irq = openpic_irq( smp_processor_id() );
+ if (irq == OPENPIC_VEC_SPURIOUS)
+ /*
+ * Spurious interrupts should never be
+ * acknowledged
+ */
+ irq = -1;
+ /*
+ * I would like to openpic_eoi here but there seem to be timing problems
+ * between the openpic ack and the openpic eoi.
+ * -- Cort
+ */
+ return irq;
+}
+
+void gemini_post_irq(int irq)
+{
+ /*
+ * If it's an i8259 irq then we've already done the
+ * openpic irq. So we just check to make sure the controller
+ * is an openpic and if it is then eoi
+ *
+ * We do it this way since our irq_desc[irq].ctl can change
+ * with RTL and no longer be open_pic -- Cort
+ */
+ if ( irq >= open_pic.irq_offset)
+ openpic_eoi( smp_processor_id() );
+}
+
void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
@@ -506,8 +538,8 @@ void __init gemini_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.get_cpuinfo = gemini_get_cpuinfo;
ppc_md.irq_cannonicalize = NULL;
ppc_md.init_IRQ = gemini_init_IRQ;
- ppc_md.get_irq = chrp_get_irq;
- ppc_md.post_irq = chrp_post_irq;
+ ppc_md.get_irq = gemini_get_irq;
+ ppc_md.post_irq = gemini_post_irq;
ppc_md.init = NULL;
ppc_md.restart = gemini_restart;
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index 57ff53992..451a1cad4 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -137,7 +137,7 @@ __start:
#endif
/*
* We have to do any OF calls before we map ourselves to KERNELBASE,
- * because OF may have I/O devices mapped in in that area
+ * because OF may have I/O devices mapped into that area
* (particularly on CHRP).
*/
mr r31,r3 /* save parameters */
@@ -444,7 +444,9 @@ SystemCall:
STD_EXCEPTION(0xd00, SingleStep, SingleStepException)
STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
+#ifdef CONFIG_ALTIVEC
STD_EXCEPTION(0xf20, AltiVec, AltiVecUnavailable)
+#endif /* CONFIG_ALTIVEC */
/*
* Handle TLB miss for instruction on 603/603e.
@@ -1166,7 +1168,6 @@ __secondary_start:
mtspr SRR0,r3
mtspr SRR1,r4
rfi
-
#endif /* CONFIG_SMP */
/*
@@ -1351,6 +1352,42 @@ _GLOBAL(set_context)
SYNC
blr
+/*
+ * An undocumented "feature" of 604e requires that the v bit
+ * be cleared before changing BAT values.
+ *
+ * Also, newer IBM firmware does not clear bat3 and 4 so
+ * this makes sure it's done.
+ * -- Cort
+ */
+clear_bats:
+#if !defined(CONFIG_GEMINI)
+ li r20,0
+ mfspr r9,PVR
+ rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
+ cmpwi r9, 1
+ beq 1f
+
+ mtspr DBAT0U,r20
+ mtspr DBAT0L,r20
+ mtspr DBAT1U,r20
+ mtspr DBAT1L,r20
+ mtspr DBAT2U,r20
+ mtspr DBAT2L,r20
+ mtspr DBAT3U,r20
+ mtspr DBAT3L,r20
+1:
+ mtspr IBAT0U,r20
+ mtspr IBAT0L,r20
+ mtspr IBAT1U,r20
+ mtspr IBAT1L,r20
+ mtspr IBAT2U,r20
+ mtspr IBAT2L,r20
+ mtspr IBAT3U,r20
+ mtspr IBAT3L,r20
+#endif /* !defined(CONFIG_GEMINI) */
+ blr
+
/*
* We put a few things here that have to be page-aligned.
* This stuff goes at the beginning of the data segment,
@@ -1374,45 +1411,3 @@ swapper_pg_dir:
.globl cmd_line
cmd_line:
.space 512
-
-/*
- * An undocumented "feature" of 604e requires that the v bit
- * be cleared before changing BAT values.
- *
- * Also, newer IBM firmware does not clear bat3 and 4 so
- * this makes sure it's done.
- * -- Cort
- */
-clear_bats:
- mfmsr r20
- andi. r19,r20,MSR_DR
- beqlr
-
- li r20,0
-
- mtspr DBAT0U,r20
- mtspr DBAT0L,r20
- mtspr IBAT0U,r20
- mtspr IBAT0L,r20
- sync
- isync
-
- mtspr DBAT1U,r20
- mtspr DBAT1L,r20
- mtspr IBAT1U,r20
- mtspr IBAT1L,r20
- sync
- isync
-
- mtspr DBAT2U,r20
- mtspr DBAT2L,r20
- mtspr IBAT2U,r20
- mtspr IBAT2L,r20
-
- mtspr DBAT3U,r20
- mtspr DBAT3L,r20
- mtspr IBAT3U,r20
- mtspr IBAT3L,r20
-
- blr
-
diff --git a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S
new file mode 100644
index 000000000..abc651218
--- /dev/null
+++ b/arch/ppc/kernel/head_4xx.S
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
+ * Initial PowerPC version.
+ * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
+ * Rewritten for PReP
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Low-level exception handers, MMU support, and rewrite.
+ * Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
+ * PowerPC 8xx modifications.
+ * Copyright (c) 1998-1999 TiVo, Inc.
+ * PowerPC 403GCX modifications.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * PowerPC 403GCX/405GP modifications.
+ *
+ * Module name: head_4xx.S
+ *
+ * Description:
+ * Kernel execution entry point code.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include <linux/config.h>
+
+#include <asm/processor.h>
+#include <asm/4xx.h>
+#include <asm/403gcx.h>
+#include <asm/405gp.h>
+#include <asm/page.h>
+#include <asm/mmu.h>
+
+#include "ppc_asm.h"
+
+
+/* Preprocessor Defines */
+
+#define STND_EXC 0
+#define CRIT_EXC 1
+
+###
+### Check to make sure the right processor has been defined.
+###
+
+#if !defined(CONFIG_4xx)
+#error "This file is only appropriate for kernels supporting the PPC4xx."
+#endif
+
+###
+### Execution entry point.
+###
+
+###
+### As with the other PowerPC ports, it is expected that when code
+### execution begins here, the following registers contain valid, yet
+### optional, information:
+###
+### r3 - ???
+### r4 - Starting address of the init RAM disk
+### r5 - Ending address of the init RAM disk
+### r6 - Start of kernel command line string (e.g. "mem=96m")
+### r7 - End of kernel command line string
+###
+
+ .text
+_GLOBAL(_stext)
+_GLOBAL(_start)
+ ## Save residual data, init RAM disk, and command line parameters
+
+ mr r31,r3
+ mr r30,r4
+ mr r29,r5
+ mr r28,r6
+ mr r27,r7
+
+ ## Set the ID for this CPU
+
+ li r24,0
+
+ ## Establish exception vector base
+
+ lis r0,KERNELBASE@h
+ mtspr SPRN_EVPR,r0
+
+ ## Jump to the main PowerPC kernel start-up code
+
+1: lis r7,start_here@ha
+ addi r7,r7,start_here@l
+ mtlr r7
+ blr
+
+###
+### Exception vector entry code. This code runs with address translation
+### turned off (i.e. using physical addresses). We assume SPRG3 has the
+### physical address of the current task thread_struct.
+###
+
+ ## Common exception code for all exception types.
+
+#define COMMON_PROLOG \
+0: mtspr SPRN_SPRG0,r20; /* We need r20, move it to SPRG0 */\
+ mtspr SPRN_SPRG1,r21; /* We need r21, move it to SPRG1 */\
+ mfcr r20; /* We need the CR, move it to r20 */\
+ mfspr r21,SPRN_SPRG2; /* Exception stack to use */\
+ cmpwi cr0,r21,0; /* From user mode or RTAS? */\
+ bne 1f; /* Not RTAS, branch */\
+ tophys(r21, r1); /* Convert vka in r1 to pka in r21 */\
+ subi r21,r21,INT_FRAME_SIZE; /* Allocate an exception frame */\
+1: stw r20,_CCR(r21); /* Save CR on the stack */\
+ stw r22,GPR22(r21); /* Save r22 on the stack */\
+ stw r23,GPR23(r21); /* r23 Save on the stack */\
+ mfspr r20,SPRN_SPRG0; /* Get r20 back out of SPRG0 */\
+ stw r20,GPR20(r21); /* Save r20 on the stack */\
+ mfspr r22,SPRN_SPRG1; /* Get r21 back out of SPRG0 */\
+ stw r22,GPR21(r21); /* Save r21 on the stack */\
+ mflr r20; \
+ stw r20,_LINK(r21); /* Save LR on the stack */\
+ mfctr r22; \
+ stw r22,_CTR(r21); /* Save CTR on the stack */\
+ mfspr r20,XER; \
+ stw r20,_XER(r21); /* Save XER on the stack */
+
+#define COMMON_EPILOG \
+ stw r0,GPR0(r21); /* Save r0 on the stack */\
+ stw r1,GPR1(r21); /* Save r1 on the stack */\
+ stw r2,GPR2(r21); /* Save r2 on the stack */\
+ stw r1,0(r21); \
+ tovirt(r1,r21); /* Set-up new kernel stack pointer */\
+ SAVE_4GPRS(3, r21); /* Save r3 through r6 on the stack */
+
+ ## Common exception code for standard (non-critical) exceptions.
+
+#define STND_EXCEPTION_PROLOG \
+ COMMON_PROLOG; \
+ mfspr r22,SPRN_SRR0; /* Faulting instruction address */\
+ mfspr r23,SPRN_SRR1; /* MSR at the time of fault */\
+ COMMON_EPILOG;
+
+ ## Common exception code for critical exceptions.
+
+#define CRIT_EXCEPTION_PROLOG \
+ COMMON_PROLOG; \
+ mfspr r22,SPRN_SRR2; /* Faulting instruction address */\
+ mfspr r23,SPRN_SRR3; /* MSR at the time of fault */\
+ COMMON_EPILOG;
+
+###
+### Macros for specific exception types
+###
+
+#define START_EXCEPTION(n, label) \
+ . = n; \
+label:
+
+
+#define FINISH_EXCEPTION(func) \
+ bl transfer_to_handler; \
+ .long func; \
+ .long ret_from_except
+
+
+#define STND_EXCEPTION(n, label, func) \
+ START_EXCEPTION(n, label); \
+ STND_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ li r0,STND_EXC; \
+ li r20,MSR_KERNEL; \
+ FINISH_EXCEPTION(func)
+
+
+#define CRIT_EXCEPTION(n, label, func) \
+ START_EXCEPTION(n, label); \
+ CRIT_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ li r0,CRIT_EXC; \
+ li r20,MSR_KERNEL; \
+ FINISH_EXCEPTION(func)
+
+
+#define INTR_EXCEPTION(n, label, func) \
+ START_EXCEPTION(n, label); \
+ STND_EXCEPTION_PROLOG; \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ li r0,STND_EXC; \
+ li r20,MSR_KERNEL; \
+ li r4,0; \
+ bl transfer_to_handler; \
+_GLOBAL(do_IRQ_intercept); \
+ .long func; \
+ .long ret_from_except
+
+
+###
+### Exception vectors.
+###
+
+### 0x0100 - Critical Interrupt Exception
+
+ CRIT_EXCEPTION(0x0100, CriticalInterrupt, UnknownException)
+
+### 0x0200 - Machine Check Exception
+
+ CRIT_EXCEPTION(0x0200, MachineCheck, MachineCheckException)
+
+### 0x0300 - Data Storage Exception
+
+ START_EXCEPTION(0x0300, DataAccess)
+ STND_EXCEPTION_PROLOG
+ mfspr r5,SPRN_ESR # Grab the ESR, save it, pass as arg3
+ stw r5,_ESR(r21)
+ mfspr r4,SPRN_DEAR # Grab the DEAR, save it, pass as arg2
+ stw r4,_DEAR(r21)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r0,STND_EXC # This is a standard exception
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR
+ FINISH_EXCEPTION(do_page_fault) # do_page_fault(regs, ESR, DEAR)
+
+### 0x0400 - Instruction Storage Exception
+
+ START_EXCEPTION(0x0400, InstructionAccess)
+ STND_EXCEPTION_PROLOG
+ mr r4,r22 # Pass SRR0 as arg2
+ mr r5,r23 # Pass SRR1 as arg3
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r0,STND_EXC # This is a standard exception
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR
+ FINISH_EXCEPTION(do_page_fault) # do_page_fault(regs, SRR0, SRR1)
+
+### 0x0500 - External Interrupt Exception
+
+ INTR_EXCEPTION(0x0500, HardwareInterrupt, do_IRQ)
+
+### 0x0600 - Alignment Exception
+
+ START_EXCEPTION(0x0600, Alignment)
+ STND_EXCEPTION_PROLOG
+ mfspr r4,SPRN_DEAR # Grab the DEAR and save it
+ stw r4,_DEAR(r21)
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r0,STND_EXC # This is a standard exception
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR
+ FINISH_EXCEPTION(AlignmentException)
+
+### 0x0700 - Program Exception
+
+ START_EXCEPTION(0x0700, ProgramCheck)
+ STND_EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r0,STND_EXC # This is a standard exception
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR
+ FINISH_EXCEPTION(ProgramCheckException)
+
+ STND_EXCEPTION(0x0800, Trap_08, UnknownException)
+ STND_EXCEPTION(0x0900, Trap_09, UnknownException)
+ STND_EXCEPTION(0x0A00, Trap_0A, UnknownException)
+ STND_EXCEPTION(0x0B00, Trap_0B, UnknownException)
+### 0x0C00 - System Call Exception
+
+ START_EXCEPTION(0x0C00, SystemCall)
+ STND_EXCEPTION_PROLOG
+ stw r3,ORIG_GPR3(r21)
+ li r0,STND_EXC # This is a standard exception
+ li r20,MSR_KERNEL
+ rlwimi r20,r23,0,16,16 # Copy EE bit from the saved MSR
+ FINISH_EXCEPTION(DoSyscall)
+
+ STND_EXCEPTION(0x0D00, Trap_0D, UnknownException)
+ STND_EXCEPTION(0x0E00, Trap_0E, UnknownException)
+ STND_EXCEPTION(0x0F00, Trap_0F, UnknownException)
+
+#if 0
+### 0x1000 - Programmable Interval Timer (PIT) Exception
+
+ STND_EXCEPTION(0x1000, PITException, UnknownException)
+
+### 0x1010 - Fixed Interval Timer (FIT) Exception
+
+ STND_EXCEPTION(0x1010, FITException, UnknownException)
+
+### 0x1020 - Watchdog Timer (WDT) Exception
+
+ CRIT_EXCEPTION(0x1020, WDTException, UnknownException)
+#endif
+
+### 0x1100 - Data TLB Miss Exception
+
+ START_EXCEPTION(0x1100, DTLBMiss)
+ STND_EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r0,STND_EXC
+ li r20,MSR_KERNEL
+ FINISH_EXCEPTION(UnknownException)
+
+### 0x1200 - Instruction TLB Miss Exception
+
+ START_EXCEPTION(0x1200, ITLBMiss)
+ STND_EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ li r0,STND_EXC
+ li r20,MSR_KERNEL
+ FINISH_EXCEPTION(UnknownException)
+
+ STND_EXCEPTION(0x1300, Trap_13, UnknownException)
+ STND_EXCEPTION(0x1400, Trap_14, UnknownException)
+ STND_EXCEPTION(0x1500, Trap_15, UnknownException)
+ STND_EXCEPTION(0x1600, Trap_16, UnknownException)
+ STND_EXCEPTION(0x1700, Trap_17, UnknownException)
+ STND_EXCEPTION(0x1800, Trap_18, UnknownException)
+ STND_EXCEPTION(0x1900, Trap_19, UnknownException)
+ STND_EXCEPTION(0x1A00, Trap_1A, UnknownException)
+ STND_EXCEPTION(0x1B00, Trap_1B, UnknownException)
+ STND_EXCEPTION(0x1C00, Trap_1C, UnknownException)
+ STND_EXCEPTION(0x1D00, Trap_1D, UnknownException)
+ STND_EXCEPTION(0x1E00, Trap_1E, UnknownException)
+ STND_EXCEPTION(0x1F00, Trap_1F, UnknownException)
+
+### 0x2000 - Debug Exception
+
+ CRIT_EXCEPTION(0x2000, DebugTrap, UnknownException)
+
+###
+### Other PowerPC processors, namely those derived from the 6xx-series
+### have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
+### However, for the 4xx-series processors these are neither defined nor
+### reserved.
+###
+
+###
+### This code finishes saving the registers to the exception frame
+### and jumps to the appropriate handler for the exception, turning
+### on address translation.
+###
+
+_GLOBAL(transfer_to_handler)
+ stw r22,_NIP(r21) # Save the faulting IP on the stack
+ stw r23,_MSR(r21) # Save the exception MSR on the stack
+ SAVE_GPR(7, r21) # Save r7 on the stack
+ SAVE_4GPRS(8, r21) # Save r8 through r11 on the stack
+ SAVE_8GPRS(12, r21) # Save r12 through r19 on the stack
+ SAVE_8GPRS(24, r21) # Save r24 through r31 on the stack
+ andi. r23,r23,MSR_PR # Is this from user space?
+ mfspr r23,SPRN_SPRG3 # If from user, fix up THREAD.regs
+ beq 2f # No, it is from the kernel; branch.
+ addi r24,r1,STACK_FRAME_OVERHEAD
+ stw r24,PT_REGS(r23) #
+2: addi r2,r23,-THREAD # Set r2 to current thread
+ tovirt(r2,r2)
+ mflr r23
+ andi. r24,r23,0x3f00 # Get vector offset
+ stw r24,TRAP(r21)
+ li r22,RESULT
+ stwcx. r22,r22,r21 # Clear the reservation
+ li r22,0
+ stw r22,RESULT(r21)
+ mtspr SPRN_SPRG2,r22 # r1 is now the kernel stack pointer
+ addi r24,r2,TASK_STRUCT_SIZE # Check for kernel stack overflow
+ cmplw cr0,r1,r2
+ cmplw cr1,r1,r24
+ crand cr1,cr1,cr4
+ bgt- stack_ovf # If r2 < r1 < r2 + TASK_STRUCT_SIZE
+ lwz r24,0(r23) # Virtual address of the handler
+ lwz r23,4(r23) # Handler return pointer
+ cmpwi cr0,r0,STND_EXC # What type of exception is this?
+ bne 3f # It is a critical exception...
+
+ ## Standard exception jump path
+
+ mtspr SPRN_SRR0,r24 # Set up the instruction pointer
+ mtspr SPRN_SRR1,r20 # Set up the machine state register
+ mtlr r23 # Set up the return pointer
+ SYNC
+ rfi # Enable the MMU, jump to the handler
+
+ ## Critical exception jump path
+
+3: mtspr SPRN_SRR2,r24 # Set up the instruction pointer
+ mtspr SPRN_SRR3,r20 # Set up the machine state register
+ mtlr r23 # Set up the return pointer
+ SYNC
+ rfci # Enable the MMU, jump to the handler
+
+###
+### On kernel stack overlow, load up an initial stack pointer and call
+### StackOverflow(regs), which should NOT return.
+###
+
+stack_ovf:
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ lis r1,init_task_union@ha
+ addi r1,r1,init_task_union@l
+ addi r1,r1,TASK_UNION_SIZE - STACK_FRAME_OVERHEAD
+ lis r24,StackOverflow@ha
+ addi r24,r24,StackOverflow@l
+ li r20,MSR_KERNEL
+ mtspr SPRN_SRR0,r24 # Set up the instruction pointer
+ mtspr SPRN_SRR1,r20 # Set up the machine state register
+ SYNC
+ rfi # Enable the MMU, jump to StackOverflow
+
+###
+### extern void giveup_altivec(struct task_struct *prev)
+###
+### The PowerPC 4xx family of processors do not have AltiVec capabilities, so
+### this just returns.
+###
+
+_GLOBAL(giveup_altivec)
+ blr
+
+###
+### extern void giveup_fpu(struct task_struct *prev)
+###
+### The PowerPC 4xx family of processors do not have an FPU, so this just
+### returns.
+###
+
+_GLOBAL(giveup_fpu)
+ blr
+
+###
+### extern void abort(void)
+###
+### At present, this routine just applies a system reset.
+###
+
+_GLOBAL(abort)
+ mfspr r13,SPRN_DBCR
+ ori r13,r13,DBCR_RST(SYSTEM)@h
+ mtspr SPRN_DBCR,r13
+
+
+###
+### This code is jumped-to from the startup code. It copies the kernel
+### image from wherever it happens to be currently running at in physical
+### address space to physical address 0.
+###
+### In general, for a running Linux/PPC system:
+### Kernel Physical Address (KPA) = 0x00000000
+### Kernel Virtual Address (KVA) = 0xC0000000
+###
+
+#if 0
+relocate_kernel:
+ lis r9,0x426f /* if booted from BootX, don't */
+ addi r9,r9,0x6f58 /* translate source addr */
+ cmpw r31,r9 /* (we have to on chrp) */
+ beq 7f
+ rlwinm r4,r4,0,8,31 /* translate source address */
+ add r4,r4,r3 /* to region mapped with BATs */
+7: addis r9,r26,klimit@ha /* fetch klimit */
+ lwz r25,klimit@l(r9)
+ addis r25,r25,-KERNELBASE@h
+ li r6,0 /* Destination offset */
+ li r5,0x4000 /* # bytes of memory to copy */
+ bl copy_and_flush /* copy the first 0x4000 bytes */
+ addi r0,r3,4f@l /* jump to the address of 4f */
+ mtctr r0 /* in copy and do the rest. */
+ bctr /* jump to the copy */
+4: mr r5,r25
+ bl copy_and_flush /* copy the rest */
+ b turn_on_mmu
+
+/*
+ * Copy routine used to copy the kernel to start at physical address 0
+ * and flush and invalidate the caches as needed.
+ * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset
+ * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5.
+ */
+copy_and_flush:
+ addi r5,r5,-4
+ addi r6,r6,-4
+4: li r0,8
+ mtctr r0
+3: addi r6,r6,4 /* copy a cache line */
+ lwzx r0,r6,r4
+ stwx r0,r6,r3
+ bdnz 3b
+ dcbst r6,r3 /* write it to memory */
+ sync
+ icbi r6,r3 /* flush the icache line */
+ cmplw 0,r6,r5
+ blt 4b
+ isync
+ addi r5,r5,4
+ addi r6,r6,4
+ blr
+#endif
+
+###
+### This is where the main kernel code starts.
+###
+
+start_here:
+ ## Establish a pointer to the current task
+
+ lis r2,init_task_union@h
+ ori r2,r2,init_task_union@l
+
+ ## Clear out the BSS as per ANSI C requirements
+
+ lis r7,_end@ha
+ addi r7,r7,_end@l
+ lis r8,__bss_start@ha
+ addi r8,r8,__bss_start@l
+ subf r7,r8,r7
+ addi r7,r7,3
+ srwi. r7,r7,2
+ beq 2f
+ addi r8,r8,-4
+ mtctr r7
+ li r0,0
+3: stwu r0,4(r8)
+ bdnz 3b
+
+ ## Stack
+
+2: addi r1,r2,TASK_UNION_SIZE
+ li r0,0
+ stwu r0,-STACK_FRAME_OVERHEAD(r1)
+
+ ## Determine what type of platform this is.
+
+ mr r3,r31
+ mr r4,r30
+ mr r5,r29
+ mr r6,r28
+ mr r7,r27
+ bl identify_machine
+
+ ## Initialize the memory management unit.
+
+ bl MMU_init
+
+ ## Go back to running unmapped so that we can change to our
+ ## exception vectors.
+
+ lis r4,2f@h
+ ori r4,r4,2f@l
+ tophys(r4,r4)
+ li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
+ mtspr SPRN_SRR0,r4 # Set up the instruction pointer
+ mtspr SPRN_SRR1,r3 # Set up the machine state register
+ rfi
+
+ ## Load up the kernel context
+
+2: SYNC # Force all PTE updates to finish
+# tlbia # Clear all TLB entries
+# sync # Wait for tlbia to finish...
+
+ ## Set up for using our exception vectors
+
+ tophys(r4,r2) # Pointer to physical current thread
+ addi r4,r4,THREAD # The init task thread
+ mtspr SPRN_SPRG3,r4 # Save it for exceptions later
+ li r3,0 #
+ mtspr SPRN_SPRG2,r3 # 0 implies r1 has kernel stack pointer
+
+ ## Really turn on the MMU and jump into the kernel
+
+ lis r4,MSR_KERNEL@h
+ ori r4,r4,MSR_KERNEL@l
+ lis r3,start_kernel@h
+ ori r3,r3,start_kernel@l
+ mtspr SPRN_SRR0,r3 # Set up the instruction pointer
+ mtspr SPRN_SRR1,r4 # Set up the machine state register
+ rfi # Enable the MMU, jump to the kernel
+
+_GLOBAL(set_context)
+ mtspr SPRN_PID,r3
+ tlbia
+ SYNC
+ blr
+
+###
+### We put a few things here that have to be page-aligned. This stuff
+### goes at the beginning of the data segment, which is page-aligned.
+###
+
+ .data
+_GLOBAL(sdata)
+_GLOBAL(empty_zero_page)
+ .space 4096
+_GLOBAL(swapper_pg_dir)
+ .space 4096
+
+###
+### This space gets a copy of optional info passed to us by the bootstrap
+### which is used to pass parameters into the kernel like root=/dev/sda1, etc.
+###
+
+_GLOBAL(cmd_line)
+ .space 512
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 89994881b..444654ec6 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -103,8 +103,7 @@ _GLOBAL(__no_use_sti)
* We were about to enable interrupts but we have to simulate
* some interrupts that were lost by enable_irq first.
*/
- .globl do_lost_interrupts
-do_lost_interrupts:
+_GLOBAL(do_lost_interrupts)
stwu r1,-16(r1)
mflr r0
stw r0,20(r1)
@@ -405,8 +404,10 @@ _GLOBAL(atomic_set_mask)
* The *_ns versions don't do byte-swapping.
*/
_GLOBAL(_insb)
+ cmpw 0,r5,0
mtctr r5
subi r4,r4,1
+ blelr-
00: lbz r5,0(r3)
eieio
stbu r5,1(r4)
@@ -414,8 +415,10 @@ _GLOBAL(_insb)
blr
_GLOBAL(_outsb)
+ cmpw 0,r5,0
mtctr r5
subi r4,r4,1
+ blelr-
00: lbzu r5,1(r4)
stb r5,0(r3)
eieio
@@ -423,8 +426,10 @@ _GLOBAL(_outsb)
blr
_GLOBAL(_insw)
+ cmpw 0,r5,0
mtctr r5
subi r4,r4,2
+ blelr-
00: lhbrx r5,0,r3
eieio
sthu r5,2(r4)
@@ -432,8 +437,10 @@ _GLOBAL(_insw)
blr
_GLOBAL(_outsw)
+ cmpw 0,r5,0
mtctr r5
subi r4,r4,2
+ blelr-
00: lhzu r5,2(r4)
eieio
sthbrx r5,0,r3
@@ -441,8 +448,10 @@ _GLOBAL(_outsw)
blr
_GLOBAL(_insl)
+ cmpw 0,r5,0
mtctr r5
subi r4,r4,4
+ blelr-
00: lwbrx r5,0,r3
eieio
stwu r5,4(r4)
@@ -450,8 +459,10 @@ _GLOBAL(_insl)
blr
_GLOBAL(_outsl)
+ cmpw 0,r5,0
mtctr r5
subi r4,r4,4
+ blelr-
00: lwzu r5,4(r4)
stwbrx r5,0,r3
eieio
@@ -460,8 +471,10 @@ _GLOBAL(_outsl)
_GLOBAL(ide_insw)
_GLOBAL(_insw_ns)
+ cmpw 0,r5,0
mtctr r5
subi r4,r4,2
+ blelr-
00: lhz r5,0(r3)
eieio
sthu r5,2(r4)
@@ -470,8 +483,10 @@ _GLOBAL(_insw_ns)
_GLOBAL(ide_outsw)
_GLOBAL(_outsw_ns)
+ cmpw 0,r5,0
mtctr r5
subi r4,r4,2
+ blelr-
00: lhzu r5,2(r4)
sth r5,0(r3)
eieio
@@ -479,8 +494,10 @@ _GLOBAL(_outsw_ns)
blr
_GLOBAL(_insl_ns)
+ cmpw 0,r5,0
mtctr r5
subi r4,r4,4
+ blelr-
00: lwz r5,0(r3)
eieio
stwu r5,4(r4)
@@ -488,8 +505,10 @@ _GLOBAL(_insl_ns)
blr
_GLOBAL(_outsl_ns)
+ cmpw 0,r5,0
mtctr r5
subi r4,r4,4
+ blelr-
00: lwzu r5,4(r4)
stw r5,0(r3)
eieio
@@ -758,8 +777,19 @@ _GLOBAL(_set_L2CR)
* We restore and save the fpscr so the task gets the same result
* and exceptions as if the cpu had performed the load or store.
*/
+
+#if defined(CONFIG_4xx)
+_GLOBAL(cvt_fd)
+ lfs 0,0(r3)
+ stfd 0,0(r4)
+ blr
+
+_GLOBAL(cvt_df)
+ lfd 0,0(r3)
+ stfs 0,0(r4)
+ blr
+#else
_GLOBAL(cvt_fd)
-cvt_fd:
lfd 0,-4(r5) /* load up fpscr value */
mtfsf 0xff,0
lfs 0,0(r3)
@@ -769,7 +799,6 @@ cvt_fd:
blr
_GLOBAL(cvt_df)
-cvt_df:
lfd 0,-4(r5) /* load up fpscr value */
mtfsf 0xff,0
lfd 0,0(r3)
@@ -777,9 +806,9 @@ cvt_df:
mffs 0 /* save new fpscr value */
stfd 0,-4(r5)
blr
+#endif
- .globl __clear_msr_me
-__clear_msr_me:
+_GLOBAL(__clear_msr_me)
mfmsr r0 /* Get current interrupt state */
lis r3,0
ori r3,r3,MSR_ME
@@ -843,8 +872,7 @@ SYSCALL(read)
/* Why isn't this a) automatic, b) written in 'C'? */
.data
.align 4
- .globl sys_call_table
-sys_call_table:
+_GLOBAL(sys_call_table)
.long sys_ni_syscall /* 0 - old "setup()" system call */
.long sys_exit
.long sys_fork
@@ -921,7 +949,7 @@ sys_call_table:
.long sys_sigpending
.long sys_sethostname
.long sys_setrlimit /* 75 */
- .long sys_getrlimit
+ .long sys_old_getrlimit
.long sys_getrusage
.long sys_gettimeofday
.long sys_settimeofday
@@ -1039,4 +1067,5 @@ sys_call_table:
.long sys_ni_syscall /* streams1 */
.long sys_ni_syscall /* streams2 */
.long sys_vfork
- .space (NR_syscalls-183)*4
+ .long sys_getrlimit /* 190 */
+ .space (NR_syscalls-190)*4
diff --git a/arch/ppc/kernel/mk_defs.c b/arch/ppc/kernel/mk_defs.c
index 849e268fe..34682bd2a 100644
--- a/arch/ppc/kernel/mk_defs.c
+++ b/arch/ppc/kernel/mk_defs.c
@@ -88,7 +88,9 @@ main(void)
DEFINE(GPR29, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[29]));
DEFINE(GPR30, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[30]));
DEFINE(GPR31, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[31]));
- /* Note: these symbols include _ because they overlap with special register names */
+ /* Note: these symbols include _ because they overlap with special
+ * register names
+ */
DEFINE(_NIP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, nip));
DEFINE(_MSR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, msr));
DEFINE(_CTR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, ctr));
@@ -97,6 +99,12 @@ main(void)
DEFINE(_XER, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, xer));
DEFINE(_DAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
DEFINE(_DSISR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
+ /* The PowerPC 400-class processors have neither the DAR nor the DSISR
+ * SPRs. Hence, we overload them to hold the similar DEAR and ESR SPRs
+ * for such processors.
+ */
+ DEFINE(_DEAR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dar));
+ DEFINE(_ESR, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, dsisr));
DEFINE(ORIG_GPR3, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, orig_gpr3));
DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result));
DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap));
diff --git a/arch/ppc/kernel/oak_setup.c b/arch/ppc/kernel/oak_setup.c
new file mode 100644
index 000000000..a9c9137a0
--- /dev/null
+++ b/arch/ppc/kernel/oak_setup.c
@@ -0,0 +1,84 @@
+/*
+ *
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ * Module name: oak_setup.c
+ *
+ * Description:
+ * Architecture- / platform-specific boot-time initialization code for
+ * the IBM PowerPC 403GCX "Oak" evaluation board. Adapted from original
+ * code by Gary Thomas, Cort Dougan <cort@cs.nmt.edu>, and Dan Malek
+ * <dmalek@jlc.net>.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/machdep.h>
+#include <asm/page.h>
+
+#include "oak_setup.h"
+
+
+void __init
+oak_init(unsigned long r3, unsigned long r4, unsigned long r5,
+ unsigned long r6, unsigned long r7)
+{
+#if 0
+#if defined(CONFIG_BLK_DEV_INITRD)
+ /*
+ * If the init RAM disk has been configured in, and there's a valid
+ * starting address for it, set it up.
+ */
+ if (r4) {
+ initrd_start = r4 + KERNELBASE;
+ initrd_end = r5 + KERNELBASE;
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+ /* Copy the kernel command line arguments to a safe place. */
+
+ if (r6) {
+ *(char *)(r7 + KERNELBASE) = 0;
+ strcpy(cmd_line, (char *)(r6 + KERNELBASE));
+ }
+#endif /* 0 */
+
+ ppc_md.setup_arch = oak_setup_arch;
+ ppc_md.setup_residual = NULL;
+ ppc_md.get_cpuinfo = NULL;
+ ppc_md.irq_cannonicalize = NULL;
+ ppc_md.init_IRQ = NULL;
+ ppc_md.get_irq = NULL;
+ ppc_md.init = NULL;
+
+ ppc_md.restart = NULL;
+ ppc_md.power_off = NULL;
+ ppc_md.halt = NULL;
+
+ ppc_md.time_init = NULL;
+ ppc_md.set_rtc_time = NULL;
+ ppc_md.get_rtc_time = NULL;
+ ppc_md.calibrate_decr = NULL;
+
+ ppc_md.kbd_setkeycode = NULL;
+ ppc_md.kbd_getkeycode = NULL;
+ ppc_md.kbd_translate = NULL;
+ ppc_md.kbd_unexpected_up = NULL;
+ ppc_md.kbd_leds = NULL;
+ ppc_md.kbd_init_hw = NULL;
+
+#if defined(CONFIG_MAGIC_SYSRQ)
+ ppc_md.kbd_sysrq_xlate = NULL;
+#endif
+
+ return;
+}
+
+void __init
+oak_setup_arch(void)
+{
+
+}
diff --git a/arch/ppc/kernel/oak_setup.h b/arch/ppc/kernel/oak_setup.h
new file mode 100644
index 000000000..10f7d7354
--- /dev/null
+++ b/arch/ppc/kernel/oak_setup.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ * Module name: oak_setup.c
+ *
+ * Description:
+ * Architecture- / platform-specific boot-time initialization code for
+ * the IBM PowerPC 403GCX "Oak" evaluation board. Adapted from original
+ * code by Gary Thomas, Cort Dougan <cort@cs.nmt.edu>, and Dan Malek
+ * <dmalek@jlc.net>.
+ *
+ */
+
+#ifndef __OAK_SETUP_H__
+#define __OAK_SETUP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void oak_init(unsigned long r3,
+ unsigned long ird_start, unsigned long ird_end,
+ unsigned long cline_start, unsigned long cline_end);
+extern void oak_setup_arch(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OAK_SETUP_H__ */
diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c
index 9f3f58a38..4b0375433 100644
--- a/arch/ppc/kernel/open_pic.c
+++ b/arch/ppc/kernel/open_pic.c
@@ -63,9 +63,15 @@ struct hw_interrupt_type open_pic = {
#define check_arg_pri(pri) \
if (pri < 0 || pri >= OPENPIC_NUM_PRI) \
printk("openpic.c:%d: illegal priority %d\n", __LINE__, pri);
-#define check_arg_irq(irq) \
+/*
+ * Turned this check off since the IPI's are treated as irqs
+ * but they're above NumSources -- Cort
+ */
+#define check_arg_irq(irq)
+#if 0
if (irq < 0 || irq >= (NumSources+open_pic.irq_offset)) \
printk("openpic.c:%d: illegal irq %d\n", __LINE__, irq);
+#endif
#define check_arg_cpu(cpu) \
if (cpu < 0 || cpu >= NumProcessors) \
printk("openpic.c:%d: illegal cpu %d\n", __LINE__, cpu);
@@ -201,15 +207,12 @@ void __init openpic_init(int main_pic)
/* Initialize IPI interrupts */
if ( ppc_md.progress ) ppc_md.progress("openpic ipi",0x3bb);
for (i = 0; i < OPENPIC_NUM_IPI; i++) {
- /* Disabled, Priority 0 */
- openpic_initipi(i, 0, OPENPIC_VEC_IPI+i);
+ /* Disabled, Priority 8 */
+ openpic_initipi(i, 8, OPENPIC_VEC_IPI+i);
}
/* Initialize external interrupts */
if ( ppc_md.progress ) ppc_md.progress("openpic ext",0x3bc);
- /* SIOint (8259 cascade) is special */
- openpic_initirq(0, 8, open_pic.irq_offset, 1, 1);
- openpic_mapirq(0, 1<<0);
for (i = 1; i < NumSources; i++) {
/* Enabled, Priority 8 */
openpic_initirq(i, 8, open_pic.irq_offset+i, 0,
@@ -223,6 +226,9 @@ void __init openpic_init(int main_pic)
openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
if ( _machine != _MACH_gemini )
{
+ /* SIOint (8259 cascade) is special */
+ openpic_initirq(0, 8, open_pic.irq_offset, 1, 1);
+ openpic_mapirq(0, 1<<0);
if (request_irq(IRQ_8259_CASCADE, no_action, SA_INTERRUPT,
"82c59 cascade", NULL))
printk("Unable to get OpenPIC IRQ 0 for cascade\n");
diff --git a/arch/ppc/kernel/open_pic.h b/arch/ppc/kernel/open_pic.h
index ace8590bb..1097c70bf 100644
--- a/arch/ppc/kernel/open_pic.h
+++ b/arch/ppc/kernel/open_pic.h
@@ -4,5 +4,6 @@
extern struct hw_interrupt_type open_pic;
void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs);
+void openpic_enable_IPI(u_int ipi);
#endif /* _PPC_KERNEL_OPEN_PIC_H */
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 0d07c289d..054eee918 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -8,7 +8,6 @@
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/init.h>
-#include <linux/config.h>
#include <linux/openpic.h>
#include <asm/processor.h>
@@ -77,6 +76,21 @@ void __init pcibios_init(void)
ppc_md.pcibios_fixup();
}
+void __init
+pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
+{
+ ranges->io_start -= bus->resource[0]->start;
+ ranges->io_end -= bus->resource[0]->start;
+ ranges->mem_start -= bus->resource[1]->start;
+ ranges->mem_end -= bus->resource[1]->start;
+}
+
+unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
+ unsigned long start, unsigned long size)
+{
+ return start;
+}
+
static void __init pcibios_claim_resources(struct pci_bus *bus)
{
struct pci_dev *dev;
@@ -117,31 +131,6 @@ char __init *pcibios_setup(char *str)
return str;
}
-#ifndef CONFIG_8xx
-/* Recursively searches any node that is of type PCI-PCI bridge. Without
- * this, the old code would miss children of P2P bridges and hence not
- * fix IRQ's for cards located behind P2P bridges.
- * - Ranjit Deshpande, 01/20/99
- */
-void __init fix_intr(struct device_node *node, struct pci_dev *dev)
-{
- unsigned int *reg, *class_code;
-
- for (; node != 0;node = node->sibling) {
- class_code = (unsigned int *) get_property(node, "class-code", 0);
- if((*class_code >> 8) == PCI_CLASS_BRIDGE_PCI)
- fix_intr(node->child, dev);
- reg = (unsigned int *) get_property(node, "reg", 0);
- if (reg == 0 || ((reg[0] >> 8) & 0xff) != dev->devfn)
- continue;
- /* this is the node, see if it has interrupts */
- if (node->n_intrs > 0)
- dev->irq = node->intrs[0].line;
- break;
- }
-}
-#endif
-
int pcibios_assign_resource(struct pci_dev *pdev, int resource)
{
return 0;
@@ -168,3 +157,8 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
/* XXX FIXME - update OF device tree node interrupt property */
}
+
+void __init
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
+{
+}
diff --git a/arch/ppc/kernel/pmac_support.c b/arch/ppc/kernel/pmac_nvram.c
index cf3d1711a..99bfa4f8b 100644
--- a/arch/ppc/kernel/pmac_support.c
+++ b/arch/ppc/kernel/pmac_nvram.c
@@ -1,15 +1,13 @@
/*
* Miscellaneous procedures for dealing with the PowerMac hardware.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/stddef.h>
-#include <linux/reboot.h>
#include <linux/nvram.h>
#include <linux/init.h>
#include <asm/init.h>
-#include <asm/ptrace.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/prom.h>
#include <linux/adb.h>
@@ -25,7 +23,6 @@ static int nvram_mult;
#define NVRAM_SIZE 0x2000 /* 8kB of non-volatile RAM */
-
__init
void pmac_nvram_init(void)
{
@@ -55,6 +52,7 @@ void pmac_nvram_init(void)
}
}
+__openfirmware
unsigned char nvram_read_byte(int addr)
{
struct adb_request req;
@@ -79,6 +77,7 @@ unsigned char nvram_read_byte(int addr)
return 0;
}
+__openfirmware
void nvram_write_byte(unsigned char val, int addr)
{
struct adb_request req;
diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c
index 62161f68a..a9166da34 100644
--- a/arch/ppc/kernel/pmac_pci.c
+++ b/arch/ppc/kernel/pmac_pci.c
@@ -21,7 +21,6 @@
#include <asm/init.h>
#include <asm/io.h>
-#include <asm/pgtable.h>
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
@@ -442,6 +441,30 @@ static void __init add_bridges(struct device_node *dev)
}
}
+/* Recursively searches any node that is of type PCI-PCI bridge. Without
+ * this, the old code would miss children of P2P bridges and hence not
+ * fix IRQ's for cards located behind P2P bridges.
+ * - Ranjit Deshpande, 01/20/99
+ */
+void __init
+fix_intr(struct device_node *node, struct pci_dev *dev)
+{
+ unsigned int *reg, *class_code;
+
+ for (; node != 0;node = node->sibling) {
+ class_code = (unsigned int *) get_property(node, "class-code", 0);
+ if((*class_code >> 8) == PCI_CLASS_BRIDGE_PCI)
+ fix_intr(node->child, dev);
+ reg = (unsigned int *) get_property(node, "reg", 0);
+ if (reg == 0 || ((reg[0] >> 8) & 0xff) != dev->devfn)
+ continue;
+ /* this is the node, see if it has interrupts */
+ if (node->n_intrs > 0)
+ dev->irq = node->intrs[0].line;
+ break;
+ }
+}
+
void __init
pmac_pcibios_fixup(void)
{
diff --git a/arch/ppc/kernel/ppc8xx_pic.c b/arch/ppc/kernel/ppc8xx_pic.c
index 96c1e7260..afcda088b 100644
--- a/arch/ppc/kernel/ppc8xx_pic.c
+++ b/arch/ppc/kernel/ppc8xx_pic.c
@@ -1,4 +1,4 @@
-
+#include <linux/config.h>
#include <linux/stddef.h>
#include <linux/init.h>
#include <linux/sched.h>
diff --git a/arch/ppc/kernel/ppc8xx_pic.h b/arch/ppc/kernel/ppc8xx_pic.h
index c4de8f12e..13518bb06 100644
--- a/arch/ppc/kernel/ppc8xx_pic.h
+++ b/arch/ppc/kernel/ppc8xx_pic.h
@@ -1,7 +1,7 @@
-
#ifndef _PPC_KERNEL_PPC8xx_H
#define _PPC_KERNEL_PPC8xx_H
+#include <linux/config.h>
#include "local_irq.h"
extern struct hw_interrupt_type ppc8xx_pic;
diff --git a/arch/ppc/kernel/ppc_asm.h b/arch/ppc/kernel/ppc_asm.h
index 10be7ceab..2b999ab36 100644
--- a/arch/ppc/kernel/ppc_asm.h
+++ b/arch/ppc/kernel/ppc_asm.h
@@ -10,6 +10,9 @@
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
+
+#include <linux/config.h>
+
#include "ppc_asm.tmpl"
#include "ppc_defs.h"
@@ -45,14 +48,20 @@
sync; \
isync
-/* This instruction is not implemented on the PPC 603 or 601 */
-#define tlbia \
- li r4,128; \
- mtctr r4; \
- lis r4,KERNELBASE@h; \
-0: tlbie r4; \
- addi r4,r4,0x1000; \
+/*
+ * This instruction is not implemented on the PPC 603 or 601; however, on
+ * the 403GCX and 405GP tlbia IS defined and tlbie is not.
+ */
+
+#if !defined(CONFIG_4xx)
+#define tlbia \
+ li r4,128; \
+ mtctr r4; \
+ lis r4,KERNELBASE@h; \
+0: tlbie r4; \
+ addi r4,r4,0x1000; \
bdnz 0b
+#endif
/*
* On APUS (Amiga PowerPC cpu upgrade board), we don't know the
diff --git a/arch/ppc/kernel/ppc_asm.tmpl b/arch/ppc/kernel/ppc_asm.tmpl
index e3004c8f6..94a5bd74c 100644
--- a/arch/ppc/kernel/ppc_asm.tmpl
+++ b/arch/ppc/kernel/ppc_asm.tmpl
@@ -1,4 +1,17 @@
-/* Register names */
+/* Condition Register Bit Fields */
+
+#define cr0 0
+#define cr1 1
+#define cr2 2
+#define cr3 3
+#define cr4 4
+#define cr5 5
+#define cr6 6
+#define cr7 7
+
+
+/* General Purpose Registers (GPRs) */
+
#define r0 0
#define r1 1
#define r2 2
@@ -32,6 +45,9 @@
#define r30 30
#define r31 31
+
+/* Floating Point Registers (FPRs) */
+
#define fr0 0
#define fr1 1
#define fr2 2
diff --git a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c
index 0b7c77683..b90fa7a2c 100644
--- a/arch/ppc/kernel/ppc_htab.c
+++ b/arch/ppc/kernel/ppc_htab.c
@@ -63,25 +63,6 @@ static struct file_operations ppc_htab_operations = {
*/
struct inode_operations proc_ppc_htab_inode_operations = {
&ppc_htab_operations, /* default proc 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 */
};
/* these will go into processor.h when I'm done debugging -- Cort */
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 7bd21c277..11d2cd114 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -76,7 +76,7 @@ EXPORT_SYMBOL(ppc_local_bh_count);
EXPORT_SYMBOL(kernel_flag);
#endif /* __SMP__ */
-#ifndef CONFIG_8xx
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
EXPORT_SYMBOL(isa_io_base);
EXPORT_SYMBOL(isa_mem_base);
EXPORT_SYMBOL(pci_dram_offset);
@@ -219,21 +219,22 @@ EXPORT_SYMBOL(pmu_register_sleep_notifier);
EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
EXPORT_SYMBOL(pmu_enable_irled);
#endif CONFIG_PMAC_PBOOK
-EXPORT_SYMBOL(abort);
-#ifndef CONFIG_8xx
+#if defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
EXPORT_SYMBOL(find_devices);
EXPORT_SYMBOL(find_type_devices);
EXPORT_SYMBOL(find_compatible_devices);
EXPORT_SYMBOL(find_path_device);
EXPORT_SYMBOL(find_phandle);
+EXPORT_SYMBOL(device_is_compatible);
+EXPORT_SYMBOL(machine_is_compatible);
EXPORT_SYMBOL(get_property);
EXPORT_SYMBOL(pci_io_base);
EXPORT_SYMBOL(pci_device_loc);
EXPORT_SYMBOL(feature_set);
EXPORT_SYMBOL(feature_clear);
EXPORT_SYMBOL(feature_test);
-#endif
-#ifdef CONFIG_SCSI
+#endif /* defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC) */
+#if defined(CONFIG_SCSI) && (defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC))
EXPORT_SYMBOL(note_scsi_host);
#endif
EXPORT_SYMBOL(kd_mksound);
@@ -251,17 +252,16 @@ EXPORT_SYMBOL_NOVERS(memscan);
EXPORT_SYMBOL_NOVERS(memcmp);
EXPORT_SYMBOL(abs);
-#ifndef CONFIG_8xx
-EXPORT_SYMBOL(device_is_compatible);
-#endif
#ifdef CONFIG_VT
EXPORT_SYMBOL(screen_info);
#endif
EXPORT_SYMBOL(int_control);
+#if !defined(CONFIG_4xx)
EXPORT_SYMBOL(timer_interrupt_intercept);
EXPORT_SYMBOL(timer_interrupt);
+#endif
extern unsigned long do_IRQ_intercept;
EXPORT_SYMBOL(do_IRQ_intercept);
EXPORT_SYMBOL(irq_desc);
diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c
index 1bfc63c63..e7f62c429 100644
--- a/arch/ppc/kernel/prep_setup.c
+++ b/arch/ppc/kernel/prep_setup.c
@@ -760,22 +760,6 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
prep_setup_pci_ptrs();
-#ifdef CONFIG_BLK_DEV_INITRD
- /* take care of initrd if we have one */
- if ( r4 )
- {
- initrd_start = r4 + KERNELBASE;
- initrd_end = r5 + KERNELBASE;
- }
-#endif /* CONFIG_BLK_DEV_INITRD */
-
- /* take care of cmd line */
- if ( r6 && (((char *) r6) != '\0'))
- {
- *(char *)(r7+KERNELBASE) = 0;
- strcpy(cmd_line, (char *)(r6+KERNELBASE));
- }
-
ppc_md.setup_arch = prep_setup_arch;
ppc_md.setup_residual = prep_setup_residual;
ppc_md.get_cpuinfo = prep_get_cpuinfo;
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index adeeefe33..403213883 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -204,9 +204,15 @@ _switch_to(struct task_struct *prev, struct task_struct *new,
if ( (prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)) &&
prev->thread.vrsave )
giveup_altivec(prev);
- if ( (new->last_processor != NO_PROC_ID) &&
+ /*
+ * The 750 doesn't broadcast invalidates with tlbie's
+ * so flush every processor switch.
+ * -- Cort
+ */
+ if ( ((_get_PVR()>>16) == 8) &&
+ (new->last_processor != NO_PROC_ID) &&
(new->last_processor != new->processor) && new->mm )
- flush_tlb_mm(new->mm);
+ flush_tlb_mm(new->mm);
prev->last_processor = prev->processor;
current_set[smp_processor_id()] = new;
#endif /* __SMP__ */
diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c
index 22dcf8cbe..049cde10f 100644
--- a/arch/ppc/kernel/prom.c
+++ b/arch/ppc/kernel/prom.c
@@ -283,11 +283,6 @@ prom_init(int r3, int r4, prom_entry pp)
int l;
char *p, *d;
-#ifdef CONFIG_GEMINI
- gemini_prom_init();
- return;
-#endif /* CONFIG_GEMINI */
-
/* check if we're apus, return if we are */
if ( r3 == 0x61707573 )
return;
diff --git a/arch/ppc/kernel/qspan_pci.c b/arch/ppc/kernel/qspan_pci.c
index 6d331b2b4..860f4f0cc 100644
--- a/arch/ppc/kernel/qspan_pci.c
+++ b/arch/ppc/kernel/qspan_pci.c
@@ -15,6 +15,7 @@
* we have switched the chip select.
*/
+#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/delay.h>
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 2cf9ee714..caffdcf99 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -30,6 +30,8 @@
#include <asm/bootx.h>
#include <asm/machdep.h>
+#include "oak_setup.h"
+
extern void pmac_init(unsigned long r3,
unsigned long r4,
unsigned long r5,
@@ -67,11 +69,11 @@ extern void gemini_init(unsigned long r3,
unsigned long r7);
extern boot_infos_t *boot_infos;
-extern char cmd_line[512];
char saved_command_line[256];
unsigned char aux_device_present;
struct int_control_struct int_control;
struct ide_machdep_calls ppc_ide_md;
+int parse_bootinfo(void);
unsigned long ISA_DMA_THRESHOLD;
unsigned long DMA_MODE_READ, DMA_MODE_WRITE;
@@ -84,14 +86,9 @@ int have_of = 0;
#ifdef CONFIG_MAGIC_SYSRQ
unsigned long SYSRQ_KEY;
#endif /* CONFIG_MAGIC_SYSRQ */
-/* For MTX/MVME boards.. with Raven/Falcon Chipset
- Real close to CHRP, but boot like PReP (via PPCbug)
- There's probably a nicer way to do this.. --Troy */
-int is_powerplus = 0;
struct machdep_calls ppc_md;
-
/* copy of the residual data */
#ifndef CONFIG_8xx
extern unsigned char __res[sizeof(RESIDUAL)];
@@ -196,6 +193,7 @@ int get_cpuinfo(char *buffer)
unsigned long len = 0;
unsigned long bogosum = 0;
unsigned long i;
+ unsigned short maj, min;
#ifdef __SMP__
#define CPU_PRESENT(x) (cpu_callin_map[(x)])
@@ -215,8 +213,8 @@ int get_cpuinfo(char *buffer)
if ( i )
len += sprintf(len+buffer,"\n");
len += sprintf(len+buffer,"processor\t: %lu\n",i);
- len += sprintf(len+buffer,"cpu\t\t: ");
-
+ len += sprintf(len+buffer,"cpu\t\t: ");
+
switch (GET_PVR >> 16)
{
case 1:
@@ -254,7 +252,7 @@ int get_cpuinfo(char *buffer)
len += sprintf(len+buffer, "860\n");
break;
default:
- len += sprintf(len+buffer, "unknown (%lu)\n",
+ len += sprintf(len+buffer, "unknown (%lx)\n",
GET_PVR>>16);
break;
}
@@ -294,8 +292,7 @@ int get_cpuinfo(char *buffer)
len += ppc_md.setup_residual(buffer + len);
}
- len += sprintf(len+buffer, "revision\t: %ld.%ld\n",
- (GET_PVR & 0xff00) >> 8, GET_PVR & 0xff);
+ len += sprintf(len+buffer, "revision\t: %hd.%hd\n", maj, min);
len += sprintf(buffer+len, "bogomips\t: %lu.%02lu\n",
(CD(loops_per_sec)+2500)/500000,
@@ -333,6 +330,30 @@ int get_cpuinfo(char *buffer)
return len;
}
+#ifndef CONFIG_MACH_SPECIFIC
+void __init
+intuit_machine_type(void)
+{
+ char *model;
+ struct device_node *root;
+
+ /* ask the OF info if we're a chrp or pmac */
+ root = find_path_device("/");
+ if (root != 0) {
+ /* assume pmac unless proven to be chrp -- Cort */
+ _machine = _MACH_Pmac;
+ model = get_property(root, "device_type", NULL);
+ if (model && !strncmp("chrp", model, 4))
+ _machine = _MACH_chrp;
+ else {
+ model = get_property(root, "model", NULL);
+ if (model && !strncmp(model, "IBM", 3))
+ _machine = _MACH_chrp;
+ }
+ }
+}
+#endif /* CONFIG_MACH_SPECIFIC */
+
/*
* Find out what kind of machine we're on and save any data we need
* from the early boot process (devtree is copied on pmac by prom_init() )
@@ -341,49 +362,31 @@ unsigned long __init
identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7)
{
+ int_control.int_sti = __no_use_sti;
+ int_control.int_cli = __no_use_cli;
+ int_control.int_save_flags = __no_use_save_flags;
+ int_control.int_restore_flags = __no_use_restore_flags;
-#ifndef CONFIG_8xx
- if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100);
+ parse_bootinfo();
+ if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100);
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
#ifndef CONFIG_MACH_SPECIFIC
- /* boot loader will tell us if we're APUS */
- if ( r3 == 0x61707573 )
+ /* if we didn't get any bootinfo telling us what we are... */
+ if ( _machine == 0 )
{
- _machine = _MACH_apus;
- r3 = 0;
- }
- /* prep boot loader tells us if we're prep or not */
- else if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
- {
- _machine = _MACH_prep;
- } else
- {
- char *model;
- struct device_node *root;
-
- have_of = 1;
-
- /* prom_init has already been called from __start */
- if (boot_infos)
- relocate_nodes();
-
- /* ask the OF info if we're a chrp or pmac */
- /* we need to set _machine before calling finish_device_tree */
- root = find_path_device("/");
- if (root != 0) {
- /* assume pmac unless proven to be chrp -- Cort */
- _machine = _MACH_Pmac;
- model = get_property(root, "device_type", NULL);
- if (model && !strncmp("chrp", model, 4))
- _machine = _MACH_chrp;
- else {
- model = get_property(root, "model", NULL);
- if (model && !strncmp(model, "IBM", 3))
- _machine = _MACH_chrp;
- }
+ /* boot loader will tell us if we're APUS */
+ if ( r3 == 0x61707573 )
+ {
+ _machine = _MACH_apus;
+ r3 = 0;
}
-
- finish_device_tree();
+ /* prep boot loader tells us if we're prep or not */
+ else if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) )
+ {
+ _machine = _MACH_prep;
+ } else
+ have_of = 1;
}
#endif /* CONFIG_MACH_SPECIFIC */
@@ -392,7 +395,13 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
/* prom_init has already been called from __start */
if (boot_infos)
relocate_nodes();
+#ifndef CONFIG_MACH_SPECIFIC
+ /* we need to set _machine before calling finish_device_tree */
+ if (_machine == 0)
+ intuit_machine_type();
+#endif /* CONFIG_MACH_SPECIFIC */
finish_device_tree();
+
/*
* If we were booted via quik, r3 points to the physical
* address of the command-line parameters.
@@ -444,11 +453,6 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
cmd_line[sizeof(cmd_line) - 1] = 0;
}
- int_control.int_sti = __no_use_sti;
- int_control.int_cli = __no_use_cli;
- int_control.int_save_flags = __no_use_save_flags;
- int_control.int_restore_flags = __no_use_restore_flags;
-
switch (_machine)
{
case _MACH_Pmac:
@@ -469,7 +473,7 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
case _MACH_gemini:
gemini_init(r3, r4, r5, r6, r7);
break;
-#endif
+#endif
default:
printk("Unknown machine type in identify_machine!\n");
}
@@ -478,14 +482,15 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
extern int __map_without_bats;
__map_without_bats = 1;
}
-#else /* CONFIG_8xx */
- int_control.int_sti = __no_use_sti;
- int_control.int_cli = __no_use_cli;
- int_control.int_save_flags = __no_use_save_flags;
- int_control.int_restore_flags = __no_use_restore_flags;
-
+#else
+#if defined(CONFIG_4xx)
+ oak_init(r3, r4, r5, r6, r7);
+#elif defined(CONFIG_8xx)
m8xx_init(r3, r4, r5, r6, r7);
-#endif
+#else
+#error "No board type has been defined for identify_machine()!"
+#endif /* CONFIG_4xx */
+#endif /* !CONFIG_4xx && !CONFIG_8xx */
/* Look for mem= option on command line */
if (strstr(cmd_line, "mem=")) {
@@ -513,6 +518,53 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.ppc_machine = _machine;
if ( ppc_md.progress ) ppc_md.progress("id mach(): done", 0x200);
+
+ return 0;
+}
+
+int parse_bootinfo(void)
+{
+ struct bi_record *rec;
+ extern char _end[];
+
+ rec = (struct bi_record *)PAGE_ALIGN((ulong)_end);
+ if ( rec->tag != BI_FIRST )
+ {
+ /*
+ * This 0x10000 offset is a terrible hack but it will go away when
+ * we have the bootloader handle all the relocation and
+ * prom calls -- Cort
+ */
+ rec = (struct bi_record *)PAGE_ALIGN((ulong)_end+0x10000);
+ if ( rec->tag != BI_FIRST )
+ return -1;
+ }
+
+ for ( ; rec->tag != BI_LAST ;
+ rec = (struct bi_record *)((ulong)rec + rec->size) )
+ {
+ ulong *data = rec->data;
+ switch (rec->tag)
+ {
+ case BI_CMD_LINE:
+ memcpy(cmd_line, (void *)data, rec->size);
+ break;
+#ifdef CONFIG_BLK_DEV_INITRD
+ case BI_INITRD:
+ initrd_start = data[0];
+ initrd_end = data[0] + rec->size;
+ break;
+#endif /* CONFIG_BLK_DEV_INITRD */
+#ifndef CONFIG_MACH_SPECIFIC
+ case BI_MACHTYPE:
+ _machine = data[0];
+ have_of = data[1];
+ break;
+#endif /* CONFIG_MACH_SPECIFIC */
+
+ }
+ }
+
return 0;
}
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
index 0d55bcefc..1ca3a65f8 100644
--- a/arch/ppc/kernel/signal.c
+++ b/arch/ppc/kernel/signal.c
@@ -444,6 +444,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index a21361340..fad7c7c1d 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -39,6 +39,7 @@
#include <asm/gemini.h>
#include "time.h"
+#include "open_pic.h"
int smp_threads_ready = 0;
volatile int smp_commenced = 0;
int smp_num_cpus = 1;
@@ -160,14 +161,15 @@ void smp_message_recv(void)
void smp_send_reschedule(int cpu)
{
/*
+ * This is only used if `cpu' is running an idle task,
+ * so it will reschedule itself anyway...
+ *
* This isn't the case anymore since the other CPU could be
* sleeping and won't reschedule until the next interrupt (such
* as the timer).
* -- Cort
*/
- /* This is only used if `cpu' is running an idle task,
- so it will reschedule itself anyway... */
- /*smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);*/
+ smp_message_pass(cpu, MSG_RESCHEDULE, 0, 0);
}
void smp_send_stop(void)
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 07e45db6b..47fef50d4 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -128,6 +128,7 @@ MachineCheckException(struct pt_regs *regs)
_exception(SIGSEGV, regs);
}
+#if defined(CONFIG_ALTIVEC)
void
AltiVecUnavailable(struct pt_regs *regs)
{
@@ -163,6 +164,7 @@ AltiVecUnavailable(struct pt_regs *regs)
/* enable altivec for the task on return */
regs->msr |= MSR_VEC;
}
+#endif /* CONFIG_ALTIVEC */
void
UnknownException(struct pt_regs *regs)
@@ -191,6 +193,20 @@ RunModeException(struct pt_regs *regs)
void
ProgramCheckException(struct pt_regs *regs)
{
+#if defined(CONFIG_4xx)
+ unsigned int instr;
+ unsigned int esr = mfspr(SPRN_ESR);
+
+ if (esr & ESR_PTR) {
+#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
+ if (debugger_bpt(regs))
+ return;
+#endif
+ _exception(SIGTRAP, regs);
+ } else {
+ _exception(SIGILL, regs);
+ }
+#else
if (regs->msr & 0x100000) {
/* IEEE FP exception */
_exception(SIGFPE, regs);
@@ -204,6 +220,7 @@ ProgramCheckException(struct pt_regs *regs)
} else {
_exception(SIGILL, regs);
}
+#endif
}
void
diff --git a/arch/ppc/lib/checksum.S b/arch/ppc/lib/checksum.S
index 5eb60537c..40741dac4 100644
--- a/arch/ppc/lib/checksum.S
+++ b/arch/ppc/lib/checksum.S
@@ -24,13 +24,12 @@
* 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
+ addic. r4,r4,-2
addc r0,r0,r5
mtctr r4
+ blelr-
1: lwzu r4,4(r3)
adde r0,r0,r4
bdnz 1b
@@ -40,8 +39,6 @@ _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/Makefile b/arch/ppc/mm/Makefile
index 2b07c7227..43f53ef4d 100644
--- a/arch/ppc/mm/Makefile
+++ b/arch/ppc/mm/Makefile
@@ -8,6 +8,10 @@
# Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := mm.o
-O_OBJS = fault.o init.o extable.o
+O_OBJS = fault.o init.o mem_pieces.o extable.o
+
+ifeq ($(CONFIG_4xx),y)
+O_OBJS += 4xx_tlb.o
+endif
include $(TOPDIR)/Rules.make
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index aa4f97acd..0427f2166 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -52,36 +52,36 @@ void bad_page_fault(struct pt_regs *, unsigned long);
void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
/*
- * The error_code parameter is DSISR for a data fault, SRR1 for
- * an instruction fault.
+ * For 600- and 800-family processors, the error_code parameter is DSISR
+ * for a data fault, SRR1 for an instruction fault. For 400-family processors
+ * the error_code parameter is ESR for a data fault, 0 for an instruction
+ * fault.
*/
void do_page_fault(struct pt_regs *regs, unsigned long address,
unsigned long error_code)
{
struct vm_area_struct * vma;
struct mm_struct *mm = current->mm;
+#if defined(CONFIG_4xx)
+ int is_write = error_code & ESR_DST;
+#else
+ int is_write = error_code & 0x02000000;
+#endif /* CONFIG_4xx */
- /*printk("address: %08lx nip:%08lx code: %08lx %s%s%s%s%s%s\n",
- address,regs->nip,error_code,
- (error_code&0x40000000)?"604 tlb&htab miss ":"",
- (error_code&0x20000000)?"603 tlbmiss ":"",
- (error_code&0x02000000)?"write ":"",
- (error_code&0x08000000)?"prot ":"",
- (error_code&0x80000000)?"I/O ":"",
- (regs->trap == 0x400)?"instr":"data"
- );*/
-
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
if (debugger_fault_handler && regs->trap == 0x300) {
debugger_fault_handler(regs);
return;
}
+#if !defined(CONFIG_4xx)
if (error_code & 0x00400000) {
/* DABR match */
if (debugger_dabr_match(regs))
return;
}
-#endif
+#endif /* !CONFIG_4xx */
+#endif /* CONFIG_XMON || CONFIG_KGDB */
+
if (in_interrupt()) {
static int complained;
if (complained < 20) {
@@ -107,12 +107,12 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
goto bad_area;
good_area:
-#ifdef CONFIG_6xx
+#if defined(CONFIG_6xx)
if (error_code & 0x95700000)
/* an error such as lwarx to I/O controller space,
address matching DABR, eciwx, etc. */
#endif /* CONFIG_6xx */
-#ifdef CONFIG_8xx
+#if defined(CONFIG_8xx)
/* The MPC8xx seems to always set 0x80000000, which is
* "undefined". Of those that can be set, this is the only
* one which seems bad.
@@ -124,7 +124,7 @@ good_area:
/* a write */
- if (error_code & 0x02000000) {
+ if (is_write) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
/* a read */
@@ -135,7 +135,7 @@ good_area:
if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
goto bad_area;
}
- if (!handle_mm_fault(current, vma, address, error_code & 0x02000000))
+ if (!handle_mm_fault(current, vma, address, is_write))
goto bad_area;
up(&mm->mmap_sem);
/*
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 025145d71..397083aca 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -40,6 +40,7 @@
#include <linux/blk.h> /* for initrd_* */
#endif
+#include <asm/pgalloc.h>
#include <asm/prom.h>
#include <asm/io.h>
#include <asm/mmu_context.h>
@@ -56,6 +57,10 @@
#include <asm/amigahw.h>
#include <asm/gemini.h>
+#include "mem_pieces.h"
+
+#define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10)
+
int prom_trashed;
atomic_t next_mmu_context;
unsigned long *end_of_DRAM;
@@ -71,7 +76,6 @@ extern char __prep_begin, __prep_end;
extern char __pmac_begin, __pmac_end;
extern char __apus_begin, __apus_end;
extern char __openfirmware_begin, __openfirmware_end;
-char *klimit = _end;
struct device_node *memory_node;
unsigned long ioremap_base;
unsigned long ioremap_bot;
@@ -98,34 +102,13 @@ void map_page(unsigned long va, unsigned long pa, int flags);
extern void die_if_kernel(char *,struct pt_regs *,long);
extern void show_net_buffers(void);
-
-/*
- * The following stuff defines a data structure for representing
- * areas of memory as an array of (address, length) pairs, and
- * procedures for manipulating them.
- */
-#define MAX_MEM_REGIONS 32
-
-struct mem_pieces {
- int n_regions;
- struct reg_property regions[MAX_MEM_REGIONS];
-};
struct mem_pieces phys_mem;
-struct mem_pieces phys_avail;
-
-static void remove_mem_piece(struct mem_pieces *, unsigned, unsigned, int);
-static void set_phys_avail(void);
-void *find_mem_piece(unsigned, unsigned);
-static void print_mem_pieces(struct mem_pieces *);
-#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC)
-static void append_mem_piece(struct mem_pieces *, unsigned, unsigned);
-#endif
extern struct task_struct *current_set[NR_CPUS];
PTE *Hash, *Hash_end;
unsigned long Hash_size, Hash_mask;
-#ifndef CONFIG_8xx
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
#ifdef CONFIG_PPC64
unsigned long long _SDR1;
#else
@@ -174,12 +157,10 @@ static inline unsigned long p_mapped_by_bats(unsigned long pa)
return 0;
}
-#else /* CONFIG_8xx */
-
-/* 8xx doesn't have BATs */
+#else /* CONFIG_4xx || CONFIG_8xx */
#define v_mapped_by_bats(x) (0UL)
#define p_mapped_by_bats(x) (0UL)
-#endif /* CONFIG_8xx */
+#endif /* !CONFIG_4xx && !CONFIG_8xx */
/*
* this tells the system to map all of ram with the segregs
@@ -343,24 +324,23 @@ void show_mem(void)
void si_meminfo(struct sysinfo *val)
{
- int i;
+ int i, c;
i = max_mapnr;
- val->totalram = 0;
- val->sharedram = 0;
+ val->totalram = totalram_pages;
val->freeram = nr_free_pages();
val->bufferram = atomic_read(&buffermem_pages);
+ val->sharedram = 0;
while (i-- > 0) {
if (PageReserved(mem_map+i))
continue;
- val->totalram++;
- if (!atomic_read(&mem_map[i].count))
- continue;
- val->sharedram += atomic_read(&mem_map[i].count) - 1;
+ c = atomic_read(&mem_map[i].count);
+ if (c > 1)
+ val->sharedram += c - 1;
}
- val->totalram <<= PAGE_SHIFT;
- val->sharedram <<= PAGE_SHIFT;
- return;
+ val->totalhigh = 0;
+ val->freehigh = 0;
+ val->mem_unit = PAGE_SIZE;
}
void *
@@ -422,7 +402,7 @@ __ioremap(unsigned long addr, unsigned long size, unsigned long flags)
if (mem_init_done) {
struct vm_struct *area;
- area = get_vm_area(size);
+ area = get_vm_area(size, VM_IOREMAP);
if (area == 0)
return NULL;
v = VMALLOC_VMADDR(area->addr);
@@ -593,191 +573,8 @@ mmu_context_overflow(void)
}
#endif /* CONFIG_8xx */
-/*
- * Set phys_avail to phys_mem less the kernel text/data/bss.
- */
-static void __init set_phys_avail(void)
-{
- unsigned long kstart, ksize;
-
- /* we can't call the prom any more at this stage, so
- all of memory is available (after klimit) */
- phys_avail = phys_mem;
-
- /*
- * phys_avail records memory we can use.
- * Make sure the kernel text/data/bss is not in it.
- */
- kstart = __pa(_stext); /* should be 0 */
- ksize = PAGE_ALIGN(klimit - _stext);
- remove_mem_piece(&phys_avail, kstart, ksize, 0);
- remove_mem_piece(&phys_avail, 0, 0x4000, 0);
-
-#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_start) {
- /*
- * Remove the initialized ramdisk from the available memory.
- */
- remove_mem_piece(&phys_avail, __pa(initrd_start),
- initrd_end - initrd_start, 1);
- }
-#endif /* CONFIG_BLK_DEV_INITRD */
-}
-
-/*
- * Scan a region for a piece of a given size with the required alignment.
- */
-void __init *find_mem_piece(unsigned size, unsigned align)
-{
- int i;
- unsigned a, e;
- struct mem_pieces *mp = &phys_avail;
-
- for (i = 0; i < mp->n_regions; ++i) {
- a = mp->regions[i].address;
- e = a + mp->regions[i].size;
- a = (a + align - 1) & -align;
- if (a + size <= e) {
- remove_mem_piece(mp, a, size, 1);
- return __va(a);
- }
- }
- printk("Couldn't find %u bytes at %u alignment\n", size, align);
- abort();
- return NULL;
-}
-
-/*
- * Remove some memory from an array of pieces
- */
-static void __init
-remove_mem_piece(struct mem_pieces *mp, unsigned start, unsigned size,
- int must_exist)
-{
- int i, j;
- unsigned end, rs, re;
- struct reg_property *rp;
-
- end = start + size;
- for (i = 0, rp = mp->regions; i < mp->n_regions; ++i, ++rp) {
- if (end > rp->address && start < rp->address + rp->size)
- break;
- }
- if (i >= mp->n_regions) {
- if (must_exist)
- printk("remove_mem_piece: [%x,%x) not in any region\n",
- start, end);
- return;
- }
- for (; i < mp->n_regions && end > rp->address; ++i, ++rp) {
- rs = rp->address;
- re = rs + rp->size;
- if (must_exist && (start < rs || end > re)) {
- printk("remove_mem_piece: bad overlap [%x,%x) with",
- start, end);
- print_mem_pieces(mp);
- must_exist = 0;
- }
- if (start > rs) {
- rp->size = start - rs;
- if (end < re) {
- /* need to split this entry */
- if (mp->n_regions >= MAX_MEM_REGIONS)
- panic("eek... mem_pieces overflow");
- for (j = mp->n_regions; j > i + 1; --j)
- mp->regions[j] = mp->regions[j-1];
- ++mp->n_regions;
- rp[1].address = end;
- rp[1].size = re - end;
- }
- } else {
- if (end < re) {
- rp->address = end;
- rp->size = re - end;
- } else {
- /* need to delete this entry */
- for (j = i; j < mp->n_regions - 1; ++j)
- mp->regions[j] = mp->regions[j+1];
- --mp->n_regions;
- --i;
- --rp;
- }
- }
- }
-}
-
-static void __init print_mem_pieces(struct mem_pieces *mp)
-{
- int i;
-
- for (i = 0; i < mp->n_regions; ++i)
- printk(" [%x, %x)", mp->regions[i].address,
- mp->regions[i].address + mp->regions[i].size);
- printk("\n");
-}
-
-#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC)
-/*
- * Add some memory to an array of pieces
- */
-static void __init
-append_mem_piece(struct mem_pieces *mp, unsigned start, unsigned size)
-{
- struct reg_property *rp;
-
- if (mp->n_regions >= MAX_MEM_REGIONS)
- return;
- rp = &mp->regions[mp->n_regions++];
- rp->address = start;
- rp->size = size;
-}
-#endif
-
-#ifndef CONFIG_8xx
-static void hash_init(void);
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
static void get_mem_prop(char *, struct mem_pieces *);
-static void sort_mem_pieces(struct mem_pieces *);
-static void coalesce_mem_pieces(struct mem_pieces *);
-
-static void __init sort_mem_pieces(struct mem_pieces *mp)
-{
- unsigned long a, s;
- int i, j;
-
- for (i = 1; i < mp->n_regions; ++i) {
- a = mp->regions[i].address;
- s = mp->regions[i].size;
- for (j = i - 1; j >= 0; --j) {
- if (a >= mp->regions[j].address)
- break;
- mp->regions[j+1] = mp->regions[j];
- }
- mp->regions[j+1].address = a;
- mp->regions[j+1].size = s;
- }
-}
-
-static void __init coalesce_mem_pieces(struct mem_pieces *mp)
-{
- unsigned long a, s, ns;
- int i, j, d;
-
- d = 0;
- for (i = 0; i < mp->n_regions; i = j) {
- a = mp->regions[i].address;
- s = mp->regions[i].size;
- for (j = i + 1; j < mp->n_regions
- && mp->regions[j].address - a <= s; ++j) {
- ns = mp->regions[j].address + mp->regions[j].size - a;
- if (ns > s)
- s = ns;
- }
- mp->regions[d].address = a;
- mp->regions[d].size = s;
- ++d;
- }
- mp->n_regions = d;
-}
#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC)
/*
@@ -799,8 +596,8 @@ static void __init get_mem_prop(char *name, struct mem_pieces *mp)
memcpy(mp->regions, rp, s);
/* Make sure the pieces are sorted. */
- sort_mem_pieces(mp);
- coalesce_mem_pieces(mp);
+ mem_pieces_sort(mp);
+ mem_pieces_coalesce(mp);
}
#endif /* CONFIG_PMAC || CONFIG_CHRP || CONFIG_ALL_PPC */
@@ -918,7 +715,7 @@ static void __init mapin_ram(void)
f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE;
#ifndef CONFIG_8xx
else
- /* On the powerpc (not 8xx), no user access
+ /* On the powerpc, denying user access
forces R/W kernel access */
f |= _PAGE_USER;
#endif /* CONFIG_8xx */
@@ -939,7 +736,7 @@ static void __init *MMU_get_page(void)
} else if (init_bootmem_done) {
p = alloc_bootmem_pages(PAGE_SIZE);
} else {
- p = find_mem_piece(PAGE_SIZE, PAGE_SIZE);
+ p = mem_pieces_find(PAGE_SIZE, PAGE_SIZE);
}
if (p == 0)
panic("couldn't get a page in MMU_get_page");
@@ -1000,18 +797,32 @@ void __init free_initmem(void)
num_openfirmware_pages );
printk ("Freeing unused kernel memory: %ldk init",
- (num_freed_pages * PAGE_SIZE) >> 10);
+ PGTOKB(num_freed_pages));
+
if ( num_prep_pages )
- printk(" %ldk prep",(num_prep_pages*PAGE_SIZE)>>10);
+ printk(" %ldk prep", PGTOKB(num_prep_pages));
if ( num_pmac_pages )
- printk(" %ldk pmac",(num_pmac_pages*PAGE_SIZE)>>10);
+ printk(" %ldk pmac", PGTOKB(num_pmac_pages));
if ( num_openfirmware_pages )
- printk(" %ldk open firmware",(num_openfirmware_pages*PAGE_SIZE)>>10);
+ printk(" %ldk open firmware", PGTOKB(num_openfirmware_pages));
if ( num_apus_pages )
- printk(" %ldk apus",(num_apus_pages*PAGE_SIZE)>>10);
+ printk(" %ldk apus", PGTOKB(num_apus_pages));
printk("\n");
}
+#ifdef CONFIG_BLK_DEV_INITRD
+void free_initrd_mem(unsigned long start, unsigned long end)
+{
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(mem_map + MAP_NR(start));
+ set_page_count(mem_map+MAP_NR(start), 1);
+ free_page(start);
+ totalram_pages++;
+ }
+ printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10);
+}
+#endif
+
/*
* Do very early mm setup such as finding the size of memory
* and setting up the hash table.
@@ -1063,7 +874,7 @@ void __init MMU_init(void)
setbat(3, 0x90000000, 0x90000000, 0x10000000, IO_PAGE);
break;
case _MACH_Pmac:
-#if 0
+#if 1
{
unsigned long base = 0xf3000000;
struct device_node *macio = find_devices("mac-io");
@@ -1155,7 +966,8 @@ void __init do_init_bootmem(void)
__pa(end_of_DRAM) >> PAGE_SHIFT);
/* remove the bootmem bitmap from the available memory */
- remove_mem_piece(&phys_avail, start, boot_mapsize, 1);
+ mem_pieces_remove(&phys_avail, start, boot_mapsize, 1);
+
/* add everything in phys_avail into the bootmem map */
for (i = 0; i < phys_avail.n_regions; ++i)
free_bootmem(phys_avail.regions[i].address,
@@ -1215,6 +1027,24 @@ void __init paging_init(void)
*/
empty_bad_page = alloc_bootmem_pages(PAGE_SIZE);
empty_bad_page_table = alloc_bootmem_pages(PAGE_SIZE);
+ {
+ unsigned int zones_size[MAX_NR_ZONES], i;
+ /*
+ * All pages are DMA-able so this is wrong - the zone code is
+ * assuming both regions have a value so this is necessary for
+ * now.
+ * -- Cort
+ */
+#if 1
+ for ( i = 1; i < MAX_NR_ZONES; i++ )
+ zones_size[i] = 1<<MAX_ORDER;
+ zones_size[0] = (virt_to_phys(end_of_DRAM) >> PAGE_SHIFT) -
+ ((MAX_NR_ZONES-1)*(1<<MAX_ORDER));
+#else
+ zones_size[0] = virt_to_phys(end_of_DRAM) >> PAGE_SHIFT;
+#endif
+ free_area_init(zones_size);
+ }
}
void __init mem_init(void)
@@ -1223,8 +1053,9 @@ void __init mem_init(void)
int codepages = 0;
int datapages = 0;
int initpages = 0;
+#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
extern unsigned int rtas_data, rtas_size;
-
+#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */
max_mapnr = max_low_pfn;
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
num_physpages = max_mapnr; /* RAM is assumed contiguous */
@@ -1239,6 +1070,14 @@ void __init mem_init(void)
clear_bit(PG_reserved, &mem_map[MAP_NR(addr)].flags);
}
#endif /* CONFIG_BLK_DEV_INITRD */
+
+#if defined(CONFIG_CHRP) || defined(CONFIG_PMAC) || defined(CONFIG_ALL_PPC)
+ /* mark the RTAS pages as reserved */
+ if ( rtas_data )
+ for (addr = rtas_data; addr < PAGE_ALIGN(rtas_data+rtas_size) ;
+ addr += PAGE_SIZE)
+ SetPageReserved(mem_map + MAP_NR(addr));
+#endif /* CONFIG_CHRP || CONFIG_PMAC || CONFIG_ALL_PPC */
for (addr = PAGE_OFFSET; addr < (unsigned long)end_of_DRAM;
addr += PAGE_SIZE) {
@@ -1249,12 +1088,12 @@ void __init mem_init(void)
else if (addr >= (unsigned long)&__init_begin
&& addr < (unsigned long)&__init_end)
initpages++;
- else if (addr < (ulong) klimit)
+ else
datapages++;
}
printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08x,%08lx]\n",
- (unsigned long) nr_free_pages << (PAGE_SHIFT-10),
+ (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
codepages << (PAGE_SHIFT-10),
datapages << (PAGE_SHIFT-10),
initpages << (PAGE_SHIFT-10),
@@ -1262,7 +1101,7 @@ void __init mem_init(void)
mem_init_done = 1;
}
-#ifndef CONFIG_8xx
+#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP) || defined(CONFIG_ALL_PPC)
/*
* On systems with Open Firmware, collect information about
@@ -1324,7 +1163,7 @@ unsigned long __init *pmac_find_end_of_memory(void)
phys_mem.n_regions = 1;
}
- set_phys_avail();
+ set_phys_avail(&phys_mem);
#undef RAM_LIMIT
return __va(total);
@@ -1353,8 +1192,8 @@ unsigned long __init *prep_find_end_of_memory(void)
total = 0x02000000;
printk("Ramsize default to be %ldM\n", total>>20);
}
- append_mem_piece(&phys_mem, 0, total);
- set_phys_avail();
+ mem_pieces_append(&phys_mem, 0, total);
+ set_phys_avail(&phys_mem);
return (__va(total));
}
@@ -1376,7 +1215,7 @@ unsigned long __init *gemini_find_end_of_memory(void)
phys_mem.n_regions = 1;
ret = __va(phys_mem.regions[0].size);
- set_phys_avail();
+ set_phys_avail(&phys_mem);
return ret;
}
#endif /* defined(CONFIG_GEMINI) */
@@ -1412,8 +1251,8 @@ unsigned long __init *apus_find_end_of_memory(void)
}
/* Now register the memory block. */
- append_mem_piece(&phys_mem, memory[0].addr, memory[0].size);
- set_phys_avail();
+ mem_pieces_append(&phys_mem, memory[0].addr, memory[0].size);
+ set_phys_avail(&phys_mem);
/* Remove the memory chunks that are controlled by special
Phase5 hardware. */
@@ -1427,8 +1266,8 @@ unsigned long __init *apus_find_end_of_memory(void)
if (shadow)
{
top -= HARDWARE_MAPPED_SIZE;
- remove_mem_piece(&phys_avail, top,
- HARDWARE_MAPPED_SIZE, 0);
+ mem_pieces_remove(&phys_avail, top,
+ HARDWARE_MAPPED_SIZE, 0);
}
/* Remove the upper 512KB where the PPC exception
@@ -1436,9 +1275,9 @@ unsigned long __init *apus_find_end_of_memory(void)
top -= HARDWARE_MAPPED_SIZE;
#if 0
/* This would be neat, but it breaks on A3000 machines!? */
- remove_mem_piece(&phys_avail, top, 16384, 0);
+ mem_pieces_remove(&phys_avail, top, 16384, 0);
#else
- remove_mem_piece(&phys_avail, top, HARDWARE_MAPPED_SIZE, 0);
+ mem_pieces_remove(&phys_avail, top, HARDWARE_MAPPED_SIZE, 0);
#endif
}
@@ -1497,7 +1336,7 @@ static void __init hash_init(void)
if ( ppc_md.progress ) ppc_md.progress("hash:find piece", 0x322);
/* Find some memory for the hash table. */
if ( Hash_size )
- Hash = find_mem_piece(Hash_size, Hash_size);
+ Hash = mem_pieces_find(Hash_size, Hash_size);
else
Hash = 0;
@@ -1575,7 +1414,7 @@ unsigned long __init *m8xx_find_end_of_memory(void)
ret = __va(phys_mem.regions[0].address+
phys_mem.regions[0].size);
- set_phys_avail();
+ set_phys_avail(&phys_mem);
return ret;
}
#endif /* ndef CONFIG_8xx */
diff --git a/arch/ppc/mm/mem_pieces.c b/arch/ppc/mm/mem_pieces.c
new file mode 100644
index 000000000..138b2a40f
--- /dev/null
+++ b/arch/ppc/mm/mem_pieces.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Changes to accomodate Power Macintoshes.
+ * Cort Dougan <cort@cs.nmt.edu>
+ * Rewrites.
+ * Grant Erickson <grant@lcse.umn.edu>
+ * General rework and split from mm/init.c.
+ *
+ * Module name: mem_pieces.c
+ *
+ * Description:
+ * Routines and data structures for manipulating and representing
+ * phyiscal memory extents (i.e. address/length pairs).
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/stddef.h>
+#include <linux/blk.h>
+
+#include <asm/page.h>
+#include <asm/prom.h>
+
+#include "mem_pieces.h"
+
+extern char _start[], _end[];
+extern char _stext[], etext[];
+
+char *klimit = _end;
+
+struct mem_pieces phys_avail;
+
+static void mem_pieces_print(struct mem_pieces *);
+
+/*
+ * Scan a region for a piece of a given size with the required alignment.
+ */
+void __init *
+mem_pieces_find(unsigned int size, unsigned int align)
+{
+ int i;
+ unsigned a, e;
+ struct mem_pieces *mp = &phys_avail;
+
+ for (i = 0; i < mp->n_regions; ++i) {
+ a = mp->regions[i].address;
+ e = a + mp->regions[i].size;
+ a = (a + align - 1) & -align;
+ if (a + size <= e) {
+ mem_pieces_remove(mp, a, size, 1);
+ return __va(a);
+ }
+ }
+ panic("Couldn't find %u bytes at %u alignment\n", size, align);
+
+ return NULL;
+}
+
+/*
+ * Remove some memory from an array of pieces
+ */
+void __init
+mem_pieces_remove(struct mem_pieces *mp, unsigned int start, unsigned int size,
+ int must_exist)
+{
+ int i, j;
+ unsigned int end, rs, re;
+ struct reg_property *rp;
+
+ end = start + size;
+ for (i = 0, rp = mp->regions; i < mp->n_regions; ++i, ++rp) {
+ if (end > rp->address && start < rp->address + rp->size)
+ break;
+ }
+ if (i >= mp->n_regions) {
+ if (must_exist)
+ printk("mem_pieces_remove: [%x,%x) not in any region\n",
+ start, end);
+ return;
+ }
+ for (; i < mp->n_regions && end > rp->address; ++i, ++rp) {
+ rs = rp->address;
+ re = rs + rp->size;
+ if (must_exist && (start < rs || end > re)) {
+ printk("mem_pieces_remove: bad overlap [%x,%x) with",
+ start, end);
+ mem_pieces_print(mp);
+ must_exist = 0;
+ }
+ if (start > rs) {
+ rp->size = start - rs;
+ if (end < re) {
+ /* need to split this entry */
+ if (mp->n_regions >= MEM_PIECES_MAX)
+ panic("eek... mem_pieces overflow");
+ for (j = mp->n_regions; j > i + 1; --j)
+ mp->regions[j] = mp->regions[j-1];
+ ++mp->n_regions;
+ rp[1].address = end;
+ rp[1].size = re - end;
+ }
+ } else {
+ if (end < re) {
+ rp->address = end;
+ rp->size = re - end;
+ } else {
+ /* need to delete this entry */
+ for (j = i; j < mp->n_regions - 1; ++j)
+ mp->regions[j] = mp->regions[j+1];
+ --mp->n_regions;
+ --i;
+ --rp;
+ }
+ }
+ }
+}
+
+static void __init
+mem_pieces_print(struct mem_pieces *mp)
+{
+ int i;
+
+ for (i = 0; i < mp->n_regions; ++i)
+ printk(" [%x, %x)", mp->regions[i].address,
+ mp->regions[i].address + mp->regions[i].size);
+ printk("\n");
+}
+
+#if defined(CONFIG_PREP) || defined(CONFIG_APUS) || defined(CONFIG_ALL_PPC)
+/*
+ * Add some memory to an array of pieces
+ */
+void __init
+mem_pieces_append(struct mem_pieces *mp, unsigned int start, unsigned int size)
+{
+ struct reg_property *rp;
+
+ if (mp->n_regions >= MEM_PIECES_MAX)
+ return;
+ rp = &mp->regions[mp->n_regions++];
+ rp->address = start;
+ rp->size = size;
+}
+#endif
+
+void __init
+mem_pieces_sort(struct mem_pieces *mp)
+{
+ unsigned long a, s;
+ int i, j;
+
+ for (i = 1; i < mp->n_regions; ++i) {
+ a = mp->regions[i].address;
+ s = mp->regions[i].size;
+ for (j = i - 1; j >= 0; --j) {
+ if (a >= mp->regions[j].address)
+ break;
+ mp->regions[j+1] = mp->regions[j];
+ }
+ mp->regions[j+1].address = a;
+ mp->regions[j+1].size = s;
+ }
+}
+
+void __init
+mem_pieces_coalesce(struct mem_pieces *mp)
+{
+ unsigned long a, s, ns;
+ int i, j, d;
+
+ d = 0;
+ for (i = 0; i < mp->n_regions; i = j) {
+ a = mp->regions[i].address;
+ s = mp->regions[i].size;
+ for (j = i + 1; j < mp->n_regions
+ && mp->regions[j].address - a <= s; ++j) {
+ ns = mp->regions[j].address + mp->regions[j].size - a;
+ if (ns > s)
+ s = ns;
+ }
+ mp->regions[d].address = a;
+ mp->regions[d].size = s;
+ ++d;
+ }
+ mp->n_regions = d;
+}
+
+/*
+ * Set phys_avail to phys_mem less the kernel text/data/bss.
+ */
+void __init
+set_phys_avail(struct mem_pieces *mp)
+{
+ unsigned long kstart, ksize;
+
+ /*
+ * Initially, available phyiscal memory is equivalent to all
+ * physical memory.
+ */
+
+ phys_avail = *mp;
+
+ /*
+ * Map out the kernel text/data/bss from the available physical
+ * memory.
+ */
+
+ kstart = __pa(_stext); /* should be 0 */
+ ksize = PAGE_ALIGN(klimit - _stext);
+
+ printk("kstart = 0x%08lx, ksize = 0x%08lx\n", kstart, ksize);
+
+ mem_pieces_remove(&phys_avail, kstart, ksize, 0);
+ mem_pieces_remove(&phys_avail, 0, 0x4000, 0);
+
+#if defined(CONFIG_BLK_DEV_INITRD)
+ /* Remove the init RAM disk from the available memory. */
+ if (initrd_start) {
+ mem_pieces_remove(&phys_avail, __pa(initrd_start),
+ initrd_end - initrd_start, 1);
+ }
+#endif /* CONFIG_BLK_DEV_INITRD */
+}
diff --git a/arch/ppc/mm/mem_pieces.h b/arch/ppc/mm/mem_pieces.h
new file mode 100644
index 000000000..6dbe045da
--- /dev/null
+++ b/arch/ppc/mm/mem_pieces.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Changes to accomodate Power Macintoshes.
+ * Cort Dougan <cort@cs.nmt.edu>
+ * Rewrites.
+ * Grant Erickson <grant@lcse.umn.edu>
+ * General rework and split from mm/init.c.
+ *
+ * Module name: mem_pieces.h
+ *
+ * Description:
+ * Routines and data structures for manipulating and representing
+ * phyiscal memory extents (i.e. address/length pairs).
+ *
+ */
+
+#ifndef __MEM_PIECES_H__
+#define __MEM_PIECES_H__
+
+#include <linux/init.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Type Definitions */
+
+#define MEM_PIECES_MAX 32
+
+struct mem_pieces {
+ int n_regions;
+ struct reg_property regions[MEM_PIECES_MAX];
+};
+
+
+/* Global Variables */
+
+extern char *klimit;
+extern struct mem_pieces phys_avail;
+
+
+/* Function Prototypes */
+
+extern void *mem_pieces_find(unsigned int size, unsigned int align);
+extern void mem_pieces_remove(struct mem_pieces *mp, unsigned int start,
+ unsigned int size, int must_exist);
+extern void mem_pieces_append(struct mem_pieces *mp, unsigned int start,
+ unsigned int size);
+extern void mem_pieces_coalesce(struct mem_pieces *mp);
+extern void mem_pieces_sort(struct mem_pieces *mp);
+
+extern void set_phys_avail(struct mem_pieces *mp);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MEM_PIECES_H__ */
diff --git a/arch/ppc/treeboot/Makefile b/arch/ppc/treeboot/Makefile
new file mode 100644
index 000000000..405634214
--- /dev/null
+++ b/arch/ppc/treeboot/Makefile
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+#
+# Module name: Makefile
+#
+# Description:
+# Makefile for the IBM "tree" evaluation board Linux kernel
+# boot loaders.
+#
+
+HOSTCFLAGS = -O -I$(TOPDIR)/include
+
+CC = $(CROSS_COMPILE)gcc
+LD = $(CROSS_COMPILE)ld
+OBJCOPY = $(CROSS_COMPILE)objcopy
+OBJDUMP = $(CROSS_COMPILE)objdump
+
+GZIP = gzip -vf9
+RM = rm -f
+MKEVIMG = mkevimg -l
+MKIRIMG = mkirimg
+
+CFLAGS = -O -fno-builtin -I$(TOPDIR)/include
+LD_ARGS = -e _start -T ld.script -Ttext 80200000 -Bstatic
+
+OBJS = crt0.o main.o misc.o string.o zlib.o irSect.o
+LIBS =
+
+treeboot: $(OBJS) ld.script
+ $(LD) -o $@ $(LD_ARGS) $(OBJS) $(LIBS)
+
+zImage: vmlinux.img
+
+zImage.initrd: vmlinux.initrd.img
+
+treeboot.image: treeboot vmlinux.gz
+ $(OBJCOPY) --add-section=image=vmlinux.gz treeboot $@
+
+treeboot.initrd: treeboot.image ramdisk.image.gz
+ $(OBJCOPY) --add-section=initrd=ramdisk.image.gz treeboot.image $@
+
+vmlinux.img: treeboot.image
+ $(OBJDUMP) --syms treeboot.image | grep irSectStart > irSectStart.txt
+ $(MKIRIMG) treeboot.image treeboot.image.out irSectStart.txt
+ $(MKEVIMG) treeboot.image.out $@
+ $(RM) treeboot.image treeboot.image.out irSectStart.txt
+
+vmlinux.initrd.img: treeboot.initrd
+ $(OBJDUMP) --all-headers treeboot.initrd | grep irSectStart > irSectStart.txt
+ $(MKIRIMG) treeboot.initrd treeboot.initrd.out irSectStart.txt
+ $(MKEVIMG) treeboot.initrd.out $@
+ $(RM) treeboot.initrd treeboot.initrd.out irSectStart.txt
+
+vmlinux.gz: $(TOPDIR)/vmlinux
+ $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux
+ $(GZIP) vmlinux
+
+clean:
+ rm -f treeboot treeboot.image treeboot.initrd irSectStart.txt vmlinux.* *.o
+
+fastdep:
+
diff --git a/arch/ppc/treeboot/crt0.S b/arch/ppc/treeboot/crt0.S
new file mode 100644
index 000000000..1f2c1c094
--- /dev/null
+++ b/arch/ppc/treeboot/crt0.S
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Initial Power Macintosh COFF version.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * Modifications for IBM PowerPC 400-class processor evaluation
+ * boards.
+ *
+ * Module name: crt0.S
+ *
+ * Description:
+ * Boot loader execution entry point. Clears out .bss section as per
+ * ANSI C requirements. Invalidates and flushes the caches over the
+ * range covered by the boot loader's .text section. Sets up a stack
+ * below the .text section entry point.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include "../kernel/ppc_asm.h"
+
+ .text
+
+ .globl _start
+_start:
+ ## Clear out the BSS as per ANSI C requirements
+
+ lis r7,_end@ha #
+ addi r7,r7,_end@l # r7 = &_end
+ lis r8,__bss_start@ha #
+ addi r8,r8,__bss_start@l # r8 = &_bss_start
+
+ ## Determine how large an area, in number of words, to clear
+
+ subf r7,r8,r7 # r7 = &_end - &_bss_start + 1
+ addi r7,r7,3 # r7 += 3
+ srwi. r7,r7,2 # r7 = size in words.
+ beq 2f # If the size is zero, do not bother
+ addi r8,r8,-4 # r8 -= 4
+ mtctr r7 # SPRN_CTR = number of words to clear
+ li r0,0 # r0 = 0
+1: stwu r0,4(r8) # Clear out a word
+ bdnz 1b # If we are not done yet, keep clearing
+
+ ## Flush and invalidate the caches for the range in memory covering
+ ## the .text section of the boot loader
+
+2: lis r9,_start@h # r9 = &_start
+ lis r8,_etext@ha #
+ addi r8,r8,_etext@l # r8 = &_etext
+3: dcbf r0,r9 # Flush the data cache
+ icbi r0,r9 # Invalidate the instruction cache
+ addi r9,r9,0x10 # Increment by one cache line
+ cmplwi cr0,r9,r8 # Are we at the end yet?
+ blt 3b # No, keep flushing and invalidating
+
+ ## Set up the stack
+
+ lis r9,_start@h # r9 = &_start (text section entry)
+ addi r9,r9,_start@l
+ subi r1,r9,64 # Start the stack 64 bytes below _start
+ clrrwi r1,r1,4 # Make sure it is aligned on 16 bytes.
+ li r0,0
+ stwu r0,-16(r1)
+ mtlr r9
+
+ b start # All done, start the real work.
diff --git a/arch/ppc/treeboot/elf.pl b/arch/ppc/treeboot/elf.pl
new file mode 100644
index 000000000..d3e9d9d5b
--- /dev/null
+++ b/arch/ppc/treeboot/elf.pl
@@ -0,0 +1,33 @@
+#
+# ELF header field numbers
+#
+
+$e_ident = 0; # Identification bytes / magic number
+$e_type = 1; # ELF file type
+$e_machine = 2; # Target machine type
+$e_version = 3; # File version
+$e_entry = 4; # Start address
+$e_phoff = 5; # Program header file offset
+$e_shoff = 6; # Section header file offset
+$e_flags = 7; # File flags
+$e_ehsize = 8; # Size of ELF header
+$e_phentsize = 9; # Size of program header
+$e_phnum = 10; # Number of program header entries
+$e_shentsize = 11; # Size of section header
+$e_shnum = 12; # Number of section header entries
+$e_shstrndx = 13; # Section header table string index
+
+#
+# Section header field numbers
+#
+
+$sh_name = 0; # Section name
+$sh_type = 1; # Section header type
+$sh_flags = 2; # Section header flags
+$sh_addr = 3; # Virtual address
+$sh_offset = 4; # File offset
+$sh_size = 5; # Section size
+$sh_link = 6; # Miscellaneous info
+$sh_info = 7; # More miscellaneous info
+$sh_addralign = 8; # Memory alignment
+$sh_entsize = 9; # Entry size if this is a table
diff --git a/arch/ppc/treeboot/irSect.c b/arch/ppc/treeboot/irSect.c
new file mode 100644
index 000000000..7f4c7f6ab
--- /dev/null
+++ b/arch/ppc/treeboot/irSect.c
@@ -0,0 +1,36 @@
+/*
+ *
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ * Module name: irSect.c
+ *
+ * Description:
+ * Defines variables to hold the absolute starting address and size
+ * of the Linux kernel "image" and the initial RAM disk "initrd"
+ * sections within the boot loader.
+ *
+ */
+
+#include "irSect.h"
+
+
+/*
+ * The order of globals below must not change. If more globals are added,
+ * you must change the script 'mkirimg' accordingly.
+ *
+ */
+
+/*
+ * irSectStart must be at beginning of file
+ */
+unsigned int irSectStart = 0xdeadbeaf;
+
+unsigned int imageSect_start = 0;
+unsigned int imageSect_size = 0;
+unsigned int initrdSect_start = 0;
+unsigned int initrdSect_size = 0;
+
+/*
+ * irSectEnd must be at end of file
+ */
+unsigned int irSectEnd = 0xdeadbeaf;
diff --git a/arch/ppc/treeboot/irSect.h b/arch/ppc/treeboot/irSect.h
new file mode 100644
index 000000000..801c3b42e
--- /dev/null
+++ b/arch/ppc/treeboot/irSect.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ *
+ * Module name: irSect.h
+ *
+ * Description:
+ * Defines variables to hold the absolute starting address and size
+ * of the Linux kernel "image" and the initial RAM disk "initrd"
+ * sections within the boot loader.
+ *
+ */
+
+#ifndef __IRSECT_H__
+#define __IRSECT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern unsigned int imageSect_start;
+extern unsigned int imageSect_size;
+
+extern unsigned int initrdSect_start;
+extern unsigned int initrdSect_size;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __IRSECT_H__ */
diff --git a/arch/ppc/treeboot/ld.script b/arch/ppc/treeboot/ld.script
new file mode 100644
index 000000000..2469ed65d
--- /dev/null
+++ b/arch/ppc/treeboot/ld.script
@@ -0,0 +1,68 @@
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+ __DYNAMIC = 0; */
+SECTIONS
+{
+ /* Read-only sections, merged into text segment: */
+ . = + SIZEOF_HEADERS;
+ .interp : { *(.interp) }
+ .hash : { *(.hash) }
+ .dynsym : { *(.dynsym) }
+ .dynstr : { *(.dynstr) }
+ .rel.text : { *(.rel.text) }
+ .rela.text : { *(.rela.text) }
+ .rel.data : { *(.rel.data) }
+ .rela.data : { *(.rela.data) }
+ .rel.rodata : { *(.rel.rodata) }
+ .rela.rodata : { *(.rela.rodata) }
+ .rel.got : { *(.rel.got) }
+ .rela.got : { *(.rela.got) }
+ .rel.ctors : { *(.rel.ctors) }
+ .rela.ctors : { *(.rela.ctors) }
+ .rel.dtors : { *(.rel.dtors) }
+ .rela.dtors : { *(.rela.dtors) }
+ .rel.bss : { *(.rel.bss) }
+ .rela.bss : { *(.rela.bss) }
+ .rel.plt : { *(.rel.plt) }
+ .rela.plt : { *(.rela.plt) }
+ .init : { *(.init) } =0
+ .plt : { *(.plt) }
+ .text :
+ {
+ *(.text)
+ *(.rodata)
+ *(.rodata1)
+ *(.got1)
+ }
+ .fini : { *(.fini) } =0
+ .ctors : { *(.ctors) }
+ .dtors : { *(.dtors) }
+ _etext = .;
+ PROVIDE (etext = .);
+ /* Read-write section, merged into data segment: */
+ . = (. + 0x0FFF) & 0xFFFFF000;
+ .data :
+ {
+ *(.data)
+ *(.data1)
+ *(.sdata)
+ *(.sdata2)
+ *(.got.plt) *(.got)
+ *(.dynamic)
+ CONSTRUCTORS
+ }
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ .bss :
+ {
+ *(.sbss) *(.scommon)
+ *(.dynbss)
+ *(.bss)
+ *(COMMON)
+ }
+ _end = . ;
+ PROVIDE (end = .);
+}
+
diff --git a/arch/ppc/treeboot/main.c b/arch/ppc/treeboot/main.c
new file mode 100644
index 000000000..1b5ef3805
--- /dev/null
+++ b/arch/ppc/treeboot/main.c
@@ -0,0 +1,209 @@
+/*
+ * Copyright (c) 1997 Paul Mackerras <paulus@cs.anu.edu.au>
+ * Initial Power Macintosh COFF version.
+ * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+ * Modifications for an ELF-based IBM evaluation board version.
+ *
+ * Module name: main.c
+ *
+ * Description:
+ * This module does most of the real work for the boot loader. It
+ * checks the variables holding the absolute start address and size
+ * of the Linux kernel "image" and initial RAM disk "initrd" sections
+ * and if they are present, moves them to their "proper" locations.
+ *
+ * For the Linux kernel, "proper" is physical address 0x00000000.
+ * For the RAM disk, "proper" is the image's size below the top
+ * of physical memory. The Linux kernel may be in either raw
+ * binary form or compressed with GNU zip (aka gzip).
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ */
+
+#include "nonstdio.h"
+#include "zlib.h"
+#include "irSect.h"
+
+
+/* Preprocessor Defines */
+
+#define RAM_SIZE (4 * 1024 * 1024)
+
+#define RAM_PBASE 0x00000000
+#define RAM_PEND (RAM_PBASE + RAM_SIZE)
+
+#define RAM_VBASE 0xC0000000
+#define RAM_VEND (RAM_VBASE + RAM_SIZE)
+
+#define RAM_START RAM_PBASE
+#define RAM_END RAM_PEND
+#define RAM_FREE (imageSect_start + imageSect_size + initrdSect_size)
+
+#define PROG_START RAM_START
+
+
+/* Function Macros */
+
+#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1))
+
+
+/* Global Variables */
+
+/* Needed by zalloc and zfree for allocating memory */
+
+char *avail_ram; /* Indicates start of RAM available for heap */
+char *end_avail; /* Indicates end of RAM available for heap */
+
+
+/* Function Prototypes */
+
+void *zalloc(void *x, unsigned items, unsigned size);
+void zfree(void *x, void *addr, unsigned nb);
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp);
+
+void printf () {}
+void pause () {}
+void exit () {}
+
+
+void start(void)
+{
+ void *options;
+ int ns, oh, i;
+ unsigned sa, len;
+ void *dst;
+ unsigned char *im;
+ unsigned initrd_start, initrd_size;
+
+ /* setup_bats(RAM_START); */
+
+ /* Init RAM disk (initrd) section */
+
+ if (initrdSect_start != 0 && (initrd_size = initrdSect_size) != 0) {
+ initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+
+ printf("Initial RAM disk at 0x%08x (%u bytes)\n",
+ initrd_start, initrd_size);
+
+ memcpy((char *)initrd_start,
+ (char *)(initrdSect_start),
+ initrdSect_size);
+
+ end_avail = (char *)initrd_start;
+ } else {
+ end_avail = (char *)RAM_END;
+ }
+
+ /* Linux kernel image section */
+
+ im = (unsigned char *)(imageSect_start);
+ len = imageSect_size;
+ dst = (void *)PROG_START;
+
+ /* Check for the gzip archive magic numbers */
+
+ if (im[0] == 0x1f && im[1] == 0x8b) {
+
+ /* The gunzip routine needs everything nice and aligned */
+
+ void *cp = (void *)ALIGN_UP(RAM_FREE, 8);
+ avail_ram = (void *)(cp + ALIGN_UP(len, 8));
+ memcpy(cp, im, len);
+
+ /* I'm not sure what the 0x200000 parameter is for, but it works. */
+
+ gunzip(dst, 0x200000, cp, &len);
+ } else {
+ memmove(dst, im, len);
+ }
+
+ /* flush_cache(dst, len); */
+
+ sa = (unsigned long)dst;
+
+ (*(void (*)())sa)();
+
+ pause();
+}
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+ void *p = avail_ram;
+
+ size *= items;
+ size = ALIGN_UP(size, 8);
+ avail_ram += size;
+ if (avail_ram > end_avail) {
+ printf("oops... out of memory\n");
+ pause();
+ }
+ return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+
+}
+
+#define HEAD_CRC 2
+#define EXTRA_FIELD 4
+#define ORIG_NAME 8
+#define COMMENT 0x10
+#define RESERVED 0xe0
+
+#define DEFLATED 8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+ z_stream s;
+ int r, i, flags;
+
+ /* skip header */
+ i = 10;
+ flags = src[3];
+ if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+ printf("bad gzipped data\n");
+ exit();
+ }
+ if ((flags & EXTRA_FIELD) != 0)
+ i = 12 + src[10] + (src[11] << 8);
+ if ((flags & ORIG_NAME) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & COMMENT) != 0)
+ while (src[i++] != 0)
+ ;
+ if ((flags & HEAD_CRC) != 0)
+ i += 2;
+ if (i >= *lenp) {
+ printf("gunzip: ran out of data in header\n");
+ exit();
+ }
+ printf("done 1\n");
+ s.zalloc = zalloc;
+ s.zfree = zfree;
+ r = inflateInit2(&s, -MAX_WBITS);
+ if (r != Z_OK) {
+ printf("inflateInit2 returned %d\n", r);
+ exit();
+ }
+ s.next_in = src + i;
+ s.avail_in = *lenp - i;
+ s.next_out = dst;
+ s.avail_out = dstlen;
+ printf("doing inflate\n");
+ r = inflate(&s, Z_FINISH);
+ printf("done inflate\n");
+ if (r != Z_OK && r != Z_STREAM_END) {
+ printf("inflate returned %d\n", r);
+ exit();
+ }
+ *lenp = s.next_out - (unsigned char *) dst;
+ printf("doing end\n");
+ inflateEnd(&s);
+}
diff --git a/arch/ppc/treeboot/misc.S b/arch/ppc/treeboot/misc.S
new file mode 100644
index 000000000..27417563f
--- /dev/null
+++ b/arch/ppc/treeboot/misc.S
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+ .text
+
+/*
+ * Flush the dcache and invalidate the icache for a range of addresses.
+ *
+ * flush_cache(addr, len)
+ */
+ .global flush_cache
+flush_cache:
+ addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */
+ rlwinm. 4,4,27,5,31
+ mtctr 4
+ beqlr
+1: dcbf 0,3
+ icbi 0,3
+ addi 3,3,0x20
+ bdnz 1b
+ sync
+ isync
+ blr
diff --git a/arch/ppc/treeboot/mkevimg b/arch/ppc/treeboot/mkevimg
new file mode 100644
index 000000000..76f849bb7
--- /dev/null
+++ b/arch/ppc/treeboot/mkevimg
@@ -0,0 +1,437 @@
+#!/usr/local/bin/perl
+
+#
+# Copyright (c) 1998-1999 TiVo, Inc.
+# All rights reserved.
+#
+# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+# Major syntactic and usability rework.
+#
+# Module name: mkevimg
+#
+# Description:
+# Converts an ELF output file from the linker into the format used by
+# the IBM evaluation board ROM Monitor to load programs from a host
+# onto the evaluation board. The ELF file must be an otherwise execut-
+# able file (with the text and data addresses bound at link time) and
+# have space reserved after the entry point for the load information
+# block:
+#
+# typedef struct boot_block {
+# unsigned long magic; 0x0052504F
+# unsigned long dest; Target address of the image
+# unsigned long num_512blocks; Size, rounded-up, in 512 byte blocks
+# unsigned long debug_flag; Run the debugger or image after load
+# unsigned long entry_point; The image address to jump to after load
+# unsigned long reserved[3];
+# } boot_block_t;
+#
+#
+
+use File::Basename;
+use Getopt::Std;
+
+#
+# usage()
+#
+# Description:
+# This routine prints out the proper command line usage for this program
+#
+# Input(s):
+# status - Flag determining what usage information will be printed and what
+# the exit status of the program will be after the information is
+# printed.
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# This subroutine does not return.
+#
+
+sub usage {
+ my($status);
+ $status = $_[0];
+
+ printf("Usage: %s [-hlvV] <ELF input file> <Evaluation board output file>\n",
+ $program);
+
+ if ($status != 0) {
+ printf("Try `%s -h' for more information.\n", $program);
+ }
+
+ if ($status != 1) {
+ print(" -h Print out this message and exit.\n");
+ print(" -l Linux mode; if present, copy 'image' and 'initrd' sections.\n");
+ print(" -v Verbose. Print out lots of ELF information.\n");
+ print(" -V Print out version information and exit.\n");
+ }
+
+ exit($status);
+}
+
+#
+# version()
+#
+# Description:
+# This routine prints out program version information
+#
+# Input(s):
+# N/A
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# This subroutine does not return.
+#
+
+sub version {
+ print("mkevimg Version 1.1.0\n");
+ print("Copyright (c) 1998-1999 TiVo, Inc.\n");
+ print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n");
+
+ exit (0);
+}
+
+#
+# file_check()
+#
+# Description:
+# This routine checks an input file to ensure that it exists, is a
+# regular file, and is readable.
+#
+# Input(s):
+# file - Input file to be checked.
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# 0 if the file exists, is a regular file, and is readable, otherwise -1.
+#
+
+sub file_check {
+ my($file);
+ $file = $_[0];
+
+ if (!(-e $file)) {
+ printf("The file \"%s\" does not exist.\n", $file);
+ return (-1);
+ } elsif (!(-f $file)) {
+ printf("The file \"%s\" is not a regular file.\n", $file);
+ return (-1);
+ } elsif (!(-r $file)) {
+ printf("The file \"%s\" is not readable.\n", $file);
+ return (-1);
+ }
+
+ return (0);
+}
+
+#
+# decode_options()
+#
+# Description:
+# This routine steps through the command-line arguments, parsing out
+# recognzied options.
+#
+# Input(s):
+# N/A
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# N/A
+#
+
+sub decode_options {
+
+ if (!getopts("hlvV")) {
+ usage(1);
+ }
+
+ if ($opt_h) {
+ usage(0);
+ }
+
+ if ($opt_l) {
+ $linux = 1;
+ }
+
+ if ($opt_V) {
+ version();
+ exit (0);
+ }
+
+ if ($opt_v) {
+ $verbose = 1;
+ }
+
+ if (!($ifile = shift(@ARGV))) {
+ usage(1);
+ }
+
+ if (!($ofile = shift(@ARGV))) {
+ usage (1);
+ }
+
+ if (file_check($ifile)) {
+ exit(1);
+ }
+
+}
+
+#
+# ELF file and section header field numbers
+#
+
+require 'elf.pl';
+
+#
+# Main program body
+#
+
+{
+ $program = basename($0);
+
+ decode_options();
+
+ open(ELF, "<$ifile") || die "Cannot open input file";
+
+ $ifilesize = (-s $ifile);
+
+ if ($verbose) {
+ print("Output file: $ofile\n");
+ print("Input file: $ifile, $ifilesize bytes.\n");
+ }
+
+ if (read(ELF, $ibuf, $ifilesize) != $ifilesize) {
+ print("Failed to read input file!\n");
+ exit(1);
+ }
+
+ #
+ # Parse ELF header
+ #
+
+ @eh = unpack("a16n2N5n6", $ibuf);
+
+ #
+ # Make sure this is actually a PowerPC ELF file.
+ #
+
+ if (substr($eh[$e_ident], 0, 4) ne "\177ELF") {
+ printf("The file \"%s\" is not an ELF file.\n", $ifile);
+ exit (1);
+ } elsif ($eh[$e_machine] != 20) {
+ printf("The file \"%s\" is not a PowerPC ELF file.\n", $ifile);
+ exit (1);
+ }
+
+ if ($verbose) {
+ print("File header:\n");
+ printf(" Identifier: %s\n", $eh[$e_ident]);
+ printf(" Type: %d\n", $eh[$e_type]);
+ printf(" Machine: %d\n", $eh[$e_machine]);
+ printf(" Version: %d\n", $eh[$e_version]);
+ printf(" Entry point: 0x%08x\n", $eh[$e_entry]);
+ printf(" Program header offset: 0x%x\n", $eh[$e_phoff]);
+ printf(" Section header offset: 0x%x\n", $eh[$e_shoff]);
+ printf(" Flags: 0x%08x\n", $eh[$e_flags]);
+ printf(" Header size: %d\n", $eh[$e_ehsize]);
+ printf(" Program entry size: %d\n", $eh[$e_phentsize]);
+ printf(" Program table entries: %d\n", $eh[$e_phnum]);
+ printf(" Section header size: %d\n", $eh[$e_shentsize]);
+ printf(" Section table entries: %d\n", $eh[$e_shnum]);
+ printf(" String table section: %d\n", $eh[$e_shstrndx]);
+ }
+
+ #
+ # Find the section header for the string table.
+ #
+
+ $strtable_section_offset = $eh[$e_shoff] +
+ $eh[$e_shstrndx] * $eh[$e_shentsize];
+
+ if ($verbose) {
+ printf("String table section header offset: 0x%x\n",
+ $strtable_section_offset);
+ }
+
+ #
+ # Find the start of the string table.
+ #
+
+ @strh = unpack("N10", substr($ibuf, $strtable_section_offset,
+ $eh[$e_shentsize]));
+
+ if ($verbose) {
+ printf("Section name strings start at: 0x%x, %d bytes.\n",
+ $strh[$sh_offset], $strh[$sh_size]);
+ }
+
+ $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]);
+
+ # Grab each section header and find '.text' and '.bss' sections in
+ # particular.
+
+ if ($verbose) {
+ print("Section headers:\n");
+ print("Idx Name Size Address File off Algn\n");
+ print("--- ------------------------ -------- -------- -------- ----\n");
+ }
+
+ $off = $eh[$e_shoff];
+
+ for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) {
+ @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize]));
+
+ # Take the first section name from the array returned by split.
+
+ ($name) = split(/\000/, substr($names, $sh[$sh_name]));
+
+ if ($verbose) {
+ printf("%3d %-24s %8x %08x %08x %4d\n",
+ $i, $name, $sh[$sh_size], $sh[$sh_addr],
+ $sh[$sh_offset], $sh[$sh_addralign]);
+ }
+
+ # Attempt to find the .text and .bss sections
+
+ if ($name =~ /^\.bss$/) {
+ ($bss_addr, $bss_offset, $bss_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+ } elsif ($name =~ /^\.text$/) {
+ ($text_addr, $text_offset, $text_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+ } elsif ($linux && ($name =~ /^\image$/)) {
+ $image_found = 1;
+
+ ($image_addr, $image_offset, $image_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+ } elsif ($linux && ($name =~ /^\initrd$/)) {
+ $initrd_found = 1;
+
+ ($initrd_addr, $initrd_offset, $initrd_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+ }
+ }
+
+ printf("Text section - Address: 0x%08x, Size: 0x%08x\n",
+ $text_addr, $text_size);
+ printf("Bss section - Address: 0x%08x, Size: 0x%08x\n",
+ $bss_addr, $bss_size);
+
+ if ($linux) {
+ if ($image_found) {
+ printf("Image section - Address: 0x%08x, Size: 0x%08x\n",
+ $image_addr, $image_size);
+ }
+
+ if ($initrd_found) {
+ printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n",
+ $initrd_addr, $initrd_size);
+ }
+ }
+
+ #
+ # Open output file
+ #
+
+ open(BOOT, ">$ofile") || die "Cannot open output file";
+
+ #
+ # Compute image size
+ #
+
+ $output_size = $bss_offset - $text_offset + $bss_size;
+
+ if ($linux && $image_found) {
+ $output_size += $image_size;
+ }
+
+ if ($linux && $initrd_found) {
+ $output_size += $initrd_size;
+ }
+
+ $num_blocks = $output_size / 512 + 1;
+
+ #
+ # Write IBM PowerPC evaluation board boot_block_t header
+ #
+
+ $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0,
+ $text_addr, 0, 0, 0);
+
+ $bytes = length($header);
+
+ if (($resid = syswrite(BOOT, $header, $bytes)) != $bytes) {
+ die("Could not write boot image header to output file.");
+ }
+
+ printf("Entry point = 0x%08x\n", $text_addr);
+ printf("Image size = 0x%08x (%d bytes) (%d blocks).\n",
+ $output_size, $output_size, $num_blocks);
+
+ #
+ # Write image starting after ELF and program headers and
+ # continuing to beginning of bss
+ #
+
+ $bytes = $bss_offset - $text_offset + $bss_size;
+
+ if (($resid = syswrite(BOOT, $ibuf, $bytes, $text_offset)) != $bytes) {
+ die("Could not write boot image to output file.\n");
+ }
+
+ #
+ # If configured, write out the image and initrd sections as well
+ #
+
+ if ($linux) {
+ if ($image_found) {
+ $bytes = $image_size;
+ if (($resid = syswrite(BOOT, $ibuf, $bytes, $image_offset)) != $bytes) {
+ die("Could not write boot image to output file.\n");
+ }
+ }
+
+ if ($initrd_found) {
+ $bytes = $initrd_size;
+ if (($resid = syswrite(BOOT, $ibuf, $bytes, $initrd_offset)) != $bytes) {
+ die("Could not write boot image to output file.\n");
+ }
+ }
+ }
+
+ #
+ # Pad to a multiple of 512 bytes
+ #
+
+ $pad_size = 512 - (length($header) + $output_size) % 512;
+
+ if ($verbose) {
+ print("Padding boot image by an additional $pad_size bytes.\n");
+ }
+
+ $pad_string = pack(("H8","deadbeef") x 128);
+
+ syswrite(BOOT, $pad_string, $pad_size) or
+ die "Could not pad boot image in output file.\n";
+
+ #
+ # Clean-up and leave
+ #
+
+ close(BOOT);
+
+ print("\nBoot image file \"$ofile\" built successfuly.\n\n");
+
+ exit(0);
+}
diff --git a/arch/ppc/treeboot/mkirimg b/arch/ppc/treeboot/mkirimg
new file mode 100644
index 000000000..e8aa24e3d
--- /dev/null
+++ b/arch/ppc/treeboot/mkirimg
@@ -0,0 +1,367 @@
+#!/usr/local/bin/perl
+#
+# Copyright (c) 1998-1999 TiVo, Inc.
+# Original ELF parsing code.
+#
+# Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
+# Original code from 'mkevimg'.
+#
+# Module name: mkirimg
+#
+# Description:
+# Reads an ELF file and assigns global variables 'imageSect_start',
+# 'imageSect_size', 'initrdSect_start', and 'initrdSect_size' from
+# the "image" and "initrd" section header information. It then
+# rewrites the input ELF file with assigned globals to an output
+# file.
+#
+# An input file, "irSectStart.txt" has the memory address of
+# 'irSectStart'. The irSectStart memory address is used to find
+# the global variables in the ".data" section of the ELF file.
+# The 'irSectStart' and the above global variables are defined
+# in "irSect.c".
+#
+#
+
+use File::Basename;
+use Getopt::Std;
+
+#
+# usage()
+#
+# Description:
+# This routine prints out the proper command line usage for this program
+#
+# Input(s):
+# status - Flag determining what usage information will be printed and what
+# the exit status of the program will be after the information is
+# printed.
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# This subroutine does not return.
+#
+
+sub usage {
+ my($status);
+ $status = $_[0];
+
+ printf("Usage: %s [-hvV] <ELF input file> <Evaluation board output file> <irSectStart.txt file>\n",
+ $program);
+
+ if ($status != 0) {
+ printf("Try `%s -h' for more information.\n", $program);
+ }
+
+ if ($status != 1) {
+ print(" -h Print out this message and exit.\n");
+ print(" -v Verbose. Print out lots of ELF information.\n");
+ print(" -V Print out version information and exit.\n");
+ }
+
+ exit($status);
+}
+
+#
+# version()
+#
+# Description:
+# This routine prints out program version information
+#
+# Input(s):
+# N/A
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# This subroutine does not return.
+#
+
+sub version {
+ print("mkirimg Version 1.1.0\n");
+ print("Copyright (c) 1998-1999 TiVo, Inc.\n");
+ print("Copyright (c) 1999 Grant Erickson <grant\@lcse.umn.edu>\n");
+
+ exit (0);
+}
+
+#
+# file_check()
+#
+# Description:
+# This routine checks an input file to ensure that it exists, is a
+# regular file, and is readable.
+#
+# Input(s):
+# file - Input file to be checked.
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# 0 if the file exists, is a regular file, and is readable, otherwise -1.
+#
+
+sub file_check {
+ my($file);
+ $file = $_[0];
+
+ if (!(-e $file)) {
+ printf("The file \"%s\" does not exist.\n", $file);
+ return (-1);
+ } elsif (!(-f $file)) {
+ printf("The file \"%s\" is not a regular file.\n", $file);
+ return (-1);
+ } elsif (!(-r $file)) {
+ printf("The file \"%s\" is not readable.\n", $file);
+ return (-1);
+ }
+
+ return (0);
+}
+
+#
+# decode_options()
+#
+# Description:
+# This routine steps through the command-line arguments, parsing out
+# recognzied options.
+#
+# Input(s):
+# N/A
+#
+# Output(s):
+# N/A
+#
+# Returns:
+# N/A
+#
+
+sub decode_options {
+
+ if (!getopts("hvV")) {
+ usage(1);
+ }
+
+ if ($opt_h) {
+ usage(0);
+ }
+
+ if ($opt_V) {
+ version();
+ exit (0);
+ }
+
+ if ($opt_v) {
+ $verbose = 1;
+ }
+
+ if (!($ElfFile = shift(@ARGV))) {
+ usage(1);
+ }
+
+ if (!($OutputFile = shift(@ARGV))) {
+ usage (1);
+ }
+
+ if (!($IrFile = shift(@ARGV))) {
+ usage (1);
+ }
+
+ if (file_check($ElfFile)) {
+ exit(1);
+ }
+
+ if (file_check($IrFile)) {
+ exit(1);
+ }
+}
+
+#
+# ELF file and section header field numbers
+#
+
+require 'elf.pl';
+
+#
+# Main program body
+#
+
+{
+ $program = basename($0);
+ decode_options();
+
+ open(ELF, "<$ElfFile") || die "Cannot open input file";
+ open(OUTPUT, ">$OutputFile") || die "Cannot open output file";
+ open(IR, "$IrFile") || die "Cannot open input file";
+
+ $ElfFilesize = (-s $ElfFile);
+
+ if (read(ELF, $ibuf, $ElfFilesize) != $ElfFilesize) {
+ print("Failed to read ELF input file!\n");
+ exit(1);
+ }
+
+ if (read(IR, $irbuf, 8) != 8) {
+ print("Failed to read Ir input file!\n");
+ exit(1);
+ }
+
+ #
+ # Parse ELF header
+ #
+
+ @eh = unpack("a16n2N5n6", $ibuf);
+
+ #
+ # Make sure this is actually a PowerPC ELF file.
+ #
+
+ if (substr($eh[$e_ident], 0, 4) ne "\177ELF") {
+ printf("The file \"%s\" is not an ELF file.\n", $ElfFile);
+ exit (1);
+ } elsif ($eh[$e_machine] != 20) {
+ printf("The file \"%s\" is not a PowerPC ELF file.\n", $ElfFile);
+ exit (1);
+ }
+
+ #
+ # Find the section header for the string table.
+ #
+
+ $strtable_section_offset = $eh[$e_shoff] +
+
+ $eh[$e_shstrndx] * $eh[$e_shentsize];
+
+ if ($verbose) {
+ printf("String table section header offset: 0x%x\n",
+ $strtable_section_offset);
+ }
+
+ #
+ # Find the start of the string table.
+ #
+
+ @strh = unpack("N10", substr($ibuf, $strtable_section_offset,
+ $eh[$e_shentsize]));
+
+ if ($verbose) {
+ printf("Section name strings start at: 0x%x, %d bytes.\n",
+ $strh[$sh_offset], $strh[$sh_size]);
+ }
+
+ $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]);
+
+ # Grab each section header and find '.data', 'image', and
+ # 'initrd' sections in particular.
+
+ $off = $eh[$e_shoff];
+ $imageFound = 0;
+ $initrdFound = 0;
+
+ for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) {
+ @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize]));
+
+ # Take the first section name from the array returned by split.
+
+ ($name) = split(/\000/, substr($names, $sh[$sh_name]));
+
+ # Attempt to find the .data, image, and initrd sections
+
+ if ($name =~ /^\image$/) {
+ ($image_addr, $image_offset, $image_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+ $imageFound = 1;
+
+ } elsif ($name =~ /^\initrd$/) {
+ ($initrd_addr, $initrd_offset, $initrd_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+ $initrdFound = 1;
+
+ } elsif ($name =~ /^\.data$/) {
+ ($data_addr, $data_offset, $data_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+ } elsif ($name =~ /^\.bss$/) {
+ ($bss_addr, $bss_offset, $bss_size) =
+ ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]);
+
+ }
+ }
+
+ if ($verbose) {
+ printf("Data section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n",
+ $data_addr, $data_size, $data_offset);
+ printf("Bss section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n",
+ $bss_addr, $bss_size, $bss_offset);
+ }
+
+ if ($verbose) {
+ if ($imageFound) {
+ printf("Image section - Address: 0x%08x, Size: 0x%08x\n",
+ $image_addr, $image_size);
+ } else {
+ printf("Image section not found in file: $ElfFile\n");
+ }
+
+ if ($initrdFound) {
+ printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n",
+ $initrd_addr, $initrd_size);
+ } else {
+ printf("Initrd section not found in file: $ElfFile\n");
+ }
+ }
+
+ # get file offset of irSectStart
+
+ $irSectStartoffset = hex ($irbuf);
+
+ if ($verbose) {
+ printf("irSectStartOffset Address: 0x%08x\n", $irSectStartoffset);
+ }
+
+ # get the offset of global variables
+
+ $initialOffset = ($irSectStartoffset - $data_addr) + $data_offset + 4;
+
+ # write modified values to OUTPUT file
+
+ syswrite(OUTPUT, $ibuf, $initialOffset);
+
+ if ($imageFound) {
+ $testN = pack ("I2", $bss_addr + $bss_size, $image_size);
+ syswrite(OUTPUT, $testN, length($testN));
+ printf("Updated symbol \"imageSect_start\" to 0x%08x\n",
+ $bss_addr + $bss_size);
+ printf("Updated symbol \"imageSect_size\" to 0x%08x\n", $image_size);
+ } else {
+ syswrite(OUTPUT, $ibuf, 8, $initialOffset);
+ }
+
+ if ($initrdFound) {
+ $testN = pack ("I2", $bss_addr + $bss_size + $image_size, $initrd_size);
+ syswrite(OUTPUT, $testN, length($testN));
+ printf("Updated symbol \"initrdSect_start\" to 0x%08x\n",
+ $bss_addr + $bss_size + $image_size);
+ printf("Updated symbol \"initrdSect_size\" to 0x%08x\n", $initrd_size);
+ } else {
+ syswrite(OUTPUT, $ibuf,8, $initialOffset + 8);
+ }
+
+ syswrite(OUTPUT, $ibuf, $ElfFilesize - ($initialOffset + 16),
+ $initialOffset + 16);
+
+ #
+ # Clean-up and leave
+ #
+
+ close (ELF);
+ close (OUTPUT);
+ close (IR);
+
+ exit (0);
+}
+
diff --git a/arch/ppc/xmon/ppc-opc.c b/arch/ppc/xmon/ppc-opc.c
index b3566863d..5e838d924 100644
--- a/arch/ppc/xmon/ppc-opc.c
+++ b/arch/ppc/xmon/ppc-opc.c
@@ -533,8 +533,7 @@ extract_bdp (insn, invalid)
/* Check for legal values of a BO field. */
static int
-valid_bo (value)
- long value;
+valid_bo (long value)
{
/* Certain encodings have bits that are required to be zero. These
are (z must be zero, y may be anything):
diff --git a/arch/ppc/xmon/privinst.h b/arch/ppc/xmon/privinst.h
index 9a46f1aee..ec281a154 100644
--- a/arch/ppc/xmon/privinst.h
+++ b/arch/ppc/xmon/privinst.h
@@ -70,4 +70,13 @@ static inline void store_inst(void *p)
asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p));
}
+static inline void cflush(void *p)
+{
+ asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p));
+}
+
+static inline void cinval(void *p)
+{
+ asm volatile ("dcbi 0,%0; icbi 0,%0" : : "r" (p));
+}
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index 1b0fffd71..9fc97b5a9 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -6,11 +6,11 @@
#include <asm/machdep.h>
#include <asm/io.h>
#include <asm/page.h>
-#include <asm/pgtable.h>
#include <linux/adb.h>
#include <linux/pmu.h>
#include <asm/prom.h>
#include <asm/bootx.h>
+#include <asm/processor.h>
static volatile unsigned char *sccc, *sccd;
unsigned long TXRDY, RXRDY;
@@ -41,7 +41,7 @@ xmon_map_scc(void)
#ifdef CONFIG_BOOTX_TEXT
if (boot_infos != 0 && find_via_pmu()) {
- printk(KERN_INFO "xmon uses screen and keyboard\n");
+ printk("xmon uses screen and keyboard\n");
use_screen = 1;
map_bootx_text();
return;
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index b07d7fc99..f5a42cc29 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -79,6 +79,7 @@ static void remove_bpts(void);
static void insert_bpts(void);
static struct bpt *at_breakpoint(unsigned pc);
static void bpt_cmds(void);
+static void cacheflush(void);
extern int print_insn_big_powerpc(FILE *, unsigned long, unsigned);
extern void printf(const char *fmt, ...);
@@ -342,11 +343,9 @@ cmds(struct pt_regs *excp)
case 't':
backtrace(excp);
break;
-#if 0
case 'f':
- openforth();
+ cacheflush();
break;
-#endif
case 'h':
dump_hash_table();
break;
@@ -541,6 +540,30 @@ prregs(struct pt_regs *fp)
fp->ctr, fp->xer, fp->trap);
}
+void
+cacheflush(void)
+{
+ int cmd;
+ unsigned nflush;
+
+ cmd = inchar();
+ if (cmd != 'i')
+ termch = cmd;
+ scanhex(&adrs);
+ if (termch != '\n')
+ termch = 0;
+ nflush = 1;
+ scanhex(&nflush);
+ nflush = (nflush + 31) / 32;
+ if (cmd != 'i') {
+ for (; nflush > 0; --nflush, adrs += 0x20)
+ cflush((void *) adrs);
+ } else {
+ for (; nflush > 0; --nflush, adrs += 0x20)
+ cinval((void *) adrs);
+ }
+}
+
unsigned int
read_spr(int n)
{
diff --git a/arch/sh/defconfig b/arch/sh/defconfig
index 6a65ad411..37440e7c0 100644
--- a/arch/sh/defconfig
+++ b/arch/sh/defconfig
@@ -82,9 +82,6 @@ CONFIG_EXT2_FS=y
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
diff --git a/arch/sh/kernel/irq_onchip.c b/arch/sh/kernel/irq_onchip.c
index f03456bfa..cd28d2a59 100644
--- a/arch/sh/kernel/irq_onchip.c
+++ b/arch/sh/kernel/irq_onchip.c
@@ -8,6 +8,7 @@
*
*/
+#include <linux/config.h>
#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/kernel_stat.h>
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 8583afff1..7c9fbbf00 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -566,6 +566,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
case SIGQUIT: case SIGILL: case SIGTRAP:
case SIGABRT: case SIGFPE: case SIGSEGV:
+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
/* FALLTHRU */
diff --git a/arch/sh/mm/ioremap.c b/arch/sh/mm/ioremap.c
index 90fd190ef..c12b97d18 100644
--- a/arch/sh/mm/ioremap.c
+++ b/arch/sh/mm/ioremap.c
@@ -123,7 +123,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
/*
* Ok, go for it..
*/
- area = get_vm_area(size);
+ area = get_vm_area(size, VM_IOREMAP);
if (!area)
return NULL;
addr = area->addr;
diff --git a/arch/sparc/config.in b/arch/sparc/config.in
index 81fc41f5d..27a756a2a 100644
--- a/arch/sparc/config.in
+++ b/arch/sparc/config.in
@@ -29,6 +29,7 @@ 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
+ source drivers/pci/Config.in
fi
mainmenu_option next_comment
diff --git a/arch/sparc/defconfig b/arch/sparc/defconfig
index 98d1431a5..1c14e11ff 100644
--- a/arch/sparc/defconfig
+++ b/arch/sparc/defconfig
@@ -23,6 +23,7 @@ CONFIG_VT_CONSOLE=y
# CONFIG_SMP is not set
# CONFIG_SUN4 is not set
# CONFIG_PCI is not set
+# CONFIG_PCI_NAMES is not set
#
# Console drivers
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index 7fb43e354..f2065d20e 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -1162,7 +1162,8 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
continue;
case SIGQUIT: case SIGILL: case SIGTRAP:
- case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS:
+ case SIGABRT: case SIGFPE: case SIGSEGV:
+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
#ifdef DEBUG_SIGNALS
diff --git a/arch/sparc/math-emu/math.c b/arch/sparc/math-emu/math.c
index 301cebd1b..050431cfc 100644
--- a/arch/sparc/math-emu/math.c
+++ b/arch/sparc/math-emu/math.c
@@ -70,10 +70,10 @@
#include <asm/uaccess.h>
#include "sfp-util.h"
-#include "soft-fp.h"
-#include "single.h"
-#include "double.h"
-#include "quad.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+#include <math-emu/double.h>
+#include <math-emu/quad.h>
#define FLOATFUNC(x) extern int x(void *,void *,void *)
diff --git a/arch/sparc/math-emu/sfp-machine.h b/arch/sparc/math-emu/sfp-machine.h
deleted file mode 100644
index c3f12332d..000000000
--- a/arch/sparc/math-emu/sfp-machine.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/* Machine-dependent software floating-point definitions.
- Sparc userland (_Q_*) version.
- Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Richard Henderson (rth@cygnus.com),
- Jakub Jelinek (jj@ultra.linux.cz),
- David S. Miller (davem@redhat.com) and
- Peter Maydell (pmaydell@chiark.greenend.org.uk).
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, write to the Free Software Foundation, Inc.,
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef _SFP_MACHINE_H
-#define _SFP_MACHINE_H
-
-#define _FP_W_TYPE_SIZE 32
-#define _FP_W_TYPE unsigned long
-#define _FP_WS_TYPE signed long
-#define _FP_I_TYPE long
-
-#define _FP_MUL_MEAT_S(R,X,Y) \
- _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_D(R,X,Y) \
- _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_Q(R,X,Y) \
- _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y)
-#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
-#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
-#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
-#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
-#define _FP_NANSIGN_S 0
-#define _FP_NANSIGN_D 0
-#define _FP_NANSIGN_Q 0
-
-#define _FP_KEEPNANFRACP 1
-
-/* If one NaN is signaling and the other is not,
- * we choose that one, otherwise we choose X.
- */
-/* For _Qp_* and _Q_*, this should prefer X, for
- * CPU instruction emulation this should prefer Y.
- * (see SPAMv9 B.2.2 section).
- */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
- do { \
- if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs) \
- && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
- { \
- R##_s = X##_s; \
- _FP_FRAC_COPY_##wc(R,X); \
- } \
- else \
- { \
- R##_s = Y##_s; \
- _FP_FRAC_COPY_##wc(R,Y); \
- } \
- R##_c = FP_CLS_NAN; \
- } while (0)
-
-/* Some assembly to speed things up. */
-#define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
- __asm__ ("addcc %r7,%8,%2
- addxcc %r5,%6,%1
- addx %r3,%4,%0" \
- : "=r" ((USItype)(r2)), \
- "=&r" ((USItype)(r1)), \
- "=&r" ((USItype)(r0)) \
- : "%rJ" ((USItype)(x2)), \
- "rI" ((USItype)(y2)), \
- "%rJ" ((USItype)(x1)), \
- "rI" ((USItype)(y1)), \
- "%rJ" ((USItype)(x0)), \
- "rI" ((USItype)(y0)) \
- : "cc")
-
-#define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) \
- __asm__ ("subcc %r7,%8,%2
- subxcc %r5,%6,%1
- subx %r3,%4,%0" \
- : "=r" ((USItype)(r2)), \
- "=&r" ((USItype)(r1)), \
- "=&r" ((USItype)(r0)) \
- : "%rJ" ((USItype)(x2)), \
- "rI" ((USItype)(y2)), \
- "%rJ" ((USItype)(x1)), \
- "rI" ((USItype)(y1)), \
- "%rJ" ((USItype)(x0)), \
- "rI" ((USItype)(y0)) \
- : "cc")
-
-#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
- do { \
- /* We need to fool gcc, as we need to pass more than 10 \
- input/outputs. */ \
- register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \
- __asm__ __volatile__ ("
- addcc %r8,%9,%1
- addxcc %r6,%7,%0
- addxcc %r4,%5,%%g2
- addx %r2,%3,%%g1" \
- : "=&r" ((USItype)(r1)), \
- "=&r" ((USItype)(r0)) \
- : "%rJ" ((USItype)(x3)), \
- "rI" ((USItype)(y3)), \
- "%rJ" ((USItype)(x2)), \
- "rI" ((USItype)(y2)), \
- "%rJ" ((USItype)(x1)), \
- "rI" ((USItype)(y1)), \
- "%rJ" ((USItype)(x0)), \
- "rI" ((USItype)(y0)) \
- : "cc", "g1", "g2"); \
- __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2)); \
- r3 = _t1; r2 = _t2; \
- } while (0)
-
-#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
- do { \
- /* We need to fool gcc, as we need to pass more than 10 \
- input/outputs. */ \
- register USItype _t1 __asm__ ("g1"), _t2 __asm__ ("g2"); \
- __asm__ __volatile__ ("
- subcc %r8,%9,%1
- subxcc %r6,%7,%0
- subxcc %r4,%5,%%g2
- subx %r2,%3,%%g1" \
- : "=&r" ((USItype)(r1)), \
- "=&r" ((USItype)(r0)) \
- : "%rJ" ((USItype)(x3)), \
- "rI" ((USItype)(y3)), \
- "%rJ" ((USItype)(x2)), \
- "rI" ((USItype)(y2)), \
- "%rJ" ((USItype)(x1)), \
- "rI" ((USItype)(y1)), \
- "%rJ" ((USItype)(x0)), \
- "rI" ((USItype)(y0)) \
- : "cc", "g1", "g2"); \
- __asm__ __volatile__ ("" : "=r" (_t1), "=r" (_t2)); \
- r3 = _t1; r2 = _t2; \
- } while (0)
-
-#define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0)
-
-#define __FP_FRAC_DEC_4(x3,x2,x1,x0,y3,y2,y1,y0) __FP_FRAC_SUB_4(x3,x2,x1,x0,x3,x2,x1,x0,y3,y2,y1,y0)
-
-#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \
- __asm__ ("addcc %3,%4,%3
- addxcc %2,%%g0,%2
- addxcc %1,%%g0,%1
- addx %0,%%g0,%0" \
- : "=&r" ((USItype)(x3)), \
- "=&r" ((USItype)(x2)), \
- "=&r" ((USItype)(x1)), \
- "=&r" ((USItype)(x0)) \
- : "rI" ((USItype)(i)), \
- "0" ((USItype)(x3)), \
- "1" ((USItype)(x2)), \
- "2" ((USItype)(x1)), \
- "3" ((USItype)(x0)) \
- : "cc")
-
-#ifndef __SMP__
-extern struct task_struct *last_task_used_math;
-#endif
-
-/* Obtain the current rounding mode. */
-#ifndef FP_ROUNDMODE
-#ifdef __SMP__
-#define FP_ROUNDMODE ((current->thread.fsr >> 30) & 0x3)
-#else
-#define FP_ROUNDMODE ((last_task_used_math->thread.fsr >> 30) & 0x3)
-#endif
-#endif
-
-/* Exception flags. */
-#define FP_EX_INVALID (1 << 4)
-#define FP_EX_OVERFLOW (1 << 3)
-#define FP_EX_UNDERFLOW (1 << 2)
-#define FP_EX_DIVZERO (1 << 1)
-#define FP_EX_INEXACT (1 << 0)
-
-#define FP_HANDLE_EXCEPTIONS return _fex
-
-#ifdef __SMP__
-#define FP_INHIBIT_RESULTS ((current->thread.fsr >> 23) & _fex)
-#else
-#define FP_INHIBIT_RESULTS ((last_task_used_math->thread.fsr >> 23) & _fex)
-#endif
-
-#endif
diff --git a/arch/sparc/mm/generic.c b/arch/sparc/mm/generic.c
index ea94a8f60..9669f5111 100644
--- a/arch/sparc/mm/generic.c
+++ b/arch/sparc/mm/generic.c
@@ -91,7 +91,9 @@ static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigne
pte_t * pte = pte_alloc(pmd, address);
if (!pte)
return -ENOMEM;
+ spin_lock(&current->mm->page_table_lock);
io_remap_pte_range(pte, address, end - address, address + offset, prot, space);
+ spin_unlock(&current->mm->page_table_lock);
address = (address + PMD_SIZE) & PMD_MASK;
pmd++;
} while (address < end);
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index 86e942597..01fc2e43a 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -37,6 +37,7 @@ define_bool CONFIG_SUN_CONSOLE y
define_bool CONFIG_SUN_AUXIO y
define_bool CONFIG_SUN_IO y
bool 'PCI support' CONFIG_PCI
+source drivers/pci/Config.in
source drivers/sbus/char/Config.in
source drivers/sbus/audio/Config.in
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig
index 59ab0b543..904027e07 100644
--- a/arch/sparc64/defconfig
+++ b/arch/sparc64/defconfig
@@ -60,6 +60,7 @@ CONFIG_SUN_CONSOLE=y
CONFIG_SUN_AUXIO=y
CONFIG_SUN_IO=y
CONFIG_PCI=y
+CONFIG_PCI_NAMES=y
#
# Misc Linux/SPARC drivers
@@ -330,9 +331,6 @@ CONFIG_NCP_FS=m
#
# CONFIG_PARTITION_ADVANCED is not set
CONFIG_MSDOS_PARTITION=y
-# CONFIG_BSD_DISKLABEL is not set
-# CONFIG_SOLARIS_X86_PARTITION is not set
-# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
CONFIG_SUN_PARTITION=y
CONFIG_NLS=y
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index f784e3b9e..f618ab85c 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -726,7 +726,8 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
continue;
case SIGQUIT: case SIGILL: case SIGTRAP:
- case SIGABRT: case SIGFPE: case SIGSEGV: case SIGBUS:
+ case SIGABRT: case SIGFPE: case SIGSEGV:
+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
if (do_coredump(signr, regs))
exit_code |= 0x80;
#ifdef DEBUG_SIGNALS
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index a1e0f26dd..e394ec35b 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -2988,11 +2988,8 @@ qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
if (mod->next == NULL)
return -EINVAL;
- if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
- if (put_user(0, ret))
- return -EFAULT;
- else
- return 0;
+ if (!MOD_CAN_QUERY(mod))
+ return put_user(0, ret);
space = 0;
for (i = 0; i < mod->ndeps; ++i) {
@@ -3008,10 +3005,7 @@ qm_deps(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
space += len;
}
- if (put_user(i, ret))
- return -EFAULT;
- else
- return 0;
+ return put_user(i, ret);
calc_space_needed:
space += len;
@@ -3032,7 +3026,7 @@ qm_refs(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret)
if (mod->next == NULL)
return -EINVAL;
- if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
+ if (!MOD_CAN_QUERY(mod))
if (put_user(0, ret))
return -EFAULT;
else
@@ -3076,7 +3070,7 @@ qm_symbols(struct module *mod, char *buf, size_t bufsize, __kernel_size_t32 *ret
char *strings;
unsigned *vals;
- if ((mod->flags & (MOD_RUNNING | MOD_DELETED)) != MOD_RUNNING)
+ if (!MOD_CAN_QUERY(mod))
if (put_user(0, ret))
return -EFAULT;
else
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S
index fba910a55..6efbe1356 100644
--- a/arch/sparc64/kernel/trampoline.S
+++ b/arch/sparc64/kernel/trampoline.S
@@ -4,8 +4,6 @@
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
*/
-#include <linux/config.h>
-
#include <asm/head.h>
#include <asm/asi.h>
#include <asm/lsu.h>
diff --git a/arch/sparc64/math-emu/math.c b/arch/sparc64/math-emu/math.c
index 38a846c9f..b23bbf1bb 100644
--- a/arch/sparc64/math-emu/math.c
+++ b/arch/sparc64/math-emu/math.c
@@ -16,10 +16,10 @@
#include <asm/uaccess.h>
#include "sfp-util.h"
-#include "soft-fp.h"
-#include "single.h"
-#include "double.h"
-#include "quad.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/single.h>
+#include <math-emu/double.h>
+#include <math-emu/quad.h>
/* QUAD - ftt == 3 */
#define FMOVQ 0x003
diff --git a/arch/sparc64/math-emu/sfp-machine.h b/arch/sparc64/math-emu/sfp-machine.h
deleted file mode 100644
index edb309873..000000000
--- a/arch/sparc64/math-emu/sfp-machine.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Machine-dependent software floating-point definitions.
- Sparc64 kernel version.
- Copyright (C) 1997,1998,1999 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Richard Henderson (rth@cygnus.com),
- Jakub Jelinek (jj@ultra.linux.cz) and
- David S. Miller (davem@redhat.com).
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
- License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
-
- You should have received a copy of the GNU Library General Public
- License along with the GNU C Library; see the file COPYING.LIB. If
- not, write to the Free Software Foundation, Inc.,
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-#ifndef _SFP_MACHINE_H
-#define _SFP_MACHINE_H
-
-#define _FP_W_TYPE_SIZE 64
-#define _FP_W_TYPE unsigned long
-#define _FP_WS_TYPE signed long
-#define _FP_I_TYPE long
-
-#define _FP_MUL_MEAT_S(R,X,Y) \
- _FP_MUL_MEAT_1_imm(_FP_WFRACBITS_S,R,X,Y)
-#define _FP_MUL_MEAT_D(R,X,Y) \
- _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_Q(R,X,Y) \
- _FP_MUL_MEAT_2_wide_3mul(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm)
-
-#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
-#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv(D,R,X,Y)
-#define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv(Q,R,X,Y)
-
-#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
-#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1)
-#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1
-#define _FP_NANSIGN_S 0
-#define _FP_NANSIGN_D 0
-#define _FP_NANSIGN_Q 0
-
-#define _FP_KEEPNANFRACP 1
-
-/* If one NaN is signaling and the other is not,
- * we choose that one, otherwise we choose X.
- */
-/* For _Qp_* and _Q_*, this should prefer X, for
- * CPU instruction emulation this should prefer Y.
- * (see SPAMv9 B.2.2 section).
- */
-#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
- do { \
- if ((_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs) \
- && !(_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs)) \
- { \
- R##_s = X##_s; \
- _FP_FRAC_COPY_##wc(R,X); \
- } \
- else \
- { \
- R##_s = Y##_s; \
- _FP_FRAC_COPY_##wc(R,Y); \
- } \
- R##_c = FP_CLS_NAN; \
- } while (0)
-
-/* Obtain the current rounding mode. */
-#ifndef FP_ROUNDMODE
-#define FP_ROUNDMODE ((current->thread.xfsr[0] >> 30) & 0x3)
-#endif
-
-/* Exception flags. */
-#define FP_EX_INVALID (1 << 4)
-#define FP_EX_OVERFLOW (1 << 3)
-#define FP_EX_UNDERFLOW (1 << 2)
-#define FP_EX_DIVZERO (1 << 1)
-#define FP_EX_INEXACT (1 << 0)
-
-#define FP_HANDLE_EXCEPTIONS return _fex
-
-#define FP_INHIBIT_RESULTS ((current->thread.xfsr[0] >> 23) & _fex)
-
-#endif
diff --git a/arch/sparc64/mm/generic.c b/arch/sparc64/mm/generic.c
index cf94f4250..be999f446 100644
--- a/arch/sparc64/mm/generic.c
+++ b/arch/sparc64/mm/generic.c
@@ -127,7 +127,9 @@ static inline int io_remap_pmd_range(pmd_t * pmd, unsigned long address, unsigne
pte_t * pte = pte_alloc(pmd, address);
if (!pte)
return -ENOMEM;
+ spin_lock(&current->mm->page_table_lock);
io_remap_pte_range(pte, address, end - address, address + offset, prot, space);
+ spin_unlock(&current->mm->page_table_lock);
address = (address + PMD_SIZE) & PMD_MASK;
pmd++;
} while (address < end);
diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S
index 71e05dc7e..638edae1d 100644
--- a/arch/sparc64/mm/ultra.S
+++ b/arch/sparc64/mm/ultra.S
@@ -4,8 +4,6 @@
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
*/
-#include <linux/config.h>
-
#include <asm/asi.h>
#include <asm/pgtable.h>
#include <asm/spitfire.h>