summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-10-05 01:18:40 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-10-05 01:18:40 +0000
commit012bb3e61e5eced6c610f9e036372bf0c8def2d1 (patch)
tree87efc733f9b164e8c85c0336f92c8fb7eff6d183 /arch
parent625a1589d3d6464b5d90b8a0918789e3afffd220 (diff)
Merge with Linux 2.4.0-test9. Please check DECstation, I had a number
of rejects to fixup while integrating Linus patches. I also found that this kernel will only boot SMP on Origin; the UP kernel freeze soon after bootup with SCSI timeout messages. I commit this anyway since I found that the last CVS versions had the same problem.
Diffstat (limited to 'arch')
-rw-r--r--arch/alpha/Makefile8
-rw-r--r--arch/alpha/boot/Makefile2
-rw-r--r--arch/alpha/config.in2
-rw-r--r--arch/alpha/kernel/core_cia.c385
-rw-r--r--arch/alpha/kernel/core_irongate.c49
-rw-r--r--arch/alpha/kernel/entry.S2
-rw-r--r--arch/alpha/kernel/pci_iommu.c2
-rw-r--r--arch/alpha/kernel/process.c5
-rw-r--r--arch/alpha/kernel/signal.c14
-rw-r--r--arch/alpha/kernel/smp.c14
-rw-r--r--arch/alpha/kernel/time.c46
-rw-r--r--arch/alpha/math-emu/Makefile2
-rw-r--r--arch/alpha/math-emu/math.c60
-rw-r--r--arch/alpha/math-emu/qrnnd.S163
-rw-r--r--arch/alpha/math-emu/sfp-util.h17
-rw-r--r--arch/alpha/mm/extable.c2
-rw-r--r--arch/alpha/mm/fault.c2
-rw-r--r--arch/arm/Makefile113
-rw-r--r--arch/arm/boot/Makefile11
-rw-r--r--arch/arm/boot/bootp/Makefile2
-rw-r--r--arch/arm/boot/bootp/bootp.lds39
-rw-r--r--arch/arm/boot/bootp/init.S12
-rw-r--r--arch/arm/boot/compressed/Makefile4
-rw-r--r--arch/arm/boot/compressed/head-ftvpci.S40
-rw-r--r--arch/arm/boot/compressed/head-netwinder.S9
-rw-r--r--arch/arm/boot/compressed/head-nexuspci.S101
-rw-r--r--arch/arm/boot/compressed/head.S29
-rw-r--r--arch/arm/boot/compressed/ll_char_wr.S14
-rw-r--r--arch/arm/boot/compressed/setup-sa1100.S2
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.in9
-rw-r--r--arch/arm/config.in125
-rw-r--r--arch/arm/def-configs/assabet293
-rw-r--r--arch/arm/def-configs/brutus153
-rw-r--r--arch/arm/def-configs/cerf423
-rw-r--r--arch/arm/def-configs/clps7500490
-rw-r--r--arch/arm/def-configs/lart377
-rw-r--r--arch/arm/def-configs/shark655
-rw-r--r--arch/arm/kernel/Makefile25
-rw-r--r--arch/arm/kernel/arch.c423
-rw-r--r--arch/arm/kernel/arch.h74
-rw-r--r--arch/arm/kernel/armksyms.c26
-rw-r--r--arch/arm/kernel/arthur.c10
-rw-r--r--arch/arm/kernel/bios32.c238
-rw-r--r--arch/arm/kernel/bios32.h33
-rw-r--r--arch/arm/kernel/calls.S10
-rw-r--r--arch/arm/kernel/debug-armo.S10
-rw-r--r--arch/arm/kernel/debug-armv.S48
-rw-r--r--arch/arm/kernel/dec21285.c54
-rw-r--r--arch/arm/kernel/dma-arc.c31
-rw-r--r--arch/arm/kernel/dma-footbridge.c17
-rw-r--r--arch/arm/kernel/dma-isa.c82
-rw-r--r--arch/arm/kernel/dma-rpc.c61
-rw-r--r--arch/arm/kernel/dma.c23
-rw-r--r--arch/arm/kernel/dma.h48
-rw-r--r--arch/arm/kernel/ecard.c40
-rw-r--r--arch/arm/kernel/entry-armo.S32
-rw-r--r--arch/arm/kernel/entry-armv.S52
-rw-r--r--arch/arm/kernel/entry-common.S9
-rw-r--r--arch/arm/kernel/ftv-pci.c51
-rw-r--r--arch/arm/kernel/head-armo.S16
-rw-r--r--arch/arm/kernel/head-armv.S62
-rw-r--r--arch/arm/kernel/init_task.c4
-rw-r--r--arch/arm/kernel/irq.c22
-rw-r--r--arch/arm/kernel/isa.c13
-rw-r--r--arch/arm/kernel/leds-ebsa110.c31
-rw-r--r--arch/arm/kernel/leds-ftvpci.c31
-rw-r--r--arch/arm/kernel/oldlatches.c13
-rw-r--r--arch/arm/kernel/plx90x0.c198
-rw-r--r--arch/arm/kernel/process.c31
-rw-r--r--arch/arm/kernel/ptrace.c50
-rw-r--r--arch/arm/kernel/ptrace.h9
-rw-r--r--arch/arm/kernel/semaphore.c12
-rw-r--r--arch/arm/kernel/setup.c12
-rw-r--r--arch/arm/kernel/signal.c7
-rw-r--r--arch/arm/kernel/sys_arm.c25
-rw-r--r--arch/arm/kernel/time-acorn.c18
-rw-r--r--arch/arm/kernel/time.c60
-rw-r--r--arch/arm/kernel/traps.c16
-rw-r--r--arch/arm/kernel/via82c505.c186
-rw-r--r--arch/arm/lib/Makefile7
-rw-r--r--arch/arm/lib/backtrace.S8
-rw-r--r--arch/arm/lib/changebit.S9
-rw-r--r--arch/arm/lib/clearbit.S9
-rw-r--r--arch/arm/lib/copy_page.S29
-rw-r--r--arch/arm/lib/csumipv6.S8
-rw-r--r--arch/arm/lib/csumpartial.S8
-rw-r--r--arch/arm/lib/csumpartialcopy.S8
-rw-r--r--arch/arm/lib/csumpartialcopyuser.S14
-rw-r--r--arch/arm/lib/delay.S9
-rw-r--r--arch/arm/lib/findbit.S9
-rw-r--r--arch/arm/lib/floppydma.S8
-rw-r--r--arch/arm/lib/getconsdata.c8
-rw-r--r--arch/arm/lib/io-acorn.S8
-rw-r--r--arch/arm/lib/io-ebsa110.S8
-rw-r--r--arch/arm/lib/io-shark.c8
-rw-r--r--arch/arm/lib/memchr.S31
-rw-r--r--arch/arm/lib/memcpy.S11
-rw-r--r--arch/arm/lib/memset.S144
-rw-r--r--arch/arm/lib/memzero.S140
-rw-r--r--arch/arm/lib/setbit.S9
-rw-r--r--arch/arm/lib/strchr.S17
-rw-r--r--arch/arm/lib/strncpy_from_user.S43
-rw-r--r--arch/arm/lib/strnlen_user.S40
-rw-r--r--arch/arm/lib/strrchr.S16
-rw-r--r--arch/arm/lib/testchangebit.S9
-rw-r--r--arch/arm/lib/testclearbit.S9
-rw-r--r--arch/arm/lib/testsetbit.S9
-rw-r--r--arch/arm/lib/uaccess-armo.S19
-rw-r--r--arch/arm/lib/uaccess.S80
-rw-r--r--arch/arm/mach-footbridge/Makefile46
-rw-r--r--arch/arm/mach-footbridge/arch.c152
-rw-r--r--arch/arm/mach-footbridge/cats-hw.c65
-rw-r--r--arch/arm/mach-footbridge/cats-pci.c37
-rw-r--r--arch/arm/mach-footbridge/ebsa285-leds.c (renamed from arch/arm/kernel/leds-footbridge.c)129
-rw-r--r--arch/arm/mach-footbridge/ebsa285-pci.c39
-rw-r--r--arch/arm/mach-footbridge/netwinder-hw.c (renamed from arch/arm/kernel/hw-footbridge.c)75
-rw-r--r--arch/arm/mach-footbridge/netwinder-leds.c141
-rw-r--r--arch/arm/mach-footbridge/netwinder-pci.c54
-rw-r--r--arch/arm/mach-footbridge/personal-pci.c43
-rw-r--r--arch/arm/mach-sa1100/Makefile34
-rw-r--r--arch/arm/mach-sa1100/arch.c291
-rw-r--r--arch/arm/mach-sa1100/hw.c (renamed from arch/arm/kernel/hw-sa1100.c)12
-rw-r--r--arch/arm/mach-sa1100/leds.c (renamed from arch/arm/kernel/leds-sa1100.c)24
-rw-r--r--arch/arm/mach-shark/Makefile32
-rw-r--r--arch/arm/mach-shark/arch.c31
-rw-r--r--arch/arm/mach-shark/dma.c25
-rw-r--r--arch/arm/mach-shark/mm.c30
-rw-r--r--arch/arm/mach-shark/pci.c27
-rw-r--r--arch/arm/mm/Makefile65
-rw-r--r--arch/arm/mm/consistent.c28
-rw-r--r--arch/arm/mm/extable.c2
-rw-r--r--arch/arm/mm/fault-armo.c5
-rw-r--r--arch/arm/mm/fault-armv.c11
-rw-r--r--arch/arm/mm/fault-common.c10
-rw-r--r--arch/arm/mm/init.c26
-rw-r--r--arch/arm/mm/ioremap.c2
-rw-r--r--arch/arm/mm/map.h25
-rw-r--r--arch/arm/mm/mm-armo.c19
-rw-r--r--arch/arm/mm/mm-armv.c59
-rw-r--r--arch/arm/mm/mm-clps7500.c23
-rw-r--r--arch/arm/mm/mm-ebsa110.c24
-rw-r--r--arch/arm/mm/mm-footbridge.c112
-rw-r--r--arch/arm/mm/mm-l7200.c19
-rw-r--r--arch/arm/mm/mm-nexuspci.c27
-rw-r--r--arch/arm/mm/mm-rpc.c31
-rw-r--r--arch/arm/mm/mm-sa1100.c212
-rw-r--r--arch/arm/mm/mm-shark.c25
-rw-r--r--arch/arm/mm/mm-tbox.c57
-rw-r--r--arch/arm/mm/proc-arm2,3.S14
-rw-r--r--arch/arm/mm/proc-arm6,7.S149
-rw-r--r--arch/arm/mm/proc-arm720.S160
-rw-r--r--arch/arm/mm/proc-arm920.S602
-rw-r--r--arch/arm/mm/proc-sa110.S1170
-rw-r--r--arch/arm/mm/proc-syms.c31
-rw-r--r--arch/arm/mm/small_page.c28
-rw-r--r--arch/arm/tools/mach-types5
-rw-r--r--arch/arm/vmlinux-armo.lds.in5
-rw-r--r--arch/arm/vmlinux-armv.lds.in4
-rw-r--r--arch/i386/config.in3
-rw-r--r--arch/i386/defconfig93
-rw-r--r--arch/i386/kernel/Makefile2
-rw-r--r--arch/i386/kernel/acpi.c60
-rw-r--r--arch/i386/kernel/apic.c2
-rw-r--r--arch/i386/kernel/bluesmoke.c109
-rw-r--r--arch/i386/kernel/entry.S6
-rw-r--r--arch/i386/kernel/io_apic.c62
-rw-r--r--arch/i386/kernel/microcode.c12
-rw-r--r--arch/i386/kernel/mpparse.c23
-rw-r--r--arch/i386/kernel/mtrr.c61
-rw-r--r--arch/i386/kernel/process.c19
-rw-r--r--arch/i386/kernel/ptrace.c1
-rw-r--r--arch/i386/kernel/setup.c36
-rw-r--r--arch/i386/kernel/signal.c9
-rw-r--r--arch/i386/kernel/smp.c9
-rw-r--r--arch/i386/kernel/smpboot.c26
-rw-r--r--arch/i386/kernel/time.c39
-rw-r--r--arch/i386/kernel/traps.c54
-rw-r--r--arch/i386/kernel/vm86.c4
-rw-r--r--arch/i386/lib/checksum.S12
-rw-r--r--arch/i386/mm/ioremap.c2
-rw-r--r--arch/ia64/config.in1
-rw-r--r--arch/ia64/ia32/ia32_entry.S4
-rw-r--r--arch/ia64/kernel/efi.c31
-rw-r--r--arch/ia64/kernel/entry.S8
-rw-r--r--arch/ia64/kernel/signal.c2
-rw-r--r--arch/m68k/config.in2
-rw-r--r--arch/m68k/kernel/process.c7
-rw-r--r--arch/m68k/kernel/signal.c2
-rw-r--r--arch/m68k/kernel/time.c31
-rw-r--r--arch/m68k/mac/misc.c32
-rw-r--r--arch/mips/baget/vacserial.c2
-rw-r--r--arch/mips/config.in2
-rw-r--r--arch/mips/dec/time.c31
-rw-r--r--arch/mips/defconfig19
-rw-r--r--arch/mips/defconfig-cobalt31
-rw-r--r--arch/mips/defconfig-decstation17
-rw-r--r--arch/mips/defconfig-ip2222
-rw-r--r--arch/mips/defconfig-orion15
-rw-r--r--arch/mips/defconfig-rm20013
-rw-r--r--arch/mips/kernel/gdb-stub.c2
-rw-r--r--arch/mips/kernel/irixelf.c2
-rw-r--r--arch/mips/kernel/irixsig.c25
-rw-r--r--arch/mips/kernel/process.c1
-rw-r--r--arch/mips/kernel/signal.c2
-rw-r--r--arch/mips/kernel/syscall.c4
-rw-r--r--arch/mips/kernel/time.c31
-rw-r--r--arch/mips/orion/initrd.c9
-rw-r--r--arch/mips64/config.in4
-rw-r--r--arch/mips64/defconfig22
-rw-r--r--arch/mips64/defconfig-ip2214
-rw-r--r--arch/mips64/defconfig-ip2722
-rw-r--r--arch/mips64/kernel/ioctl32.c1
-rw-r--r--arch/mips64/kernel/process.c1
-rw-r--r--arch/mips64/kernel/signal.c2
-rw-r--r--arch/mips64/kernel/signal32.c10
-rw-r--r--arch/mips64/kernel/syscall.c4
-rw-r--r--arch/mips64/sgi-ip22/ip22-timer.c31
-rw-r--r--arch/mips64/sgi-ip27/ip27-memory.c2
-rw-r--r--arch/mips64/sgi-ip27/ip27-timer.c32
-rw-r--r--arch/ppc/8260_io/Config.in15
-rw-r--r--arch/ppc/8260_io/Makefile4
-rw-r--r--arch/ppc/8260_io/commproc.c34
-rw-r--r--arch/ppc/8260_io/enet.c21
-rw-r--r--arch/ppc/8260_io/fcc_enet.c1601
-rw-r--r--arch/ppc/8260_io/uart.c23
-rw-r--r--arch/ppc/8xx_io/enet.c11
-rw-r--r--arch/ppc/8xx_io/fec.c9
-rw-r--r--arch/ppc/amiga/time.c36
-rw-r--r--arch/ppc/chrpboot/Makefile6
-rw-r--r--arch/ppc/chrpboot/addnote.c13
-rw-r--r--arch/ppc/coffboot/Makefile2
-rw-r--r--arch/ppc/coffboot/chrpmain.c65
-rw-r--r--arch/ppc/config.in58
-rw-r--r--arch/ppc/configs/common_defconfig207
-rw-r--r--arch/ppc/configs/est8260_defconfig70
-rw-r--r--arch/ppc/configs/gemini_defconfig93
-rw-r--r--arch/ppc/configs/rpxcllf_defconfig68
-rw-r--r--arch/ppc/defconfig210
-rw-r--r--arch/ppc/kernel/Makefile6
-rw-r--r--arch/ppc/kernel/apus_setup.c16
-rw-r--r--arch/ppc/kernel/chrp_pci.c95
-rw-r--r--arch/ppc/kernel/chrp_setup.c144
-rw-r--r--arch/ppc/kernel/chrp_time.c50
-rw-r--r--arch/ppc/kernel/entry.S49
-rw-r--r--arch/ppc/kernel/feature.c175
-rw-r--r--arch/ppc/kernel/gemini_setup.c4
-rw-r--r--arch/ppc/kernel/hashtable.S6
-rw-r--r--arch/ppc/kernel/head.S180
-rw-r--r--arch/ppc/kernel/head_8xx.S45
-rw-r--r--arch/ppc/kernel/idle.c1
-rw-r--r--arch/ppc/kernel/irq.c28
-rw-r--r--arch/ppc/kernel/m8260_setup.c23
-rw-r--r--arch/ppc/kernel/m8xx_setup.c62
-rw-r--r--arch/ppc/kernel/misc.S103
-rw-r--r--arch/ppc/kernel/mol.h68
-rw-r--r--arch/ppc/kernel/oak_setup.c3
-rw-r--r--arch/ppc/kernel/open_pic.c12
-rw-r--r--arch/ppc/kernel/pci.c427
-rw-r--r--arch/ppc/kernel/pmac_backlight.c18
-rw-r--r--arch/ppc/kernel/pmac_nvram.c14
-rw-r--r--arch/ppc/kernel/pmac_pci.c32
-rw-r--r--arch/ppc/kernel/pmac_pic.c9
-rw-r--r--arch/ppc/kernel/pmac_setup.c83
-rw-r--r--arch/ppc/kernel/pmac_time.c65
-rw-r--r--arch/ppc/kernel/ppc-stub.c6
-rw-r--r--arch/ppc/kernel/ppc_ksyms.c44
-rw-r--r--arch/ppc/kernel/prep_setup.c107
-rw-r--r--arch/ppc/kernel/prep_time.c46
-rw-r--r--arch/ppc/kernel/process.c31
-rw-r--r--arch/ppc/kernel/prom.c230
-rw-r--r--arch/ppc/kernel/setup.c14
-rw-r--r--arch/ppc/kernel/signal.c13
-rw-r--r--arch/ppc/kernel/smp.c343
-rw-r--r--arch/ppc/kernel/syscalls.c24
-rw-r--r--arch/ppc/kernel/time.c357
-rw-r--r--arch/ppc/kernel/traps.c144
-rw-r--r--arch/ppc/kernel/walnut_setup.c3
-rw-r--r--arch/ppc/kernel/xics.c2
-rw-r--r--arch/ppc/lib/string.S247
-rw-r--r--arch/ppc/mbxboot/misc.c5
-rw-r--r--arch/ppc/mm/extable.c48
-rw-r--r--arch/ppc/mm/fault.c4
-rw-r--r--arch/ppc/mm/init.c322
-rw-r--r--arch/ppc/xmon/start.c66
-rw-r--r--arch/ppc/xmon/xmon.c180
-rw-r--r--arch/s390/kernel/process.c7
-rw-r--r--arch/s390/kernel/signal.c2
-rw-r--r--arch/s390/kernel/smp.c2
-rw-r--r--arch/sh/boot/compressed/Makefile2
-rw-r--r--arch/sh/config.in2
-rw-r--r--arch/sh/kernel/entry.S236
-rw-r--r--arch/sh/kernel/head.S2
-rw-r--r--arch/sh/kernel/io.c2
-rw-r--r--arch/sh/kernel/irq_imask.c7
-rw-r--r--arch/sh/kernel/irq_ipr.c2
-rw-r--r--arch/sh/kernel/process.c26
-rw-r--r--arch/sh/kernel/setup_cqreek.c64
-rw-r--r--arch/sh/kernel/sh_bios.c12
-rw-r--r--arch/sh/kernel/sh_ksyms.c29
-rw-r--r--arch/sh/kernel/signal.c2
-rw-r--r--arch/sh/kernel/time.c34
-rw-r--r--arch/sh/kernel/traps.c13
-rw-r--r--arch/sh/lib/checksum.S10
-rw-r--r--arch/sh/mm/cache.c124
-rw-r--r--arch/sh/mm/fault.c179
-rw-r--r--arch/sh/mm/init.c3
-rw-r--r--arch/sh/vmlinux.lds.S5
-rw-r--r--arch/sparc/config.in10
-rw-r--r--arch/sparc/kernel/Makefile4
-rw-r--r--arch/sparc/kernel/entry.S5
-rw-r--r--arch/sparc/kernel/irq.c136
-rw-r--r--arch/sparc/kernel/pcic.c11
-rw-r--r--arch/sparc/kernel/process.c4
-rw-r--r--arch/sparc/kernel/setup.c15
-rw-r--r--arch/sparc/kernel/signal.c4
-rw-r--r--arch/sparc/kernel/smp.c45
-rw-r--r--arch/sparc/kernel/solaris.c39
-rw-r--r--arch/sparc/kernel/sparc-stub.c2
-rw-r--r--arch/sparc/kernel/sparc_ksyms.c25
-rw-r--r--arch/sparc/kernel/sun4d_smp.c5
-rw-r--r--arch/sparc/kernel/sun4m_smp.c5
-rw-r--r--arch/sparc/kernel/sunos_ioctl.c4
-rw-r--r--arch/sparc/kernel/sys_solaris.c27
-rw-r--r--arch/sparc/kernel/time.c33
-rw-r--r--arch/sparc/kernel/traps.c40
-rw-r--r--arch/sparc/mm/init.c6
-rw-r--r--arch/sparc/mm/srmmu.c6
-rw-r--r--arch/sparc/mm/sun4c.c6
-rw-r--r--arch/sparc/prom/console.c18
-rw-r--r--arch/sparc/prom/devmap.c10
-rw-r--r--arch/sparc/prom/devops.c14
-rw-r--r--arch/sparc/prom/misc.c20
-rw-r--r--arch/sparc/prom/mp.c18
-rw-r--r--arch/sparc/prom/segment.c6
-rw-r--r--arch/sparc/prom/tree.c30
-rw-r--r--arch/sparc64/boot/piggyback.c6
-rw-r--r--arch/sparc64/config.in10
-rw-r--r--arch/sparc64/kernel/auxio.c3
-rw-r--r--arch/sparc64/kernel/central.c8
-rw-r--r--arch/sparc64/kernel/entry.S8
-rw-r--r--arch/sparc64/kernel/irq.c16
-rw-r--r--arch/sparc64/kernel/pci.c7
-rw-r--r--arch/sparc64/kernel/pci_psycho.c5
-rw-r--r--arch/sparc64/kernel/process.c3
-rw-r--r--arch/sparc64/kernel/sbus.c16
-rw-r--r--arch/sparc64/kernel/setup.c6
-rw-r--r--arch/sparc64/kernel/signal.c4
-rw-r--r--arch/sparc64/kernel/signal32.c4
-rw-r--r--arch/sparc64/kernel/starfire.c36
-rw-r--r--arch/sparc64/kernel/sys_sparc.c32
-rw-r--r--arch/sparc64/kernel/sys_sparc32.c8
-rw-r--r--arch/sparc64/kernel/time.c56
-rw-r--r--arch/sparc64/lib/rwlock.S48
-rw-r--r--arch/sparc64/mm/fault.c4
-rw-r--r--arch/sparc64/mm/init.c15
-rw-r--r--arch/sparc64/solaris/fs.c33
-rw-r--r--arch/sparc64/solaris/misc.c19
-rw-r--r--arch/sparc64/solaris/signal.c20
358 files changed, 13747 insertions, 6431 deletions
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile
index 3daa2c73c..44ae94a99 100644
--- a/arch/alpha/Makefile
+++ b/arch/alpha/Makefile
@@ -8,7 +8,7 @@
# Copyright (C) 1994 by Linus Torvalds
#
-NM := nm -B
+NM := $(NM) -B
LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N #-relax
CFLAGS := $(CFLAGS) -pipe -mno-fp-regs -ffixed-8
@@ -23,6 +23,8 @@ have_mcpu_pca56 := $(shell if $(CC) -mcpu=pca56 -S -o /dev/null -xc /dev/null >
have_mcpu_ev6 := $(shell if $(CC) -mcpu=ev6 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
+have_mcpu_ev67 := $(shell if $(CC) -mcpu=ev67 -S -o /dev/null -xc /dev/null > /dev/null 2>&1; then echo y; else echo n; fi)
+
# Turn on the proper cpu optimizations.
ifeq ($(have_mcpu),y)
# If GENERIC, make sure to turn off any instruction set extensions that
@@ -117,6 +119,10 @@ archmrproper:
archdep:
@$(MAKEBOOT) dep
+
+vmlinux: arch/alpha/vmlinux.lds
+
+arch/alpha/vmlinux.lds: arch/alpha/vmlinux.lds.in
$(CPP) $(CPPFLAGS) -xc -P arch/alpha/vmlinux.lds.in -o arch/alpha/vmlinux.lds
bootpfile:
diff --git a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile
index 47a472524..23789a91c 100644
--- a/arch/alpha/boot/Makefile
+++ b/arch/alpha/boot/Makefile
@@ -68,7 +68,7 @@ vmlinux.nh: $(VMLINUX) $(OBJSTRIP)
$(OBJSTRIP) -v $(VMLINUX) vmlinux.nh
vmlinux: $(TOPDIR)/vmlinux
- strip -o vmlinux $(VMLINUX)
+ $(STRIP) -o vmlinux $(VMLINUX)
tools/lxboot: $(OBJSTRIP) bootloader
$(OBJSTRIP) -p bootloader tools/lxboot
diff --git a/arch/alpha/config.in b/arch/alpha/config.in
index 6485df4af..3b0126e7d 100644
--- a/arch/alpha/config.in
+++ b/arch/alpha/config.in
@@ -239,6 +239,8 @@ source drivers/pnp/Config.in
source drivers/block/Config.in
+source drivers/md/Config.in
+
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
fi
diff --git a/arch/alpha/kernel/core_cia.c b/arch/alpha/kernel/core_cia.c
index 5aa00254b..c686fd29d 100644
--- a/arch/alpha/kernel/core_cia.c
+++ b/arch/alpha/kernel/core_cia.c
@@ -754,6 +754,364 @@ cia_pci_clr_err(void)
*(vip)CIA_IOC_CIA_ERR; /* re-read to force write. */
}
+static void
+cia_decode_pci_error(struct el_CIA_sysdata_mcheck *cia, const char *msg)
+{
+ static const char * const pci_cmd_desc[16] = {
+ "Interrupt Acknowledge", "Special Cycle", "I/O Read",
+ "I/O Write", "Reserved 0x4", "Reserved 0x5", "Memory Read",
+ "Memory Write", "Reserved 0x8", "Reserved 0x9",
+ "Configuration Read", "Configuration Write",
+ "Memory Read Multiple", "Dual Address Cycle",
+ "Memory Read Line", "Memory Write and Invalidate"
+ };
+
+ if (cia->cia_err & (CIA_ERR_COR_ERR
+ | CIA_ERR_UN_COR_ERR
+ | CIA_ERR_MEM_NEM
+ | CIA_ERR_PA_PTE_INV)) {
+ static const char * const window_desc[6] = {
+ "No window active", "Window 0 hit", "Window 1 hit",
+ "Window 2 hit", "Window 3 hit", "Monster window hit"
+ };
+
+ const char *window;
+ const char *cmd;
+ unsigned long addr, tmp;
+ int lock, dac;
+
+ cmd = pci_cmd_desc[cia->pci_err0 & 0x7];
+ lock = (cia->pci_err0 >> 4) & 1;
+ dac = (cia->pci_err0 >> 5) & 1;
+
+ tmp = (cia->pci_err0 >> 8) & 0x1F;
+ tmp = ffs(tmp);
+ window = window_desc[tmp];
+
+ addr = cia->pci_err1;
+ if (dac) {
+ tmp = *(vip)CIA_IOC_PCI_W_DAC & 0xFFUL;
+ addr |= tmp << 32;
+ }
+
+ printk(KERN_CRIT "CIA machine check: %s\n", msg);
+ printk(KERN_CRIT " DMA command: %s\n", cmd);
+ printk(KERN_CRIT " PCI address: %#010lx\n", addr);
+ printk(KERN_CRIT " %s, Lock: %d, DAC: %d\n",
+ window, lock, dac);
+ } else if (cia->cia_err & (CIA_ERR_PERR
+ | CIA_ERR_PCI_ADDR_PE
+ | CIA_ERR_RCVD_MAS_ABT
+ | CIA_ERR_RCVD_TAR_ABT
+ | CIA_ERR_IOA_TIMEOUT)) {
+ static const char * const master_st_desc[16] = {
+ "Idle", "Drive bus", "Address step cycle",
+ "Address cycle", "Data cycle", "Last read data cycle",
+ "Last write data cycle", "Read stop cycle",
+ "Write stop cycle", "Read turnaround cycle",
+ "Write turnaround cycle", "Reserved 0xB",
+ "Reserved 0xC", "Reserved 0xD", "Reserved 0xE",
+ "Unknown state"
+ };
+ static const char * const target_st_desc[16] = {
+ "Idle", "Busy", "Read data cycle", "Write data cycle",
+ "Read stop cycle", "Write stop cycle",
+ "Read turnaround cycle", "Write turnaround cycle",
+ "Read wait cycle", "Write wait cycle",
+ "Reserved 0xA", "Reserved 0xB", "Reserved 0xC",
+ "Reserved 0xD", "Reserved 0xE", "Unknown state"
+ };
+
+ const char *cmd;
+ const char *master, *target;
+ unsigned long addr, tmp;
+ int dac;
+
+ master = master_st_desc[(cia->pci_err0 >> 16) & 0xF];
+ target = target_st_desc[(cia->pci_err0 >> 20) & 0xF];
+ cmd = pci_cmd_desc[(cia->pci_err0 >> 24) & 0xF];
+ dac = (cia->pci_err0 >> 28) & 1;
+
+ addr = cia->pci_err2;
+ if (dac) {
+ tmp = *(volatile int *)CIA_IOC_PCI_W_DAC & 0xFFUL;
+ addr |= tmp << 32;
+ }
+
+ printk(KERN_CRIT "CIA machine check: %s\n", msg);
+ printk(KERN_CRIT " PCI command: %s\n", cmd);
+ printk(KERN_CRIT " Master state: %s, Target state: %s\n",
+ master, target);
+ printk(KERN_CRIT " PCI address: %#010lx, DAC: %d\n",
+ addr, dac);
+ } else {
+ printk(KERN_CRIT "CIA machine check: %s\n", msg);
+ printk(KERN_CRIT " Unknown PCI error\n");
+ printk(KERN_CRIT " PCI_ERR0 = %#08lx", cia->pci_err0);
+ printk(KERN_CRIT " PCI_ERR1 = %#08lx", cia->pci_err1);
+ printk(KERN_CRIT " PCI_ERR2 = %#08lx", cia->pci_err2);
+ }
+}
+
+static void
+cia_decode_mem_error(struct el_CIA_sysdata_mcheck *cia, const char *msg)
+{
+ unsigned long mem_port_addr;
+ unsigned long mem_port_mask;
+ const char *mem_port_cmd;
+ const char *seq_state;
+ const char *set_select;
+ unsigned long tmp;
+
+ /* If this is a DMA command, also decode the PCI bits. */
+ if ((cia->mem_err1 >> 20) & 1)
+ cia_decode_pci_error(cia, msg);
+ else
+ printk(KERN_CRIT "CIA machine check: %s\n", msg);
+
+ mem_port_addr = cia->mem_err0 & 0xfffffff0;
+ mem_port_addr |= (cia->mem_err1 & 0x83UL) << 32;
+
+ mem_port_mask = (cia->mem_err1 >> 12) & 0xF;
+
+ tmp = (cia->mem_err1 >> 8) & 0xF;
+ tmp |= ((cia->mem_err1 >> 20) & 1) << 4;
+ if ((tmp & 0x1E) == 0x06)
+ mem_port_cmd = "WRITE BLOCK or WRITE BLOCK LOCK";
+ else if ((tmp & 0x1C) == 0x08)
+ mem_port_cmd = "READ MISS or READ MISS MODIFY";
+ else if (tmp == 0x1C)
+ mem_port_cmd = "BC VICTIM";
+ else if ((tmp & 0x1E) == 0x0E)
+ mem_port_cmd = "READ MISS MODIFY";
+ else if ((tmp & 0x1C) == 0x18)
+ mem_port_cmd = "DMA READ or DMA READ MODIFY";
+ else if ((tmp & 0x1E) == 0x12)
+ mem_port_cmd = "DMA WRITE";
+ else
+ mem_port_cmd = "Unknown";
+
+ tmp = (cia->mem_err1 >> 16) & 0xF;
+ switch (tmp) {
+ case 0x0:
+ seq_state = "Idle";
+ break;
+ case 0x1:
+ seq_state = "DMA READ or DMA WRITE";
+ break;
+ case 0x2: case 0x3:
+ seq_state = "READ MISS (or READ MISS MODIFY) with victim";
+ break;
+ case 0x4: case 0x5: case 0x6:
+ seq_state = "READ MISS (or READ MISS MODIFY) with no victim";
+ break;
+ case 0x8: case 0x9: case 0xB:
+ seq_state = "Refresh";
+ break;
+ case 0xC:
+ seq_state = "Idle, waiting for DMA pending read";
+ break;
+ case 0xE: case 0xF:
+ seq_state = "Idle, ras precharge";
+ break;
+ default:
+ seq_state = "Unknown";
+ break;
+ }
+
+ tmp = (cia->mem_err1 >> 24) & 0x1F;
+ switch (tmp) {
+ case 0x00: set_select = "Set 0 selected"; break;
+ case 0x01: set_select = "Set 1 selected"; break;
+ case 0x02: set_select = "Set 2 selected"; break;
+ case 0x03: set_select = "Set 3 selected"; break;
+ case 0x04: set_select = "Set 4 selected"; break;
+ case 0x05: set_select = "Set 5 selected"; break;
+ case 0x06: set_select = "Set 6 selected"; break;
+ case 0x07: set_select = "Set 7 selected"; break;
+ case 0x08: set_select = "Set 8 selected"; break;
+ case 0x09: set_select = "Set 9 selected"; break;
+ case 0x0A: set_select = "Set A selected"; break;
+ case 0x0B: set_select = "Set B selected"; break;
+ case 0x0C: set_select = "Set C selected"; break;
+ case 0x0D: set_select = "Set D selected"; break;
+ case 0x0E: set_select = "Set E selected"; break;
+ case 0x0F: set_select = "Set F selected"; break;
+ case 0x10: set_select = "No set selected"; break;
+ case 0x1F: set_select = "Refresh cycle"; break;
+ default: set_select = "Unknown"; break;
+ }
+
+ printk(KERN_CRIT " Memory port command: %s\n", mem_port_cmd);
+ printk(KERN_CRIT " Memory port address: %#010lx, mask: %#lx\n",
+ mem_port_addr, mem_port_mask);
+ printk(KERN_CRIT " Memory sequencer state: %s\n", seq_state);
+ printk(KERN_CRIT " Memory set: %s\n", set_select);
+}
+
+static void
+cia_decode_ecc_error(struct el_CIA_sysdata_mcheck *cia, const char *msg)
+{
+ long syn;
+ long i;
+ const char *fmt;
+
+ cia_decode_mem_error(cia, msg);
+
+ syn = cia->cia_syn & 0xff;
+ if (syn == (syn & -syn)) {
+ fmt = KERN_CRIT " ECC syndrome %#x -- check bit %d\n";
+ i = ffs(syn) - 1;
+ } else {
+ static unsigned char const data_bit[64] = {
+ 0xCE, 0xCB, 0xD3, 0xD5,
+ 0xD6, 0xD9, 0xDA, 0xDC,
+ 0x23, 0x25, 0x26, 0x29,
+ 0x2A, 0x2C, 0x31, 0x34,
+ 0x0E, 0x0B, 0x13, 0x15,
+ 0x16, 0x19, 0x1A, 0x1C,
+ 0xE3, 0xE5, 0xE6, 0xE9,
+ 0xEA, 0xEC, 0xF1, 0xF4,
+ 0x4F, 0x4A, 0x52, 0x54,
+ 0x57, 0x58, 0x5B, 0x5D,
+ 0xA2, 0xA4, 0xA7, 0xA8,
+ 0xAB, 0xAD, 0xB0, 0xB5,
+ 0x8F, 0x8A, 0x92, 0x94,
+ 0x97, 0x98, 0x9B, 0x9D,
+ 0x62, 0x64, 0x67, 0x68,
+ 0x6B, 0x6D, 0x70, 0x75
+ };
+
+ for (i = 0; i < 64; ++i)
+ if (data_bit[i] == syn)
+ break;
+
+ if (i < 64)
+ fmt = KERN_CRIT " ECC syndrome %#x -- data bit %d\n";
+ else
+ fmt = KERN_CRIT " ECC syndrome %#x -- unknown bit\n";
+ }
+
+ printk (fmt, syn, i);
+}
+
+static void
+cia_decode_parity_error(struct el_CIA_sysdata_mcheck *cia)
+{
+ static const char * const cmd_desc[16] = {
+ "NOP", "LOCK", "FETCH", "FETCH_M", "MEMORY BARRIER",
+ "SET DIRTY", "WRITE BLOCK", "WRITE BLOCK LOCK",
+ "READ MISS0", "READ MISS1", "READ MISS MOD0",
+ "READ MISS MOD1", "BCACHE VICTIM", "Spare",
+ "READ MISS MOD STC0", "READ MISS MOD STC1"
+ };
+
+ unsigned long addr;
+ unsigned long mask;
+ const char *cmd;
+ int par;
+
+ addr = cia->cpu_err0 & 0xfffffff0;
+ addr |= (cia->cpu_err1 & 0x83UL) << 32;
+ cmd = cmd_desc[(cia->cpu_err1 >> 8) & 0xF];
+ mask = (cia->cpu_err1 >> 12) & 0xF;
+ par = (cia->cpu_err1 >> 21) & 1;
+
+ printk(KERN_CRIT "CIA machine check: System bus parity error\n");
+ printk(KERN_CRIT " Command: %s, Parity bit: %d\n", cmd, par);
+ printk(KERN_CRIT " Address: %#010lx, Mask: %#lx\n", addr, mask);
+}
+
+static int
+cia_decode_mchk(unsigned long la_ptr)
+{
+ struct el_common *com;
+ struct el_CIA_sysdata_mcheck *cia;
+ int which;
+
+ com = (void *)la_ptr;
+ cia = (void *)(la_ptr + com->sys_offset);
+
+ if ((cia->cia_err & CIA_ERR_VALID) == 0)
+ return 0;
+
+ which = cia->cia_err & 0xfff;
+ switch (ffs(which) - 1) {
+ case 0: /* CIA_ERR_COR_ERR */
+ cia_decode_ecc_error(cia, "Corrected ECC error");
+ break;
+ case 1: /* CIA_ERR_UN_COR_ERR */
+ cia_decode_ecc_error(cia, "Uncorrected ECC error");
+ break;
+ case 2: /* CIA_ERR_CPU_PE */
+ cia_decode_parity_error(cia);
+ break;
+ case 3: /* CIA_ERR_MEM_NEM */
+ cia_decode_mem_error(cia, "Access to nonexistent memory");
+ break;
+ case 4: /* CIA_ERR_PCI_SERR */
+ cia_decode_pci_error(cia, "PCI bus system error");
+ break;
+ case 5: /* CIA_ERR_PERR */
+ cia_decode_pci_error(cia, "PCI data parity error");
+ break;
+ case 6: /* CIA_ERR_PCI_ADDR_PE */
+ cia_decode_pci_error(cia, "PCI address parity error");
+ break;
+ case 7: /* CIA_ERR_RCVD_MAS_ABT */
+ cia_decode_pci_error(cia, "PCI master abort");
+ break;
+ case 8: /* CIA_ERR_RCVD_TAR_ABT */
+ cia_decode_pci_error(cia, "PCI target abort");
+ break;
+ case 9: /* CIA_ERR_PA_PTE_INV */
+ cia_decode_pci_error(cia, "PCI invalid PTE");
+ break;
+ case 10: /* CIA_ERR_FROM_WRT_ERR */
+ cia_decode_mem_error(cia, "Write to flash ROM attempted");
+ break;
+ case 11: /* CIA_ERR_IOA_TIMEOUT */
+ cia_decode_pci_error(cia, "I/O timeout");
+ break;
+ }
+
+ if (cia->cia_err & CIA_ERR_LOST_CORR_ERR)
+ printk(KERN_CRIT "CIA lost machine check: "
+ "Correctable ECC error\n");
+ if (cia->cia_err & CIA_ERR_LOST_UN_CORR_ERR)
+ printk(KERN_CRIT "CIA lost machine check: "
+ "Uncorrectable ECC error\n");
+ if (cia->cia_err & CIA_ERR_LOST_CPU_PE)
+ printk(KERN_CRIT "CIA lost machine check: "
+ "System bus parity error\n");
+ if (cia->cia_err & CIA_ERR_LOST_MEM_NEM)
+ printk(KERN_CRIT "CIA lost machine check: "
+ "Access to nonexistent memory\n");
+ if (cia->cia_err & CIA_ERR_LOST_PERR)
+ printk(KERN_CRIT "CIA lost machine check: "
+ "PCI data parity error\n");
+ if (cia->cia_err & CIA_ERR_LOST_PCI_ADDR_PE)
+ printk(KERN_CRIT "CIA lost machine check: "
+ "PCI address parity error\n");
+ if (cia->cia_err & CIA_ERR_LOST_RCVD_MAS_ABT)
+ printk(KERN_CRIT "CIA lost machine check: "
+ "PCI master abort\n");
+ if (cia->cia_err & CIA_ERR_LOST_RCVD_TAR_ABT)
+ printk(KERN_CRIT "CIA lost machine check: "
+ "PCI target abort\n");
+ if (cia->cia_err & CIA_ERR_LOST_PA_PTE_INV)
+ printk(KERN_CRIT "CIA lost machine check: "
+ "PCI invalid PTE\n");
+ if (cia->cia_err & CIA_ERR_LOST_FROM_WRT_ERR)
+ printk(KERN_CRIT "CIA lost machine check: "
+ "Write to flash ROM attempted\n");
+ if (cia->cia_err & CIA_ERR_LOST_IOA_TIMEOUT)
+ printk(KERN_CRIT "CIA lost machine check: "
+ "I/O timeout\n");
+
+ return 1;
+}
+
void
cia_machine_check(unsigned long vector, unsigned long la_ptr,
struct pt_regs * regs)
@@ -769,30 +1127,7 @@ cia_machine_check(unsigned long vector, unsigned long la_ptr,
mb();
expected = mcheck_expected(0);
- if (!expected && vector == 0x660) {
- struct el_common *com;
- struct el_common_EV5_uncorrectable_mcheck *ev5;
- struct el_CIA_sysdata_mcheck *cia;
-
- com = (void *)la_ptr;
- ev5 = (void *)(la_ptr + com->proc_offset);
- cia = (void *)(la_ptr + com->sys_offset);
-
- if (com->code == 0x202) {
- printk(KERN_CRIT "CIA PCI machine check: code=%x\n"
- " cpu_err0=%08x cpu_err1=%08x cia_err=%08x\n"
- " cia_stat=%08x err_mask=%08x cia_syn=%08x\n"
- " mem_err0=%08x mem_err1=%08x\n"
- " pci_err0=%08x pci_err1=%08x pci_err2=%08x\n",
- (int) com->code,
- (int) cia->cpu_err0, (int) cia->cpu_err1,
- (int) cia->cia_err, (int) cia->cia_stat,
- (int) cia->err_mask, (int) cia->cia_syn,
- (int) cia->mem_err0, (int) cia->mem_err1,
- (int) cia->pci_err0, (int) cia->pci_err1,
- (int) cia->pci_err2);
- expected = 1;
- }
- }
+ if (!expected && vector == 0x660)
+ expected = cia_decode_mchk(la_ptr);
process_mcheck_info(vector, la_ptr, regs, "CIA", expected);
}
diff --git a/arch/alpha/kernel/core_irongate.c b/arch/alpha/kernel/core_irongate.c
index 453766d2e..030348747 100644
--- a/arch/alpha/kernel/core_irongate.c
+++ b/arch/alpha/kernel/core_irongate.c
@@ -28,12 +28,7 @@
#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.
- */
+#undef DEBUG_IRONGATE /* define to enable verbose Irongate debug */
/*
* BIOS32-style PCI interface:
@@ -200,11 +195,12 @@ struct pci_ops irongate_pci_ops =
write_dword: irongate_write_config_dword
};
-#if 0
+#ifdef DEBUG_IRONGATE
static void
irongate_register_dump(const char *function_name)
{
printk("%s: Irongate registers:\n"
+ "\tFunction 0:\n"
"\tdev_vendor\t0x%08x\n"
"\tstat_cmd\t0x%08x\n"
"\tclass\t\t0x%08x\n"
@@ -249,7 +245,26 @@ irongate_register_dump(const char *function_name)
"\tagpstat\t\t0x%08x\n"
"\tagpcmd\t\t0x%08x\n"
"\tagpva\t\t0x%08x\n"
- "\tagpmode\t\t0x%08x\n",
+ "\tagpmode\t\t0x%08x\n"
+
+ "\n\tFunction 1:\n"
+ "\tdev_vendor:\t0x%08x\n"
+ "\tcmd_status:\t0x%08x\n"
+ "\trevid_etc :\t0x%08x\n"
+ "\thtype_etc :\t0x%08x\n"
+ "\trsrvd0[0] :\t0x%08x\n"
+ "\trsrvd0[1] :\t0x%08x\n"
+ "\tbus_nmbers:\t0x%08x\n"
+ "\tio_baselim:\t0x%08x\n"
+ "\tmem_bselim:\t0x%08x\n"
+ "\tpf_baselib:\t0x%08x\n"
+ "\trsrvd1[0] :\t0x%08x\n"
+ "\trsrvd1[1] :\t0x%08x\n"
+ "\tio_baselim:\t0x%08x\n"
+ "\trsrvd2[0] :\t0x%08x\n"
+ "\trsrvd2[1] :\t0x%08x\n"
+ "\tinterrupt :\t0x%08x\n",
+
function_name,
IRONGATE0->dev_vendor,
IRONGATE0->stat_cmd,
@@ -295,7 +310,23 @@ irongate_register_dump(const char *function_name)
IRONGATE0->agpstat,
IRONGATE0->agpcmd,
IRONGATE0->agpva,
- IRONGATE0->agpmode);
+ IRONGATE0->agpmode,
+ IRONGATE1->dev_vendor,
+ IRONGATE1->stat_cmd,
+ IRONGATE1->class,
+ IRONGATE1->htype,
+ IRONGATE1->rsrvd0[0],
+ IRONGATE1->rsrvd0[1],
+ IRONGATE1->busnos,
+ IRONGATE1->io_baselim_regs,
+ IRONGATE1->mem_baselim,
+ IRONGATE1->pfmem_baselim,
+ IRONGATE1->rsrvd1[0],
+ IRONGATE1->rsrvd1[1],
+ IRONGATE1->io_baselim,
+ IRONGATE1->rsrvd2[0],
+ IRONGATE1->rsrvd2[1],
+ IRONGATE1->interrupt );
}
#else
#define irongate_register_dump(x)
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index 7dda5b566..5035d2ca3 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -833,7 +833,7 @@ sys_call_table:
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 50 */
.quad sys_acct
- .quad osf_sigpending
+ .quad sys_sigpending
.quad alpha_ni_syscall
.quad sys_ioctl
.quad alpha_ni_syscall /* 55 */
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index ccf0cefbb..3b727631a 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -416,7 +416,9 @@ sg_fill(struct scatterlist *leader, struct scatterlist *end,
ptes = &arena->ptes[dma_ofs];
sg = leader;
do {
+#if DEBUG_ALLOC > 0
struct scatterlist *last_sg = sg;
+#endif
size = sg->length;
paddr = virt_to_phys(sg->address);
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c
index 81d85386d..508e278b0 100644
--- a/arch/alpha/kernel/process.c
+++ b/arch/alpha/kernel/process.c
@@ -276,14 +276,14 @@ alpha_clone(unsigned long clone_flags, unsigned long usp,
{
if (!usp)
usp = rdusp();
- return do_fork(clone_flags, usp, (struct pt_regs *) (swstack+1));
+ return do_fork(clone_flags, usp, (struct pt_regs *) (swstack+1), 0);
}
int
alpha_vfork(struct switch_stack * swstack)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(),
- (struct pt_regs *) (swstack+1));
+ (struct pt_regs *) (swstack+1), 0);
}
/*
@@ -299,6 +299,7 @@ alpha_vfork(struct switch_stack * swstack)
int
copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
extern void ret_from_sys_call(void);
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c
index db8cacbc9..73df1e930 100644
--- a/arch/alpha/kernel/signal.c
+++ b/arch/alpha/kernel/signal.c
@@ -170,18 +170,6 @@ sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact,
return ret;
}
-asmlinkage int
-osf_sigpending(old_sigset_t *set)
-{
- sigset_t pending;
-
- spin_lock_irq(&current->sigmask_lock);
- sigandsets(&pending, &current->blocked, &current->signal);
- spin_unlock_irq(&current->sigmask_lock);
-
- return copy_to_user(set, &pending, sizeof(*set));
-}
-
/*
* Atomically swap in the new signal mask, and wait for a signal.
*/
@@ -729,7 +717,7 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw,
default:
lock_kernel();
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* NOTREACHED */
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c
index 4f7a04b3f..dd882dc14 100644
--- a/arch/alpha/kernel/smp.c
+++ b/arch/alpha/kernel/smp.c
@@ -420,7 +420,7 @@ static int __init fork_by_hand(void)
* don't care about the regs settings since
* we'll never reschedule the forked task.
*/
- return do_fork(CLONE_VM|CLONE_PID, 0, &regs);
+ return do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0);
}
/*
@@ -1046,8 +1046,8 @@ debug_spin_lock(spinlock_t * lock, const char *base_file, int line_no)
" blbs %0,2b\n"
" br 1b\n"
".previous"
- : "=r" (tmp), "=m" (__dummy_lock(lock)), "=r" (stuck)
- : "1" (__dummy_lock(lock)), "2" (stuck));
+ : "=r" (tmp), "=m" (lock->lock), "=r" (stuck)
+ : "1" (lock->lock), "2" (stuck) : "memory");
if (stuck < 0) {
printk(KERN_WARNING
@@ -1124,9 +1124,9 @@ void write_lock(rwlock_t * lock)
" blt %1,8b\n"
" br 1b\n"
".previous"
- : "=m" (__dummy_lock(lock)), "=&r" (regx), "=&r" (regy),
+ : "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (regy),
"=&r" (stuck_lock), "=&r" (stuck_reader)
- : "0" (__dummy_lock(lock)), "3" (stuck_lock), "4" (stuck_reader));
+ : "0" (*(volatile int *)lock), "3" (stuck_lock), "4" (stuck_reader) : "memory");
if (stuck_lock < 0) {
printk(KERN_WARNING "write_lock stuck at %p\n", inline_pc);
@@ -1163,8 +1163,8 @@ void read_lock(rwlock_t * lock)
" blbs %1,6b;"
" br 1b\n"
".previous"
- : "=m" (__dummy_lock(lock)), "=&r" (regx), "=&r" (stuck_lock)
- : "0" (__dummy_lock(lock)), "2" (stuck_lock));
+ : "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (stuck_lock)
+ : "0" (*(volatile int *)lock), "2" (stuck_lock) : "memory");
if (stuck_lock < 0) {
printk(KERN_WARNING "read_lock stuck at %p\n", inline_pc);
diff --git a/arch/alpha/kernel/time.c b/arch/alpha/kernel/time.c
index 00120e251..0edf60839 100644
--- a/arch/alpha/kernel/time.c
+++ b/arch/alpha/kernel/time.c
@@ -36,6 +36,7 @@
#include <linux/ioport.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
+#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/io.h>
@@ -135,38 +136,6 @@ void timer_interrupt(int irq, void *dev, struct pt_regs * regs)
write_unlock(&xtime_lock);
}
-/*
- * Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static inline unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
void
common_init_rtc(void)
{
@@ -200,7 +169,7 @@ common_init_rtc(void)
init_rtc_irq();
}
-void
+void __init
time_init(void)
{
unsigned int year, mon, day, hour, min, sec, cc1, cc2, epoch;
@@ -267,17 +236,14 @@ time_init(void)
BCD_TO_BIN(year);
}
- /* PC-like is standard; used for year <= 20 || year >= 100 */
+ /* PC-like is standard; used for year < 20 || year >= 70 */
epoch = 1900;
- if (year > 20 && year < 48)
- /* ARC console, used on some not so old boards */
+ if (year >= 20 && year < 48)
+ /* NT epoch */
epoch = 1980;
else if (year >= 48 && year < 70)
- /* Digital UNIX, used on older boards (eg. AXPpxi33) */
+ /* Digital UNIX epoch */
epoch = 1952;
- else if (year >= 70 && year < 100)
- /* Digital DECstations, very old... */
- epoch = 1928;
printk(KERN_INFO "Using epoch = %d\n", epoch);
diff --git a/arch/alpha/math-emu/Makefile b/arch/alpha/math-emu/Makefile
index b5fc37765..91e5ba660 100644
--- a/arch/alpha/math-emu/Makefile
+++ b/arch/alpha/math-emu/Makefile
@@ -8,7 +8,7 @@
# Note 2! The CFLAGS definition is now in the main makefile...
O_TARGET := math-emu.o
-O_OBJS := math.o
+O_OBJS := math.o qrnnd.o
CFLAGS += -I. -I$(TOPDIR)/include/math-emu -w
ifeq ($(CONFIG_MATHEMU),m)
diff --git a/arch/alpha/math-emu/math.c b/arch/alpha/math-emu/math.c
index ed2efe087..4e28b18cf 100644
--- a/arch/alpha/math-emu/math.c
+++ b/arch/alpha/math-emu/math.c
@@ -84,66 +84,6 @@ void cleanup_module(void)
#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
diff --git a/arch/alpha/math-emu/qrnnd.S b/arch/alpha/math-emu/qrnnd.S
new file mode 100644
index 000000000..d6373ec1b
--- /dev/null
+++ b/arch/alpha/math-emu/qrnnd.S
@@ -0,0 +1,163 @@
+ # Alpha 21064 __udiv_qrnnd
+ # Copyright (C) 1992, 1994, 1995, 2000 Free Software Foundation, Inc.
+
+ # This file is part of GCC.
+
+ # The GNU MP Library 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.
+
+ # In addition to the permissions in the GNU General Public License, the
+ # Free Software Foundation gives you unlimited permission to link the
+ # compiled version of this file with other programs, and to distribute
+ # those programs without any restriction coming from the use of this
+ # file. (The General Public License restrictions do apply in other
+ # respects; for example, they cover modification of the file, and
+ # distribution when not linked into another program.)
+
+ # This file 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 General Public License
+ # along with GCC; see the file COPYING. If not, write to the
+ # Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ # MA 02111-1307, USA.
+
+ .set noreorder
+ .set noat
+
+ .text
+
+ .globl __udiv_qrnnd
+ .ent __udiv_qrnnd
+__udiv_qrnnd:
+ .frame $30,0,$26,0
+ .prologue 0
+
+#define cnt $2
+#define tmp $3
+#define rem_ptr $16
+#define n1 $17
+#define n0 $18
+#define d $19
+#define qb $20
+#define AT $at
+
+ ldiq cnt,16
+ blt d,$largedivisor
+
+$loop1: cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule d,n1,qb
+ subq n1,d,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ subq cnt,1,cnt
+ bgt cnt,$loop1
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+$largedivisor:
+ and n0,1,$4
+
+ srl n0,1,n0
+ sll n1,63,tmp
+ or tmp,n0,n0
+ srl n1,1,n1
+
+ and d,1,$6
+ srl d,1,$5
+ addq $5,$6,$5
+
+$loop2: cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ cmplt n0,0,tmp
+ addq n1,n1,n1
+ bis n1,tmp,n1
+ addq n0,n0,n0
+ cmpule $5,n1,qb
+ subq n1,$5,tmp
+ cmovne qb,tmp,n1
+ bis n0,qb,n0
+ subq cnt,1,cnt
+ bgt cnt,$loop2
+
+ addq n1,n1,n1
+ addq $4,n1,n1
+ bne $6,$Odd
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+$Odd:
+ /* q' in n0. r' in n1 */
+ addq n1,n0,n1
+
+ cmpult n1,n0,tmp # tmp := carry from addq
+ subq n1,d,AT
+ addq n0,tmp,n0
+ cmovne tmp,AT,n1
+
+ cmpult n1,d,tmp
+ addq n0,1,AT
+ cmoveq tmp,AT,n0
+ subq n1,d,AT
+ cmoveq tmp,AT,n1
+
+ stq n1,0(rem_ptr)
+ bis $31,n0,$0
+ ret $31,($26),1
+
+ .end __udiv_qrnnd
diff --git a/arch/alpha/math-emu/sfp-util.h b/arch/alpha/math-emu/sfp-util.h
index 7a6a8cf45..f53707f77 100644
--- a/arch/alpha/math-emu/sfp-util.h
+++ b/arch/alpha/math-emu/sfp-util.h
@@ -17,18 +17,13 @@
: "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; \
+#define udiv_qrnnd(q, r, n1, n0, d) \
+ do { unsigned long __r; \
+ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \
+ (r) = __r; \
} while (0)
+extern unsigned long __udiv_qrnnd (unsigned long *, unsigned long,
+ unsigned long , unsigned long);
#define UDIV_NEEDS_NORMALIZATION 1
diff --git a/arch/alpha/mm/extable.c b/arch/alpha/mm/extable.c
index d3a02fe27..5390bd4ec 100644
--- a/arch/alpha/mm/extable.c
+++ b/arch/alpha/mm/extable.c
@@ -88,7 +88,7 @@ search_exception_table(unsigned long addr, unsigned long exc_gp)
*/
ret = search_exception_table_without_gp(addr);
if (ret) {
- printk(KERN_ALERT, "%s: [%lx] EX_TABLE search fail with"
+ printk(KERN_ALERT "%s: [%lx] EX_TABLE search fail with"
"exc frame GP, success with raw GP\n",
current->comm, addr);
return ret;
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index bf4839b8f..c81a12d18 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -167,7 +167,7 @@ no_context:
if ((fixup = search_exception_table(regs->pc, regs->gp)) != 0) {
unsigned long newpc;
newpc = fixup_exception(dpf_reg, fixup, regs->pc);
-#if 1
+#if 0
printk("%s: Exception at [<%lx>] (%lx) handled successfully\n",
current->comm, regs->pc, newpc);
#endif
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 81b78feb9..c19ccddec 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -10,7 +10,7 @@
# License. See the file "COPYING" in the main directory of this archive
# for more details.
#
-# Copyright (C) 1995-1999 by Russell King
+# Copyright (C) 1995-2000 by Russell King
OBJCOPY := $(CROSS_COMPILE)objcopy -O binary -R .note -R .comment -S
CPP := $(CC) -E
@@ -32,38 +32,30 @@ endif
GZFLAGS = -9
# Ensure this is ld "2.9.4" or later
-NEW_LINKER := $(shell if $(LD) --gc-sections --version >/dev/null 2>&1; then echo y; else echo n; fi)
+NEW_LINKER := $(shell $(LD) --gc-sections --version >/dev/null 2>&1; echo $$?)
-ifneq ($(NEW_LINKER),y)
+ifneq ($(NEW_LINKER),0)
dummy:; @echo '*** ${VERSION}.${PATCHLEVEL} kernels no longer build correctly with old versions of binutils.'
@echo '*** Please upgrade your binutils to 2.9.5.'
@false
endif
# GCC 2.7 uses different options to later compilers; sort out which we have
-NEW_GCC := $(shell if $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; then echo n; else echo y; fi)
+NEW_GCC := $(shell $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; echo $$?)
#
# select flags depending on the compiler
#
-ifeq ($(NEW_GCC),y)
+ifneq ($(NEW_GCC),0)
CFLAGS += -mshort-load-bytes
CFLAGS_PROC_CPU_26 := -mcpu=arm3 -mapcs-26 -Os
CFLAGS_PROC_CPU_32v3 := -march=armv3
CFLAGS_PROC_CPU_32v4 := -march=armv4
-CFLAGS_ARM6 := -mtune=arm6
-CFLAGS_ARM7 := -mtune=arm7
-CFLAGS_ARM720 := -mtune=arm7tdmi
-CFLAGS_SA110 := -mtune=strongarm110
else
CFLAGS += -DNO_TEXT_SECTIONS
CFLAGS_PROC_CPU_26 := -m3
-CFLAGS_PROC_CPU_32v3 :=
-CFLAGS_PROC_CPU_32v4 :=
-CFLAGS_ARM6 := -m6
-CFLAGS_ARM7 := -m6
-CFLAGS_ARM720 := -m6
-CFLAGS_SA110 := -m6
+CFLAGS_PROC_CPU_32v3 := -m6
+CFLAGS_PROC_CPU_32v4 := -m6
endif
#
@@ -86,27 +78,16 @@ ifeq ($(CONFIG_CPU_32),y)
CFLAGS += $(CFLAGS_PROC_CPU_32v3)
AFLAGS += -mapcs-32 -marmv3m
endif
- #
- # Exactly one of the following must be selected
- #
- ifeq ($(CONFIG_CPU_ARM6),y)
- CFLAGS += $(CFLAGS_ARM6)
- else
- ifeq ($(CONFIG_CPU_ARM7),y)
- CFLAGS += $(CFLAGS_ARM7)
- else
- ifeq ($(CONFIG_CPU_ARM720),y)
- CFLAGS += $(CFLAGS_ARM720)
- else
- ifeq ($(CONFIG_CPU_SA110),y)
- CFLAGS += $(CFLAGS_SA110)
- else
- ifeq ($(CONFIG_CPU_SA1100),y)
- CFLAGS += $(CFLAGS_SA110)
- endif
- endif
- endif
- endif
+
+ opt-$(CONFIG_CPU_ARM6) := -mtune=arm6
+ opt-$(CONFIG_CPU_ARM7) := -mtune=arm7
+ opt-$(CONFIG_CPU_ARM720) := -mtune=arm7tdmi
+ opt-$(CONFIG_CPU_ARM920) := -mtune=arm9tdmi
+ opt-$(CONFIG_CPU_SA110) := -mtune=strongarm110
+ opt-$(CONFIG_CPU_SA1100) := -mtune=strongarm110
+
+ ifneq ($(NEW_GCC),0)
+ CFLAGS += $(opt-y)
endif
endif
@@ -116,51 +97,63 @@ export LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS
ifeq ($(CONFIG_ARCH_ARCA5K),y)
MACHINE = arc
-ARCHDIR = arc
endif
ifeq ($(CONFIG_ARCH_RPC),y)
MACHINE = rpc
-ARCHDIR = rpc
endif
ifeq ($(CONFIG_ARCH_EBSA110),y)
MACHINE = ebsa110
-ARCHDIR = ebsa110
endif
ifeq ($(CONFIG_ARCH_CLPS7500),y)
MACHINE = clps7500
-ARCHDIR = cl7500
+INCDIR = cl7500
endif
ifeq ($(CONFIG_FOOTBRIDGE),y)
MACHINE = footbridge
-ARCHDIR = ebsa285
+INCDIR = ebsa285
endif
ifeq ($(CONFIG_ARCH_CO285),y)
TEXTADDR = 0x60008000
+MACHINE = footbridge
+INCDIR = ebsa285
endif
ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
MACHINE = nexuspci
-ARCHDIR = nexuspci
endif
ifeq ($(CONFIG_ARCH_SHARK),y)
MACHINE = shark
-ARCHDIR = shark
endif
ifeq ($(CONFIG_ARCH_SA1100),y)
MACHINE = sa1100
-ARCHDIR = sa1100
endif
ifeq ($(CONFIG_ARCH_L7200),y)
MACHINE = l7200
-ARCHDIR = l7200
+endif
+
+ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
+MACHINE = integrator
+endif
+
+# Only set INCDIR if its not already defined above
+# Grr, ?= doesn't work as all the other assignment operators do. Make bug?
+ifeq ($(origin INCDIR), undefined)
+INCDIR := $(MACHINE)
+endif
+
+# If we have a machine-specific directory, then include it in the build.
+MACHDIR := arch/arm/mach-$(MACHINE)
+ifeq ($(MACHDIR),$(wildcard $(MACHDIR)))
+SUBDIRS += $(MACHDIR)
+CORE_FILES := $(MACHDIR)/$(MACHINE).o $(CORE_FILES)
endif
HEAD := arch/arm/kernel/head-$(PROCESSOR).o \
@@ -193,36 +186,30 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
# to date before starting compilation
$(patsubst %, _dir_%, $(SUBDIRS)) init/main.o init/version.o : \
- constants \
include/asm-arm/mach-types.h
-include/asm-arm/mach-types.h: \
- arch/arm/tools/mach-types \
- arch/arm/tools/gen-mach-types
+$(patsubst %, _dir_%, $(SUBDIRS)) : constants
+
+include/asm-arm/mach-types.h: arch/arm/tools/mach-types \
+ arch/arm/tools/gen-mach-types
@awk -f arch/arm/tools/gen-mach-types arch/arm/tools/mach-types > $@
-constants: $(TOPDIR)/include/asm-arm/proc-fns.h dummy
+constants: dummy
@$(MAKE) -C arch/arm/lib constants.h
symlinks: archsymlinks
archsymlinks:
$(RM) include/asm-arm/arch include/asm-arm/proc
- (cd include/asm-arm; ln -sf arch-$(ARCHDIR) arch; ln -sf proc-$(PROCESSOR) proc)
+ (cd include/asm-arm; ln -sf arch-$(INCDIR) arch; ln -sf proc-$(PROCESSOR) proc)
vmlinux: arch/arm/vmlinux.lds
arch/arm/vmlinux.lds: arch/arm/vmlinux-$(PROCESSOR).lds.in dummy
@sed 's/TEXTADDR/$(TEXTADDR)/' <$< >$@
-arch/arm/kernel: dummy
- $(MAKE) linuxsubdirs SUBDIRS=arch/arm/kernel
-
-arch/arm/mm: dummy
- $(MAKE) linuxsubdirs SUBDIRS=arch/arm/mm
-
-arch/arm/lib: dummy
- $(MAKE) linuxsubdirs SUBDIRS=arch/arm/lib
+arch/arm/kernel arch/arm/mm arch/arm/lib: dummy
+ $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@)
bzImage zImage zinstall Image bootpImage install: vmlinux
@$(MAKEBOOT) $@
@@ -235,7 +222,7 @@ archclean:
$(RM) arch/arm/lib/constants.h arch/arm/vmlinux.lds
$(RM) include/asm-arm/mach-types.h
-archdep: symlinks
+archdep: archsymlinks
@$(MAKEBOOT) dep
# My testing targets (that short circuit a few dependencies)
@@ -252,7 +239,7 @@ CFGS= a5k_config ebsa110_config \
brutus_config victor_config \
empeg_config thinclient_config \
assabet_config lart_config \
- cerf_config
+ cerf_config lusl7200_config
$(CFGS):
@( \
@@ -266,7 +253,3 @@ $(CFGS):
echo "$$CFG does not exist"; \
fi; \
)
-
-l7200_config:
- $(RM) arch/arm/defconfig
- cp arch/arm/def-configs/lusl7200 arch/arm/defconfig
diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
index 2811e80ef..6fbdb5ea1 100644
--- a/arch/arm/boot/Makefile
+++ b/arch/arm/boot/Makefile
@@ -42,6 +42,13 @@ INITRD_PHYS = 0x00800000
INITRD_VIRT = 0xc0800000
endif
+ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
+ZTEXTADDR = 0x00008000
+PARAMS = 0x00000100
+INITRD_PHYS = 0x00800000
+INITRD_VIRT = 0xc0800000
+endif
+
ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
ZTEXTADDR = 0x40200000
ZRELADDR = 0x40008000
@@ -105,10 +112,10 @@ initrd:
@test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1)
install: $(CONFIGURE) Image
- sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
+ sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)"
zinstall: $(CONFIGURE) zImage
- sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
+ sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)"
clean:
$(RM) Image zImage bootpImage
diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile
index c513c8ad3..918e3eb9e 100644
--- a/arch/arm/boot/bootp/Makefile
+++ b/arch/arm/boot/bootp/Makefile
@@ -23,4 +23,4 @@ initrd.o: $(INITRD)
.PHONY: $(INITRD) $(ZSYSTEM)
-clean:; $(RM) bootp bootp.lds
+clean:; $(RM) bootp
diff --git a/arch/arm/boot/bootp/bootp.lds b/arch/arm/boot/bootp/bootp.lds
new file mode 100644
index 000000000..8c4e6895f
--- /dev/null
+++ b/arch/arm/boot/bootp/bootp.lds
@@ -0,0 +1,39 @@
+/*
+ * linux/arch/arm/boot/bootp/bootp.lds
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+ . = 0;
+ _text = .;
+ .text : {
+ _stext = .;
+ _start = .;
+ init.o(.start)
+ kernel_start = .;
+ kernel.o
+ kernel_len = . - kernel_start;
+ . = ALIGN(32);
+ *(.text)
+ initrd_start = .;
+ initrd.o
+ initrd_len = . - initrd_start;
+ . = ALIGN(32);
+ _etext = .;
+ }
+
+ .stab 0 : { *(.stab) }
+ .stabstr 0 : { *(.stabstr) }
+ .stab.excl 0 : { *(.stab.excl) }
+ .stab.exclstr 0 : { *(.stab.exclstr) }
+ .stab.index 0 : { *(.stab.index) }
+ .stab.indexstr 0 : { *(.stab.indexstr) }
+ .comment 0 : { *(.comment) }
+}
diff --git a/arch/arm/boot/bootp/init.S b/arch/arm/boot/bootp/init.S
index c5682212f..2b498b7bb 100644
--- a/arch/arm/boot/bootp/init.S
+++ b/arch/arm/boot/bootp/init.S
@@ -1,6 +1,14 @@
/*
- * Header file for splitting kernel + initrd. Note that we pass
- * r0 through to r3 straight through.
+ * linux/arch/arm/boot/bootp/init.S
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Header file for splitting kernel + initrd. Note that we pass
+ * r0 through to r3 straight through.
*/
.section .start,#alloc,#execinstr
.type _entry, #function
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 2a0108021..46b754ec5 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -24,6 +24,10 @@ ifeq ($(CONFIG_ARCH_NETWINDER),y)
OBJS += head-netwinder.o
endif
+ifeq ($(CONFIG_ARCH_INTEGRATOR),y)
+OBJS += head-netwinder.o
+endif
+
ifeq ($(CONFIG_ARCH_NEXUSPCI),y)
HEAD = head-nexuspci.o
endif
diff --git a/arch/arm/boot/compressed/head-ftvpci.S b/arch/arm/boot/compressed/head-ftvpci.S
new file mode 100644
index 000000000..a8c806ef3
--- /dev/null
+++ b/arch/arm/boot/compressed/head-ftvpci.S
@@ -0,0 +1,40 @@
+/*
+ * linux/arch/arm/boot/compressed/head-ftvpci.S
+ *
+ * Copyright (C) 2000 FutureTV Labs Ltd.
+ *
+ * Special startup code for FTV PCI board.
+ */
+
+ .section ".start", #alloc, #execinstr
+ftv_start:
+ mcr p15, 0, r0, c7, c5, 0 @ flush I cache
+ mrc p15, 0, r0, c1, c0
+ orr r0, r0, #1 << 12
+ mcr p15, 0, r0, c1, c0 @ enable I cache
+ mov r0, #0
+ mcreq p15, 0, r0, c15, c1, 2 @ enable clock switching
+
+ /* check to see if the kernel must be relocated */
+ ldr ip, =ftv_start
+ adr sl, ftv_start
+ teq ip, sl
+ beq 2f @ no need to copy
+
+ /* in the wrong place -> presumably, executing out of ROM */
+ sub ip, ip, sl @ displacement
+ ldr lr, =_start @ destination
+ sub sp, lr, ip @ source
+ ldr fp, =_edata @ end of copied area
+1: ldmia sp!, {r0, r1, r2, r3, r4, r5, r6, r10}
+ stmia lr!, {r0, r1, r2, r3, r4, r5, r6, r10}
+ cmp lr, fp
+ ble 1b
+
+2:
+ mov r8, #0
+ mov r7, #3
+ b 1f
+.ltorg
+1:
+ /* fall back into head.S */
diff --git a/arch/arm/boot/compressed/head-netwinder.S b/arch/arm/boot/compressed/head-netwinder.S
index eca1d773d..5eecdec42 100644
--- a/arch/arm/boot/compressed/head-netwinder.S
+++ b/arch/arm/boot/compressed/head-netwinder.S
@@ -1,3 +1,12 @@
+/*
+ * linux/arch/arm/boot/compressed/head-netwinder.S
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
#define K(a,b,c) ((a) << 24 | (b) << 12 | (c))
.section ".start", #alloc, #execinstr
diff --git a/arch/arm/boot/compressed/head-nexuspci.S b/arch/arm/boot/compressed/head-nexuspci.S
deleted file mode 100644
index 1fd49a95c..000000000
--- a/arch/arm/boot/compressed/head-nexuspci.S
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * linux/arch/arm/boot/compressed/head-nexuspci.S
- *
- * Copyright (C) 1996, 1997, 1998 Philip Blundell
- *
- * NexusPCI is unusual because we don't have a bootloader -- the kernel is
- * run directly out of ROM at the moment. Maybe this will change one day and
- * then this file can go away.
- *
- */
-
- .text
-
-.globl _start
-_start: b reset
- b undefined
- b undefined
- b undefined
- b undefined
- b undefined
- b undefined
- b undefined
- b go_uncompress
-
-reset: mov r2, #0x20000000 @ LED off
- mov r1, #0x1a
- str r1, [r2]
-
- mov r2, #0x10000000 @ SCC init
-
- mov r1, #42
- strb r1, [r2, #8]
-
- mov r1, #48
- strb r1, [r2, #8]
-
- mov r1, #16
- strb r1, [r2, #8]
-
- mov r1, #0x93
- strb r1, [r2, #0]
- mov r1, #0x17
- strb r1, [r2, #0]
-
- mov r1, #0xbb
- strb r1, [r2, #0x4]
-
- mov r1, #0x78
- strb r1, [r2, #0x10]
-
- mov r1, #160
- strb r1, [r2, #0x8]
-
- mov r1, #5
- strb r1, [r2, #0x8]
-
- ldr r2, =_start
- ldr r3, =_edata
- mov r8, r2
- mov r0, #0
-1:
- ldmia r0!, {r4, r5, r6, r7}
- stmia r2!, {r4, r5, r6, r7}
- cmp r2, r3
- ble 1b
-
- ldr r3, =_edata
- ldr r1, =_end
- mov r2, #0
-1:
- strb r2, [r3]
- cmp r3, r1
- beq 2f
- add r3, r3, #1
- b 1b
-2:
- add pc, r8, #0x20
-
-undefined: ldr r4, =undef_msg
-1: ldrb r0, [r4], #1
- movs r0, r0
-2: beq 2b
- bl _ll_write_char
- b 1b
-
-undef_msg: .ascii "Undefined instruction (or other problem)\000"
- .align 4
-
-/*
- * Uncompress the kernel
- */
-go_uncompress:
- mov r0, #0x40000000
- ldr sp, =user_stack
- add sp, sp, #4096
- bl decompress_kernel
-
- mov r2, #0x40000000
- mov r0, #0
- mov r1, #3
- add pc, r2, #0x20 @ call via EXEC entry
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index ef9090f72..21bdb43c0 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -1,7 +1,11 @@
/*
- * linux/arch/arm/boot/compressed/head.S
+ * linux/arch/arm/boot/compressed/head.S
*
- * Copyright (C) 1996-1999 Russell King
+ * Copyright (C) 1996-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/linkage.h>
@@ -85,7 +89,7 @@ start:
.word 0x016f2818 @ Magic numbers to help the loader
.word start
1: mov r7, r1 @ save architecture ID
- mov r8, r0 @ save r0
+ mov r8, #0 @ save r0
#ifdef CONFIG_ANGELBOOT
/*
* Booting from Angel - need to enter SVC mode and disable
@@ -198,9 +202,10 @@ cache_on: ldr r1, proc_sa110_type
1:
sub r3, r4, #16384 @ Page directory size
bic r3, r3, #0xff @ Align the pointer
- bic r3, r3, #0x3f
+ bic r3, r3, #0x3f00
/*
- * Initialise the page tables
+ * Initialise the page tables, turning on the cacheable and bufferable
+ * bits for the RAM area only.
*/
mov r0, r3
mov r8, r0, lsr #18
@@ -217,6 +222,20 @@ cache_on: ldr r1, proc_sa110_type
add r1, r1, #1048576
teq r0, r2
bne 1b
+/*
+ * If ever we are running from Flash, then we surely want the cache
+ * to be enabled also for our execution instance... We map 2MB of it
+ * so there is no map overlap problem for up to 1 MB compressed kernel.
+ * If the execution is in RAM then we would only be duplicating the above.
+ */
+ mov r1, #0x1e
+ orr r1, r1, #3 << 10
+ mov r2, pc, lsr #20
+ orr r1, r1, r2, lsl #20
+ add r0, r3, r2, lsl #2
+ str r1, [r0], #4
+ add r1, r1, #1048576
+ str r1, [r0]
mov r0, #0
mcr p15, 0, r0, c7, c10, 4 @ drain write buffer
diff --git a/arch/arm/boot/compressed/ll_char_wr.S b/arch/arm/boot/compressed/ll_char_wr.S
index 57865f2fd..8e1c8bc34 100644
--- a/arch/arm/boot/compressed/ll_char_wr.S
+++ b/arch/arm/boot/compressed/ll_char_wr.S
@@ -1,12 +1,16 @@
/*
- * linux/arch/arm/lib/ll_char_wr.S
+ * linux/arch/arm/lib/ll_char_wr.S
*
- * Copyright (C) 1995, 1996 Russell King.
+ * Copyright (C) 1995, 1996 Russell King.
*
- * Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
- * 10-04-96 RMK Various cleanups & reduced register usage.
- * 08-04-98 RMK Shifts re-ordered
+ * Speedups & 1bpp code (C) 1996 Philip Blundell & Russell King.
+ *
+ * 10-04-96 RMK Various cleanups & reduced register usage.
+ * 08-04-98 RMK Shifts re-ordered
*/
@ Regs: [] = corruptible
diff --git a/arch/arm/boot/compressed/setup-sa1100.S b/arch/arm/boot/compressed/setup-sa1100.S
index f7657773b..3babde180 100644
--- a/arch/arm/boot/compressed/setup-sa1100.S
+++ b/arch/arm/boot/compressed/setup-sa1100.S
@@ -138,7 +138,7 @@ skip_uart:
@ The machine type is passed in r0
mov r0, r3
#ifdef CONFIG_SA1100_NANOENGINE
- teq r0, #32 @ MACH_TYPE_NANOENGINE
+ teq r0, #MACH_TYPE_NANOENGINE
beq SYMBOL_NAME(bse_setup)
#endif
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in
index f7469c634..86ed5e6e3 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.in
+++ b/arch/arm/boot/compressed/vmlinux.lds.in
@@ -1,3 +1,12 @@
+/*
+ * linux/arch/arm/boot/compressed/vmlinux.lds.in
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
diff --git a/arch/arm/config.in b/arch/arm/config.in
index c45998677..1a79b55b9 100644
--- a/arch/arm/config.in
+++ b/arch/arm/config.in
@@ -15,6 +15,7 @@ bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL
bool 'Prompt for obsolete code/drivers' CONFIG_OBSOLETE
endmenu
+
mainmenu_option next_comment
comment 'Loadable module support'
bool 'Enable loadable module support' CONFIG_MODULES
@@ -24,6 +25,7 @@ if [ "$CONFIG_MODULES" = "y" ]; then
fi
endmenu
+
mainmenu_option next_comment
comment 'System Type'
@@ -33,49 +35,60 @@ choice 'ARM system type' \
Co-EBSA285 CONFIG_ARCH_CO285 \
EBSA-110 CONFIG_ARCH_EBSA110 \
FootBridge CONFIG_ARCH_FOOTBRIDGE \
+ Integrator CONFIG_ARCH_INTEGRATOR \
RiscPC CONFIG_ARCH_RPC \
SA1100-based CONFIG_ARCH_SA1100" RiscPC
# the following are placeholders for when they are fully integrated
-# Cirrus CL-PS7500FE CONFIG_ARCH_CLPS7500 \
# LinkUp-L7200 CONFIG_ARCH_L7200
+mainmenu_option next_comment
+comment 'Archimedes/A5000 Implementations'
if [ "$CONFIG_ARCH_ARCA5K" = "y" ]; then
# These architectures will be combined. However, until this
# is complete... Note that the ARC will take precidence over
# A5K
comment 'Archimedes/A5000 Implementations (select only ONE)'
- bool ' Archimedes support' CONFIG_ARCH_ARC
- bool ' A5000 support' CONFIG_ARCH_A5K
+
+ bool ' Archimedes' CONFIG_ARCH_ARC
+ bool ' A5000' CONFIG_ARCH_A5K
fi
+endmenu
+
+mainmenu_option next_comment
+comment 'Footbridge Implementations'
if [ "$CONFIG_ARCH_FOOTBRIDGE" = "y" ]; then
- comment 'Footbridge Implementations'
- bool ' CATS support' CONFIG_ARCH_CATS
- bool ' Compaq Personal Server support' CONFIG_ARCH_PERSONAL_SERVER
- bool ' EBSA285 (addin mode) support' CONFIG_ARCH_EBSA285_ADDIN
- bool ' EBSA285 (host mode) support' CONFIG_ARCH_EBSA285_HOST
- bool ' NetWinder support' CONFIG_ARCH_NETWINDER
+ bool ' CATS' CONFIG_ARCH_CATS
+ bool ' Compaq Personal Server' CONFIG_ARCH_PERSONAL_SERVER
+ bool ' EBSA285 (addin mode)' CONFIG_ARCH_EBSA285_ADDIN
+ bool ' EBSA285 (host mode)' CONFIG_ARCH_EBSA285_HOST
+ bool ' NetWinder' CONFIG_ARCH_NETWINDER
fi
+endmenu
+
+mainmenu_option next_comment
+comment 'SA11x0 Implementations'
if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
- comment 'SA11x0 Implementations'
- bool ' Include support for Assabet' CONFIG_SA1100_ASSABET
+
+ bool ' Assabet' CONFIG_SA1100_ASSABET
if [ "$CONFIG_SA1100_ASSABET" = "y" ]; then
- bool ' Include support for Neponset' CONFIG_ASSABET_NEPONSET
+ bool ' Include support for Neponset' CONFIG_ASSABET_NEPONSET
fi
- bool ' Include support for Brutus' CONFIG_SA1100_BRUTUS
- bool ' Include support for CerfBoard' CONFIG_SA1100_CERF
- bool ' Include support for Compaq iPAQ H3600 (Bitsy)' CONFIG_SA1100_BITSY
-# bool ' Include support for Empeg' CONFIG_SA1100_EMPEG
-# bool ' Include support for Itsy' CONFIG_SA1100_ITSY
- bool ' Include support for LART' CONFIG_SA1100_LART
-# bool ' Include support for PLEB' CONFIG_SA1100_PLEB
- bool ' Include support for ThinClient' CONFIG_SA1100_THINCLIENT
- bool ' Include support for GraphicsClient' CONFIG_SA1100_GRAPHICSCLIENT
- bool ' Include support for nanoEngine' CONFIG_SA1100_NANOENGINE
- bool ' Include support for Victor' CONFIG_SA1100_VICTOR
-# bool ' Include support for Tifon' CONFIG_SA1100_TIFON
- bool ' Include support for XP860' CONFIG_SA1100_XP860
-
+ bool ' Brutus' CONFIG_SA1100_BRUTUS
+ bool ' CerfBoard' CONFIG_SA1100_CERF
+ bool ' Compaq iPAQ H3600 (Bitsy)' CONFIG_SA1100_BITSY
+# bool ' Empeg' CONFIG_SA1100_EMPEG
+# bool ' Itsy' CONFIG_SA1100_ITSY
+ bool ' LART' CONFIG_SA1100_LART
+# bool ' PLEB' CONFIG_SA1100_PLEB
+ bool ' ThinClient' CONFIG_SA1100_THINCLIENT
+ bool ' GraphicsClient' CONFIG_SA1100_GRAPHICSCLIENT
+ bool ' nanoEngine' CONFIG_SA1100_NANOENGINE
+ bool ' Victor' CONFIG_SA1100_VICTOR
+# bool ' Tifon' CONFIG_SA1100_TIFON
+ bool ' XP860' CONFIG_SA1100_XP860
+
+ # Someday, we'll support this as a general option.
bool ' Load kernel using Angel Debug Monitor' CONFIG_ANGELBOOT
# Determine if SA1111 support is required
@@ -84,6 +97,7 @@ if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
define_bool CONFIG_SA1111 y
fi
fi
+endmenu
# Definitions to make life easier
if [ "$CONFIG_ARCH_ARCA5K" = "y" -o \
@@ -129,12 +143,14 @@ else
define_bool CONFIG_CPU_26 n
fi
+comment 'Processor Type'
+
# Select CPU and optimisation dependent on architecture
if [ "$CONFIG_ARCH_RPC" = "y" ]; then
define_bool CONFIG_CPU_32v3 y
- bool 'Support ARM610' CONFIG_CPU_ARM6
- bool 'Support ARM710' CONFIG_CPU_ARM7
- bool 'Support StrongARM110' CONFIG_CPU_SA110
+ bool 'Support ARM610 processor' CONFIG_CPU_ARM6
+ bool 'Support ARM710 processor' CONFIG_CPU_ARM7
+ bool 'Support StrongARM(R) SA-110 processor' CONFIG_CPU_SA110
fi
if [ "$CONFIG_ARCH_EBSA110" = "y" -o \
"$CONFIG_FOOTBRIDGE" = "y" -o \
@@ -152,11 +168,33 @@ if [ "$CONFIG_ARCH_L7200" = "y" ]; then
define_bool CONFIG_CPU_32v4 y
define_bool CONFIG_CPU_ARM720 y
fi
+if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
+ define_bool CONFIG_CPU_32v4 y
+ bool 'Support ARM720 processor' CONFIG_CPU_ARM720
+ bool 'Support ARM920 processor' CONFIG_CPU_ARM920
+# bool 'Support ARM10 processor' CONFIG_CPU_ARM10
+fi
if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
define_bool CONFIG_CPU_32v4 y
define_bool CONFIG_CPU_SA1100 y
fi
+if [ "$CONFIG_CPU_ARM920" = "y" ]; then
+ bool ' ARM920 CPU idle' CONFIG_CPU_ARM920_CPU_IDLE
+ bool ' ARM920 I-Cache on' CONFIG_CPU_ARM920_I_CACHE_ON
+ bool ' ARM920 D-Cache on' CONFIG_CPU_ARM920_D_CACHE_ON
+ if [ "$CONFIG_CPU_ARM920_D_CACHE_ON" = "y" ] ; then
+ bool ' Force write through caches on ARM920' CONFIG_CPU_ARM920_WRITETHROUGH
+ fi
+fi
+#if [ "$CONFIG_CPU_ARM10" = "y" ]; then
+# bool ' ARM10 I-Cache on' CONFIG_CPU_ARM10_I_CACHE_ON
+# bool ' ARM10 D-Cache on' CONFIG_CPU_ARM10_D_CACHE_ON
+# if [ "$CONFIG_CPU_ARM10_D_CACHE_ON" = "y" ] ; then
+# bool ' Force write through caches on ARM10' CONFIG_CPU_ARM10_FORCE_WRITE_THROUGH
+# fi
+#fi
+
# Select various configuration options depending on the machine type
if [ "$CONFIG_ARCH_SA1100" = "y" ]; then
define_bool CONFIG_DISCONTIGMEM y
@@ -164,12 +202,21 @@ else
define_bool CONFIG_DISCONTIGMEM n
fi
+endmenu
+
+mainmenu_option next_comment
+comment 'General setup'
+
# Now handle the bus types
if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o \
"$CONFIG_FOOTBRIDGE_HOST" = "y" ]; then
define_bool CONFIG_PCI y
else
- define_bool CONFIG_PCI n
+ if [ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
+ bool 'PCI support' CONFIG_PCI
+ else
+ define_bool CONFIG_PCI n
+ fi
fi
if [ "$CONFIG_FOOTBRIDGE_HOST" = "y" -o \
@@ -189,10 +236,7 @@ fi
if [ "$CONFIG_SA1100_ASSABET" = "y" ]; then
define_bool CONFIG_PC_KEYMAP y
fi
-endmenu
-mainmenu_option next_comment
-comment 'General setup'
source drivers/pci/Config.in
bool 'Support hot-pluggable devices' CONFIG_HOTPLUG
if [ "$CONFIG_HOTPLUG" = "y" ]; then
@@ -223,20 +267,23 @@ if [ "$CONFIG_ARCH_EBSA110" = "y" -o \
"$CONFIG_ARCH_SA1100" = "y" -o \
"$CONFIG_ARCH_CLPS7500" = "y" -o \
"$CONFIG_ARCH_PERSONAL_SERVER" = "y" -o \
- "$CONFIG_ARCH_CATS" = "y" ]; then
+ "$CONFIG_ARCH_CATS" = "y" -o \
+ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
string 'Default kernel command string' CONFIG_CMDLINE ""
fi
if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
"$CONFIG_ARCH_EBSA110" = "y" -o \
"$CONFIG_ARCH_EBSA285" = "y" -o \
"$CONFIG_ARCH_CO285" = "y" -o \
- "$CONFIG_ARCH_SA1100" = "y" ]; then
+ "$CONFIG_ARCH_SA1100" = "y" -o \
+ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
bool 'Timer and CPU usage LEDs' CONFIG_LEDS
if [ "$CONFIG_LEDS" = "y" ]; then
if [ "$CONFIG_ARCH_NETWINDER" = "y" -o \
"$CONFIG_ARCH_EBSA285" = "y" -o \
"$CONFIG_ARCH_CO285" = "y" -o \
- "$CONFIG_ARCH_SA1100" = "y" ]; then
+ "$CONFIG_ARCH_SA1100" = "y" -o \
+ "$CONFIG_ARCH_INTEGRATOR" = "y" ]; then
bool ' Timer LED' CONFIG_LEDS_TIMER
bool ' CPU usage LED' CONFIG_LEDS_CPU
fi
@@ -254,6 +301,7 @@ source drivers/parport/Config.in
source drivers/mtd/Config.in
source drivers/pnp/Config.in
source drivers/block/Config.in
+source drivers/md/Config.in
if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
source drivers/acorn/block/Config.in
@@ -322,10 +370,6 @@ if [ "$CONFIG_ARCH_ACORN" = "y" -a \
fi
fi
-#source drivers/misc/Config.in
-
-source drivers/media/Config.in
-
source fs/Config.in
if [ "$CONFIG_VT" = "y" ]; then
@@ -354,7 +398,6 @@ if [ "$CONFIG_ARCH_ACORN" = "y" -o \
fi
source drivers/usb/Config.in
-source drivers/input/Config.in
mainmenu_option next_comment
diff --git a/arch/arm/def-configs/assabet b/arch/arm/def-configs/assabet
index 4f046fae2..7a4cd1778 100644
--- a/arch/arm/def-configs/assabet
+++ b/arch/arm/def-configs/assabet
@@ -2,20 +2,23 @@
# Automatically generated make config: don't edit
#
CONFIG_ARM=y
+# CONFIG_SBUS is not set
CONFIG_UID16=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
#
-# System and Processor Type
+# System Type
#
# CONFIG_ARCH_ARC is not set
# CONFIG_ARCH_A5K is not set
+# CONFIG_ARCH_CO285 is not set
# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_FOOTBRIDGE is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_RPC is not set
CONFIG_ARCH_SA1100=y
@@ -24,25 +27,27 @@ CONFIG_ARCH_SA1100=y
#
CONFIG_SA1100_ASSABET=y
# CONFIG_ASSABET_NEPONSET is not set
-# CONFIG_SA1100_BITSY is not set
# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_BITSY is not set
# CONFIG_SA1100_LART is not set
# CONFIG_SA1100_THINCLIENT is not set
# CONFIG_SA1100_GRAPHICSCLIENT is not set
# CONFIG_SA1100_VICTOR is not set
-CONFIG_DISCONTIGMEM=y
-CONFIG_SA1100_FREQUENCY_SCALE=y
+CONFIG_ANGELBOOT=y
+# CONFIG_SA1100_FREQUENCY_SCALE is not set
# CONFIG_SA1100_VOLTAGE_SCALE is not set
-# CONFIG_ARCH_ACORN is not set
CONFIG_CPU_32=y
# CONFIG_CPU_26 is not set
CONFIG_CPU_32v4=y
CONFIG_CPU_SA1100=y
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_DISCONTIGMEM=y
# CONFIG_PCI is not set
# CONFIG_ISA is not set
# CONFIG_ISA_DMA is not set
-# CONFIG_SBUS is not set
-CONFIG_ALIGNMENT_TRAP=y
#
# Loadable module support
@@ -54,6 +59,15 @@ CONFIG_MODULES=y
#
# General setup
#
+CONFIG_HOTPLUG=y
+
+#
+# PC Card support
+#
+CONFIG_PCMCIA=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_SA1100_PCMCIA=y
+CONFIG_VIRTUAL_BUS=y
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
@@ -64,34 +78,23 @@ CONFIG_KCORE_ELF=y
# CONFIG_BINFMT_AOUT is not set
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
# CONFIG_ARTHUR is not set
-
-#
-# Parallel port support
-#
-# CONFIG_PARPORT is not set
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="keepinitrd"
CONFIG_LEDS=y
CONFIG_LEDS_TIMER=y
CONFIG_LEDS_CPU=y
-CONFIG_HOTPLUG=y
+CONFIG_ALIGNMENT_TRAP=y
#
-# PC Card support
+# Parallel port support
#
-CONFIG_PCMCIA=y
-# CONFIG_PCMCIA_DEBUG is not set
-CONFIG_SA1100_PCMCIA=y
-CONFIG_VIRTUAL_BUS=y
+# CONFIG_PARPORT is not set
#
-# I2O device support
+# Memory Technology Devices (MTD)
#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
+# CONFIG_MTD is not set
#
# Plug and Play configuration
@@ -113,92 +116,14 @@ CONFIG_VIRTUAL_BUS=y
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
-# CONFIG_RAID15_DANGEROUS is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_DEV_FLASH is not set
#
-# Character devices
-#
-CONFIG_VT=y
-# CONFIG_VT_CONSOLE is not set
-CONFIG_SERIAL_SA1100=y
-CONFIG_SERIAL_SA1100_CONSOLE=y
-# CONFIG_SERIAL is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-CONFIG_UNIX98_PTYS=y
-CONFIG_UNIX98_PTY_COUNT=32
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_JOYSTICK is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
-# CONFIG_PCMCIA_SERIAL is not set
-# CONFIG_AGP is not set
-
-#
-# Console drivers
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FB=y
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FB_SA1100=y
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_CFB2=y
-CONFIG_FBCON_CFB4=y
-CONFIG_FBCON_CFB8=y
-CONFIG_FBCON_CFB16=y
-CONFIG_FBCON_FONTWIDTH8_ONLY=y
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
# Networking options
#
# CONFIG_PACKET is not set
@@ -230,9 +155,9 @@ CONFIG_SKB_LARGE=y
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
# CONFIG_LLC is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -245,16 +170,6 @@ CONFIG_SKB_LARGE=y
# CONFIG_NET_SCHED is not set
#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
# Network device support
#
CONFIG_NETDEVICES=y
@@ -329,6 +244,16 @@ CONFIG_PCMCIA_PCNET=y
CONFIG_PCMCIA_NETCARD=y
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
# ATA/IDE/MFM/RLL support
#
CONFIG_IDE=y
@@ -368,6 +293,7 @@ CONFIG_BLK_DEV_IDECS=y
# CONFIG_BLK_DEV_ISAPNP is not set
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
# CONFIG_BLK_DEV_IDE_MODES is not set
#
@@ -376,22 +302,75 @@ CONFIG_BLK_DEV_IDECS=y
# CONFIG_SCSI is not set
#
-# Sound
+# I2O device support
#
-CONFIG_SOUND=y
-CONFIG_SOUND_UDA1341=y
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_OSS is not set
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+# CONFIG_VT_CONSOLE is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+# CONFIG_TOUCHSCREEN_SA1100 is not set
+# CONFIG_TOUCHSCREEN_BITSY is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_DRM_TDFX is not set
+# CONFIG_PCMCIA_SERIAL is not set
+# CONFIG_AGP is not set
#
# File systems
@@ -409,6 +388,7 @@ CONFIG_MSDOS_FS=y
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_RAMFS is not set
# CONFIG_ISO9660_FS is not set
@@ -507,6 +487,51 @@ CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_KOI8_R is not set
#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FB=y
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_SA1100=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+CONFIG_FBCON_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+CONFIG_SOUND_UDA1341=y
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
+
+#
# USB support
#
# CONFIG_USB is not set
@@ -517,6 +542,6 @@ CONFIG_NLS_CODEPAGE_437=y
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_ERRORS=y
CONFIG_DEBUG_USER=y
-CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_INFO is not set
# CONFIG_MAGIC_SYSRQ is not set
# CONFIG_DEBUG_LL is not set
diff --git a/arch/arm/def-configs/brutus b/arch/arm/def-configs/brutus
index 67c4eeafb..34391812a 100644
--- a/arch/arm/def-configs/brutus
+++ b/arch/arm/def-configs/brutus
@@ -2,45 +2,51 @@
# Automatically generated make config: don't edit
#
CONFIG_ARM=y
+# CONFIG_SBUS is not set
CONFIG_UID16=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
#
-# System and processor type
+# System Type
#
# CONFIG_ARCH_ARC is not set
# CONFIG_ARCH_A5K is not set
-# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_CO285 is not set
# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_FOOTBRIDGE is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_RPC is not set
CONFIG_ARCH_SA1100=y
+
+#
+# SA11x0 Implementations
+#
# CONFIG_SA1100_ASSABET is not set
CONFIG_SA1100_BRUTUS=y
-# CONFIG_SA1100_EMPEG is not set
-# CONFIG_SA1100_ITSY is not set
# CONFIG_SA1100_BITSY is not set
# CONFIG_SA1100_LART is not set
-# CONFIG_SA1100_PLEB is not set
# CONFIG_SA1100_THINCLIENT is not set
# CONFIG_SA1100_GRAPHICSCLIENT is not set
# CONFIG_SA1100_VICTOR is not set
-# CONFIG_SA1100_TIFON is not set
-CONFIG_DISCONTIGMEM=y
-# CONFIG_ARCH_ACORN is not set
+CONFIG_ANGELBOOT=y
+# CONFIG_SA1100_FREQUENCY_SCALE is not set
+# CONFIG_SA1100_VOLTAGE_SCALE is not set
CONFIG_CPU_32=y
# CONFIG_CPU_26 is not set
CONFIG_CPU_32v4=y
CONFIG_CPU_SA1100=y
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_DISCONTIGMEM=y
# CONFIG_PCI is not set
# CONFIG_ISA is not set
# CONFIG_ISA_DMA is not set
-# CONFIG_SBUS is not set
-# CONFIG_PCMCIA is not set
-# CONFIG_ALIGNMENT_TRAP is not set
#
# Loadable module support
@@ -52,34 +58,35 @@ CONFIG_MODULES=y
#
# General setup
#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
# CONFIG_NET is not set
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
-# CONFIG_SYSCTL is not set
+CONFIG_SYSCTL=y
CONFIG_NWFPE=y
CONFIG_KCORE_ELF=y
# CONFIG_KCORE_AOUT is not set
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="keepinitrd"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+# CONFIG_ALIGNMENT_TRAP is not set
#
# Parallel port support
#
# CONFIG_PARPORT is not set
-CONFIG_CMDLINE=""
-CONFIG_LEDS=y
-CONFIG_LEDS_TIMER=y
-CONFIG_LEDS_CPU=y
#
-# I2O device support
+# Memory Technology Devices (MTD)
#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
+# CONFIG_MTD is not set
#
# Plug and Play configuration
@@ -100,18 +107,48 @@ CONFIG_LEDS_CPU=y
# CONFIG_BLK_DEV_LVM is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_STRIPED is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
# CONFIG_BLK_DEV_FLASH is not set
#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
# Character devices
#
CONFIG_VT=y
# CONFIG_VT_CONSOLE is not set
CONFIG_SERIAL_SA1100=y
CONFIG_SERIAL_SA1100_CONSOLE=y
+# CONFIG_TOUCHSCREEN_SA1100 is not set
+# CONFIG_TOUCHSCREEN_BITSY is not set
# CONFIG_SERIAL is not set
# CONFIG_SERIAL_EXTENDED is not set
# CONFIG_SERIAL_NONSTANDARD is not set
@@ -139,6 +176,7 @@ CONFIG_UNIX98_PTY_COUNT=32
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
@@ -159,43 +197,6 @@ CONFIG_UNIX98_PTY_COUNT=32
# CONFIG_AGP is not set
#
-# Console drivers
-#
-# CONFIG_VGA_CONSOLE is not set
-CONFIG_FB=y
-
-#
-# Frame-buffer support
-#
-CONFIG_FB=y
-CONFIG_DUMMY_CONSOLE=y
-CONFIG_FB_SA1100=y
-# CONFIG_FB_VIRTUAL is not set
-# CONFIG_FBCON_ADVANCED is not set
-CONFIG_FBCON_CFB2=y
-CONFIG_FBCON_CFB4=y
-CONFIG_FBCON_CFB8=y
-CONFIG_FBCON_FONTWIDTH8_ONLY=y
-CONFIG_FBCON_FONTS=y
-CONFIG_FONT_8x8=y
-# CONFIG_FONT_8x16 is not set
-# CONFIG_FONT_SUN8x16 is not set
-# CONFIG_FONT_PEARL_8x8 is not set
-# CONFIG_FONT_ACORN_8x8 is not set
-
-#
-# ATA/IDE/MFM/RLL support
-#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_HD is not set
-
-#
-# SCSI support
-#
-# CONFIG_SCSI is not set
-
-#
# File systems
#
# CONFIG_QUOTA is not set
@@ -211,6 +212,7 @@ CONFIG_FONT_8x8=y
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_RAMFS is not set
# CONFIG_ISO9660_FS is not set
@@ -244,6 +246,37 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FB=y
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_SA1100=y
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB2=y
+CONFIG_FBCON_CFB4=y
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_FONTWIDTH8_ONLY=y
+CONFIG_FBCON_FONTS=y
+CONFIG_FONT_8x8=y
+# CONFIG_FONT_8x16 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
# USB support
#
# CONFIG_USB is not set
diff --git a/arch/arm/def-configs/cerf b/arch/arm/def-configs/cerf
new file mode 100644
index 000000000..accb50b3f
--- /dev/null
+++ b/arch/arm/def-configs/cerf
@@ -0,0 +1,423 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ARC is not set
+# CONFIG_ARCH_A5K is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_RPC is not set
+CONFIG_ARCH_SA1100=y
+
+#
+# SA11x0 Implementations
+#
+# CONFIG_SA1100_ASSABET is not set
+# CONFIG_SA1100_BRUTUS is not set
+CONFIG_SA1100_CERF=y
+# CONFIG_SA1100_BITSY is not set
+# CONFIG_SA1100_LART is not set
+# CONFIG_SA1100_THINCLIENT is not set
+# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_VICTOR is not set
+# CONFIG_ANGELBOOT is not set
+# CONFIG_SA1100_FREQUENCY_SCALE is not set
+# CONFIG_SA1100_VOLTAGE_SCALE is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+CONFIG_CPU_32v4=y
+CONFIG_CPU_SA1100=y
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_DISCONTIGMEM=y
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+
+#
+# General setup
+#
+CONFIG_HOTPLUG=y
+
+#
+# PC Card support
+#
+CONFIG_PCMCIA=y
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_SA1100_PCMCIA=y
+CONFIG_VIRTUAL_BUS=y
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_NWFPE=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="keepinitrd"
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Parallel port support
+#
+# CONFIG_PARPORT is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_FLASH=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+# CONFIG_PACKET_MMAP 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 is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+CONFIG_CERF_CS8900A=y
+# CONFIG_ARM_AM79C961A 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_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+
+#
+# PCMCIA network device support
+#
+# CONFIG_NET_PCMCIA is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+CONFIG_BLK_DEV_IDECS=y
+# CONFIG_BLK_DEV_IDECD is not set
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+# CONFIG_TOUCHSCREEN_UCB1200 is not set
+# CONFIG_TOUCHSCREEN_BITSY is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=32
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_DRM is not set
+# CONFIG_PCMCIA_SERIAL is not set
+# CONFIG_AGP is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_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_DEVFS_FS is not set
+CONFIG_DEVPTS_FS=y
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_OSS is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+CONFIG_FRAME_POINTER=y
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_DEBUG_LL is not set
diff --git a/arch/arm/def-configs/clps7500 b/arch/arm/def-configs/clps7500
new file mode 100644
index 000000000..fb1864561
--- /dev/null
+++ b/arch/arm/def-configs/clps7500
@@ -0,0 +1,490 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_OBSOLETE=y
+
+#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ARCA5K is not set
+CONFIG_ARCH_CLPS7500=y
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_FTVPCI is not set
+# CONFIG_ARCH_TBOX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+CONFIG_CPU_32v3=y
+CONFIG_CPU_ARM7=y
+# CONFIG_DISCONTIGMEM is not set
+# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_ISA_DMA is not set
+
+#
+# General setup
+#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_SYSCTL is not set
+CONFIG_NWFPE=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="root=/dev/nfs rw"
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+CONFIG_PARPORT_PC_FIFO=y
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+CONFIG_PARPORT_1284=y
+
+#
+# Memory Technology Devices (MTD)
+#
+CONFIG_MTD=y
+# CONFIG_MTD_DOC1000 is not set
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOCPROBE is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PMC551 is not set
+# CONFIG_MTD_MTDRAM is not set
+
+#
+# MTD drivers for mapped chips
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_JEDEC is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_PHYSMAP is not set
+
+#
+# Drivers for chip mappings
+#
+# CONFIG_MTD_MIXMEM is not set
+# CONFIG_MTD_NORA is not set
+# CONFIG_MTD_OCTAGON is not set
+# CONFIG_MTD_PNC2000 is not set
+# CONFIG_MTD_RPXLITE is not set
+# CONFIG_MTD_VMAX is not set
+
+#
+# User modules and translation layers for MTD devices
+#
+# CONFIG_MTD_CHAR is not set
+# CONFIG_MTD_BLOCK is not set
+# CONFIG_FTL is not set
+# CONFIG_NFTL 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_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+# CONFIG_BLK_DEV_LOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_BLK_DEV_FLD7500=y
+
+#
+# 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 is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_BOOTP=y
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+CONFIG_DUMMY=y
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_LANCE is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_NET_PCI is not set
+# CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+CONFIG_PPP=y
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_ASYNC is not set
+# CONFIG_PPP_SYNC_TTY is not set
+# CONFIG_PPP_DEFLATE is not set
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
+CONFIG_SLIP=y
+CONFIG_SLIP_COMPRESSED=y
+# CONFIG_SLIP_SMART is not set
+# CONFIG_SLIP_MODE_SLIP6 is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_ASH is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
+# SCSI support
+#
+# CONFIG_SCSI is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_UNIX98_PTYS=y
+CONFIG_UNIX98_PTY_COUNT=256
+CONFIG_PRINTER=y
+CONFIG_LP_CONSOLE=y
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+CONFIG_I2C=y
+CONFIG_I2C_ALGOBIT=y
+# CONFIG_I2C_PHILIPSPAR is not set
+# CONFIG_I2C_ELV is not set
+# CONFIG_I2C_VELLEMAN is not set
+# CONFIG_I2C_ALGOPCF is not set
+# CONFIG_I2C_CHARDEV is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+CONFIG_CLPS7500_FLASH=y
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_ADFS_FS_RW is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_FAT_FS is not set
+# CONFIG_MSDOS_FS is not set
+# CONFIG_UMSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
+# CONFIG_ISO9660_FS is not set
+# CONFIG_JOLIET is not set
+CONFIG_MINIX_FS=y
+# CONFIG_NTFS_FS is not set
+# CONFIG_NTFS_RW is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_DEVFS_MOUNT is not set
+# CONFIG_DEVFS_DEBUG is not set
+# CONFIG_DEVPTS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_QNX4FS_RW is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_SYSV_FS_WRITE is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UDF_RW is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_UFS_FS_WRITE is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+# CONFIG_NFSD_V3 is not set
+CONFIG_SUNRPC=y
+CONFIG_LOCKD=y
+# CONFIG_SMB_FS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_NCPFS_PACKET_SIGNING is not set
+# CONFIG_NCPFS_IOCTL_LOCKING is not set
+# CONFIG_NCPFS_STRONG is not set
+# CONFIG_NCPFS_NFS_NS is not set
+# CONFIG_NCPFS_OS2_NS is not set
+# CONFIG_NCPFS_SMALLDOS is not set
+# CONFIG_NCPFS_MOUNT_SUBDIR is not set
+# CONFIG_NCPFS_NDS_DOMAINS is not set
+# CONFIG_NCPFS_NLS is not set
+# CONFIG_NCPFS_EXTRAS is not set
+
+#
+# Partition Types
+#
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+# CONFIG_MSDOS_PARTITION is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+# CONFIG_NLS is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FB=y
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FB_ACORN=y
+# CONFIG_CHRONTEL_7003 is not set
+# CONFIG_FB_CYBER2000 is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_FBCON_ADVANCED=y
+# CONFIG_FBCON_MFB is not set
+# CONFIG_FBCON_CFB2 is not set
+# CONFIG_FBCON_CFB4 is not set
+CONFIG_FBCON_CFB8=y
+# CONFIG_FBCON_CFB16 is not set
+# CONFIG_FBCON_CFB24 is not set
+# CONFIG_FBCON_CFB32 is not set
+# CONFIG_FBCON_AFB is not set
+# CONFIG_FBCON_ILBM is not set
+# CONFIG_FBCON_IPLAN2P2 is not set
+# CONFIG_FBCON_IPLAN2P4 is not set
+# CONFIG_FBCON_IPLAN2P8 is not set
+# CONFIG_FBCON_MAC is not set
+# CONFIG_FBCON_VGA_PLANES is not set
+# CONFIG_FBCON_VGA is not set
+# CONFIG_FBCON_HGA is not set
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_FRAME_POINTER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_INFO is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_DEBUG_LL is not set
diff --git a/arch/arm/def-configs/lart b/arch/arm/def-configs/lart
index 2e1cd07b5..4dd0b2eeb 100644
--- a/arch/arm/def-configs/lart
+++ b/arch/arm/def-configs/lart
@@ -2,53 +2,62 @@
# Automatically generated by make menuconfig: don't edit
#
CONFIG_ARM=y
+# CONFIG_SBUS is not set
CONFIG_UID16=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
#
-# System and Processor Type
+# Loadable module support
#
-# CONFIG_ARCH_ARC is not set
-# CONFIG_ARCH_A5K is not set
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+# CONFIG_KMOD is not set
+
+#
+# System Type
+#
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CO285 is not set
# CONFIG_ARCH_EBSA110 is not set
-# CONFIG_FOOTBRIDGE is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
# CONFIG_ARCH_RPC is not set
CONFIG_ARCH_SA1100=y
# CONFIG_SA1100_ASSABET is not set
-# CONFIG_SA1100_BITSY is not set
# CONFIG_SA1100_BRUTUS is not set
+# CONFIG_SA1100_CERF is not set
+# CONFIG_SA1100_BITSY is not set
CONFIG_SA1100_LART=y
# CONFIG_SA1100_THINCLIENT is not set
# CONFIG_SA1100_GRAPHICSCLIENT is not set
+# CONFIG_SA1100_NANOENGINE is not set
# CONFIG_SA1100_VICTOR is not set
-CONFIG_DISCONTIGMEM=y
+# CONFIG_ANGELBOOT is not set
CONFIG_SA1100_FREQUENCY_SCALE=m
CONFIG_SA1100_VOLTAGE_SCALE=y
# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
CONFIG_CPU_32=y
# CONFIG_CPU_26 is not set
CONFIG_CPU_32v4=y
CONFIG_CPU_SA1100=y
+CONFIG_DISCONTIGMEM=y
# CONFIG_PCI is not set
# CONFIG_ISA is not set
# CONFIG_ISA_DMA is not set
-# CONFIG_SBUS is not set
-CONFIG_ALIGNMENT_TRAP=y
-
-#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-# CONFIG_KMOD is not set
#
# General setup
#
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
CONFIG_NET=y
CONFIG_SYSVIPC=y
# CONFIG_BSD_PROCESS_ACCT is not set
@@ -59,26 +68,23 @@ CONFIG_KCORE_ELF=y
CONFIG_BINFMT_AOUT=y
CONFIG_BINFMT_ELF=y
# CONFIG_BINFMT_MISC is not set
+CONFIG_PM=y
# CONFIG_ARTHUR is not set
+CONFIG_CMDLINE="console=ttyS0,9600"
+CONFIG_LEDS=y
+# CONFIG_LEDS_TIMER is not set
+CONFIG_LEDS_CPU=y
+CONFIG_ALIGNMENT_TRAP=y
#
# Parallel port support
#
# CONFIG_PARPORT is not set
-CONFIG_CMDLINE="console=ttyS0,9600"
-CONFIG_LEDS=y
-# CONFIG_LEDS_TIMER is not set
-CONFIG_LEDS_CPU=y
-# CONFIG_HOTPLUG is not set
#
-# I2O device support
+# Memory Technology Devices (MTD)
#
-# CONFIG_I2O is not set
-# CONFIG_I2O_BLOCK is not set
-# CONFIG_I2O_LAN is not set
-# CONFIG_I2O_SCSI is not set
-# CONFIG_I2O_PROC is not set
+# CONFIG_MTD is not set
#
# Plug and Play configuration
@@ -100,66 +106,18 @@ CONFIG_LEDS_CPU=y
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
-# CONFIG_RAID15_DANGEROUS is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
-# CONFIG_BLK_DEV_FLASH is not set
-
-#
-# Character devices
-#
-# CONFIG_VT is not set
-CONFIG_SERIAL_SA1100=y
-CONFIG_SERIAL_SA1100_CONSOLE=y
-# CONFIG_SERIAL is not set
-# CONFIG_SERIAL_EXTENDED is not set
-# CONFIG_SERIAL_NONSTANDARD is not set
-# CONFIG_UNIX98_PTYS is not set
-
-#
-# I2C support
-#
-# CONFIG_I2C is not set
-
-#
-# Mice
-#
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MOUSE is not set
-
-#
-# Joysticks
-#
-# CONFIG_JOYSTICK is not set
-# CONFIG_QIC02_TAPE is not set
-
-#
-# Watchdog Cards
-#
-# CONFIG_WATCHDOG is not set
-# CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
-# CONFIG_DTLK is not set
-# CONFIG_R3964 is not set
-# CONFIG_APPLICOM is not set
-
-#
-# Ftape, the floppy tape device driver
-#
-# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
-# CONFIG_AGP is not set
+CONFIG_BLK_DEV_FLASH=m
#
# Networking options
#
-# CONFIG_PACKET is not set
+CONFIG_PACKET=m
+# CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK is not set
# CONFIG_NETFILTER is not set
# CONFIG_FILTER is not set
@@ -172,17 +130,17 @@ CONFIG_INET=y
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
# CONFIG_IP_ALIAS is not set
+# CONFIG_INET_ECN is not set
# CONFIG_SYN_COOKIES is not set
-# CONFIG_SKB_LARGE is not set
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
# CONFIG_LLC is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -195,16 +153,6 @@ CONFIG_INET=y
# CONFIG_NET_SCHED is not set
#
-# Amateur Radio support
-#
-# CONFIG_HAMRADIO is not set
-
-#
-# IrDA (infrared) support
-#
-# CONFIG_IRDA is not set
-
-#
# Network device support
#
CONFIG_NETDEVICES=y
@@ -221,7 +169,37 @@ CONFIG_NETDEVICES=y
#
# Ethernet (10 or 100Mbit)
#
-# CONFIG_NET_ETHERNET is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A 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_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+CONFIG_CS89x0=m
+# CONFIG_DE4X5 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_NE3210 is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO 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_NET_POCKET is not set
#
# Ethernet (1000 Mbit)
@@ -262,11 +240,49 @@ CONFIG_SLIP_COMPRESSED=y
# CONFIG_WAN is not set
#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
# ATA/IDE/MFM/RLL support
#
-# CONFIG_IDE is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
+CONFIG_IDE=m
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=m
+# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=m
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
+# CONFIG_BLK_DEV_IDECS is not set
+CONFIG_BLK_DEV_IDECD=m
+# CONFIG_BLK_DEV_IDETAPE is not set
+# CONFIG_BLK_DEV_IDEFLOPPY is not set
+# CONFIG_BLK_DEV_IDESCSI is not set
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
+# CONFIG_BLK_DEV_ISAPNP is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
#
# SCSI support
@@ -274,54 +290,71 @@ CONFIG_SLIP_COMPRESSED=y
# CONFIG_SCSI is not set
#
-# Sound
+# I2O device support
#
-CONFIG_SOUND=m
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_EMU10K1 is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_TRIDENT is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-CONFIG_SOUND_OSS=m
-CONFIG_SOUND_TRACEINIT=y
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_ADLIB is not set
-# CONFIG_SOUND_ACI_MIXER is not set
-# CONFIG_SOUND_CS4232 is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_ICH is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_NM256 is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_PAS_JOYSTICK is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_SOFTOSS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_AWE32_SYNTH is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_YMPCI is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_AEDSP16 is not set
-# CONFIG_SOUND_VIDC is not set
-# CONFIG_SOUND_WAVEARTIST is not set
-CONFIG_SOUND_SA1100_SSP=m
+# CONFIG_I2O is not set
+# CONFIG_I2O_BLOCK is not set
+# CONFIG_I2O_LAN is not set
+# CONFIG_I2O_SCSI is not set
+# CONFIG_I2O_PROC is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_SERIAL_SA1100=y
+CONFIG_SERIAL_SA1100_CONSOLE=y
+CONFIG_TOUCHSCREEN_UCB1200=m
+# CONFIG_TOUCHSCREEN_BITSY is not set
+# CONFIG_SERIAL is not set
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+# CONFIG_MOUSE is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
+# CONFIG_NVRAM is not set
+# CONFIG_RTC is not set
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
#
# File systems
@@ -339,6 +372,7 @@ CONFIG_SOUND_SA1100_SSP=m
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_RAMFS is not set
# CONFIG_ISO9660_FS is not set
@@ -367,13 +401,13 @@ CONFIG_EXT2_FS=y
# Network File Systems
#
# CONFIG_CODA_FS is not set
-# CONFIG_NFS_FS is not set
+CONFIG_NFS_FS=m
# CONFIG_NFS_V3 is not set
# CONFIG_ROOT_NFS is not set
# CONFIG_NFSD is not set
# CONFIG_NFSD_V3 is not set
-# CONFIG_SUNRPC is not set
-# CONFIG_LOCKD is not set
+CONFIG_SUNRPC=m
+CONFIG_LOCKD=m
# CONFIG_SMB_FS is not set
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
@@ -395,6 +429,57 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_NLS is not set
#
+# Sound
+#
+CONFIG_SOUND=m
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+CONFIG_SOUND_OSS=m
+CONFIG_SOUND_TRACEINIT=y
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_PAS_JOYSTICK is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SOFTOSS is not set
+# CONFIG_SOUND_SB is not set
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMPCI is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+CONFIG_SOUND_SA1100_SSP=m
+# CONFIG_SOUND_TVMIXER is not set
+
+#
# USB support
#
# CONFIG_USB is not set
@@ -406,5 +491,5 @@ CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_ERRORS=y
CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_INFO is not set
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_LL=y
diff --git a/arch/arm/def-configs/shark b/arch/arm/def-configs/shark
new file mode 100644
index 000000000..5f62da754
--- /dev/null
+++ b/arch/arm/def-configs/shark
@@ -0,0 +1,655 @@
+#
+# Automatically generated make config: don't edit
+#
+CONFIG_ARM=y
+# CONFIG_SBUS is not set
+CONFIG_UID16=y
+
+#
+# Code maturity level options
+#
+CONFIG_EXPERIMENTAL=y
+# CONFIG_OBSOLETE is not set
+
+#
+# Loadable module support
+#
+CONFIG_MODULES=y
+# CONFIG_MODVERSIONS is not set
+CONFIG_KMOD=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_ARCA5K is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_FTVPCI is not set
+# CONFIG_ARCH_TBOX is not set
+CONFIG_ARCH_SHARK=y
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_ACORN is not set
+# CONFIG_FOOTBRIDGE is not set
+# CONFIG_FOOTBRIDGE_HOST is not set
+# CONFIG_FOOTBRIDGE_ADDIN is not set
+CONFIG_CPU_32=y
+# CONFIG_CPU_26 is not set
+CONFIG_CPU_32v4=y
+CONFIG_CPU_SA110=y
+# CONFIG_DISCONTIGMEM is not set
+CONFIG_PCI=y
+CONFIG_ISA=y
+CONFIG_ISA_DMA=y
+CONFIG_PC_KEYB=y
+CONFIG_PC_KEYMAP=y
+
+#
+# General setup
+#
+# CONFIG_PCI_NAMES is not set
+# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+CONFIG_NET=y
+CONFIG_SYSVIPC=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+CONFIG_SYSCTL=y
+CONFIG_NWFPE=y
+CONFIG_KCORE_ELF=y
+# CONFIG_KCORE_AOUT is not set
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_MISC is not set
+# CONFIG_PM is not set
+# CONFIG_ARTHUR is not set
+CONFIG_LEDS=y
+CONFIG_LEDS_TIMER=y
+# CONFIG_LEDS_CPU is not set
+# CONFIG_ALIGNMENT_TRAP is not set
+
+#
+# Parallel port support
+#
+CONFIG_PARPORT=y
+CONFIG_PARPORT_PC=y
+# CONFIG_PARPORT_PC_FIFO is not set
+# CONFIG_PARPORT_PC_SUPERIO is not set
+# CONFIG_PARPORT_AMIGA is not set
+# CONFIG_PARPORT_MFC3 is not set
+# CONFIG_PARPORT_ATARI is not set
+# CONFIG_PARPORT_SUNBPP is not set
+# CONFIG_PARPORT_OTHER is not set
+# CONFIG_PARPORT_1284 is not set
+
+#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
+# Plug and Play configuration
+#
+# CONFIG_PNP is not set
+
+#
+# Block devices
+#
+# CONFIG_BLK_DEV_FD is not set
+# CONFIG_BLK_DEV_XD is not set
+# CONFIG_PARIDE is not set
+# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_DEV_DAC960 is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_MD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+# CONFIG_BLK_DEV_INITRD 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 is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+# CONFIG_IP_PNP is not set
+# CONFIG_IP_ROUTER is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_ALIAS is not set
+# CONFIG_INET_ECN is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_IPV6 is not set
+# CONFIG_KHTTPD is not set
+# CONFIG_ATM is not set
+
+#
+#
+#
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_LLC is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_FASTROUTE is not set
+# CONFIG_NET_HW_FLOWCONTROL is not set
+
+#
+# QoS and/or fair queueing
+#
+# CONFIG_NET_SCHED is not set
+
+#
+# Network device support
+#
+CONFIG_NETDEVICES=y
+
+#
+# ARCnet devices
+#
+# CONFIG_ARCNET is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_NET_SB1000 is not set
+
+#
+# Ethernet (10 or 100Mbit)
+#
+CONFIG_NET_ETHERNET=y
+# CONFIG_ARM_AM79C961A 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_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_NET_ISA is not set
+CONFIG_NET_PCI=y
+# CONFIG_PCNET32 is not set
+# CONFIG_ADAPTEC_STARFIRE is not set
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+CONFIG_CS89x0=y
+# CONFIG_DE4X5 is not set
+# CONFIG_TULIP is not set
+# CONFIG_DGRS is not set
+# CONFIG_DM9102 is not set
+# CONFIG_EEPRO100 is not set
+# CONFIG_LNE390 is not set
+# CONFIG_NE3210 is not set
+# CONFIG_NE2K_PCI is not set
+# CONFIG_RTL8129 is not set
+# CONFIG_8139TOO 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_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_YELLOWFIN is not set
+# CONFIG_ACENIC is not set
+# CONFIG_SK98LIN is not set
+# CONFIG_FDDI is not set
+# CONFIG_HIPPI is not set
+# CONFIG_PLIP is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+
+#
+# Wireless LAN (non-hamradio)
+#
+# CONFIG_NET_RADIO is not set
+
+#
+# Token Ring devices
+#
+# CONFIG_TR is not set
+# CONFIG_NET_FC is not set
+# CONFIG_RCPCI is not set
+# CONFIG_SHAPER is not set
+
+#
+# Wan interfaces
+#
+# CONFIG_WAN is not set
+# CONFIG_ASH is not set
+
+#
+# Amateur Radio support
+#
+# CONFIG_HAMRADIO is not set
+
+#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
+# ATA/IDE/MFM/RLL support
+#
+CONFIG_IDE=y
+
+#
+# IDE, ATA and ATAPI Block devices
+#
+CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
+# CONFIG_BLK_DEV_HD_IDE is not set
+# CONFIG_BLK_DEV_HD is not set
+CONFIG_BLK_DEV_IDEDISK=y
+# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+CONFIG_BLK_DEV_IDECD=y
+# CONFIG_BLK_DEV_IDETAPE is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
+# CONFIG_BLK_DEV_IDESCSI is not set
+
+#
+# IDE chipset support/bugfixes
+#
+# CONFIG_BLK_DEV_CMD640 is not set
+# CONFIG_BLK_DEV_RZ1000 is not set
+# CONFIG_BLK_DEV_IDEPCI is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
+# CONFIG_IDE_CHIPSETS is not set
+# CONFIG_IDEDMA_AUTO is not set
+# CONFIG_DMA_NONPCI is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+
+#
+# SCSI support
+#
+CONFIG_SCSI=m
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=m
+CONFIG_SD_EXTRA_DEVS=40
+CONFIG_CHR_DEV_ST=m
+CONFIG_BLK_DEV_SR=m
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_SR_EXTRA_DEVS=2
+CONFIG_CHR_DEV_SG=m
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+# CONFIG_SCSI_DEBUG_QUEUES is not set
+# CONFIG_SCSI_MULTI_LUN is not set
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+
+#
+# SCSI low-level drivers
+#
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
+# CONFIG_SCSI_7000FASST is not set
+# CONFIG_SCSI_ACARD is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AHA1542 is not set
+# CONFIG_SCSI_AHA1740 is not set
+# CONFIG_SCSI_AIC7XXX is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_AM53C974 is not set
+# CONFIG_SCSI_MEGARAID is not set
+# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_DMX3191D is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_EATA is not set
+# CONFIG_SCSI_EATA_DMA is not set
+# CONFIG_SCSI_EATA_PIO is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GDTH is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_INITIO is not set
+# CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_NCR53C7xx is not set
+# CONFIG_SCSI_NCR53C8XX is not set
+# CONFIG_SCSI_SYM53C8XX is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PCI2000 is not set
+# CONFIG_SCSI_PCI2220I is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_QLOGIC_ISP is not set
+# CONFIG_SCSI_QLOGIC_FC is not set
+# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_DC390T is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_U14_34F is not set
+# CONFIG_SCSI_DEBUG is not set
+
+#
+# IEEE 1394 (FireWire) support
+#
+# CONFIG_IEEE1394 is not set
+
+#
+# I2O device support
+#
+# CONFIG_I2O is not set
+
+#
+# ISDN subsystem
+#
+# CONFIG_ISDN is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_SERIAL=y
+CONFIG_SERIAL_CONSOLE=y
+# CONFIG_SERIAL_EXTENDED is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_UNIX98_PTYS is not set
+CONFIG_PRINTER=m
+# CONFIG_LP_CONSOLE is not set
+# CONFIG_PPDEV is not set
+
+#
+# I2C support
+#
+# CONFIG_I2C is not set
+
+#
+# Mice
+#
+# CONFIG_BUSMOUSE is not set
+CONFIG_MOUSE=y
+CONFIG_PSMOUSE=y
+# CONFIG_82C710_MOUSE is not set
+# CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+CONFIG_JOYSTICK=y
+CONFIG_INPUT_JOYDEV=y
+
+#
+# Game port support
+#
+# CONFIG_INPUT_NS558 is not set
+# CONFIG_INPUT_LIGHTNING is not set
+# CONFIG_INPUT_PCIGAME is not set
+
+#
+# Gameport joysticks
+#
+# CONFIG_INPUT_ANALOG is not set
+# CONFIG_INPUT_A3D is not set
+# CONFIG_INPUT_ADI is not set
+# CONFIG_INPUT_COBRA is not set
+# CONFIG_INPUT_GF2K is not set
+# CONFIG_INPUT_GRIP is not set
+# CONFIG_INPUT_INTERACT is not set
+# CONFIG_INPUT_TMDC is not set
+# CONFIG_INPUT_SIDEWINDER is not set
+
+#
+# Serial port support
+#
+# CONFIG_INPUT_SERPORT is not set
+
+#
+# Serial port joysticks
+#
+# CONFIG_INPUT_WARRIOR is not set
+# CONFIG_INPUT_MAGELLAN is not set
+# CONFIG_INPUT_SPACEORB is not set
+# CONFIG_INPUT_SPACEBALL is not set
+# CONFIG_INPUT_IFORCE_232 is not set
+
+#
+# Parallel port joysticks
+#
+# CONFIG_INPUT_DB9 is not set
+# CONFIG_INPUT_GAMECON is not set
+# CONFIG_INPUT_TURBOGRAFX is not set
+# CONFIG_QIC02_TAPE is not set
+
+#
+# Watchdog Cards
+#
+# CONFIG_WATCHDOG is not set
+# CONFIG_NVRAM is not set
+CONFIG_RTC=y
+
+#
+# Video For Linux
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+# CONFIG_APPLICOM is not set
+
+#
+# Ftape, the floppy tape device driver
+#
+# CONFIG_FTAPE is not set
+# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# File systems
+#
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_BFS_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+# CONFIG_UMSDOS_FS is not set
+CONFIG_VFAT_FS=y
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS_FS_VERBOSE=0
+# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+# CONFIG_MINIX_FS is not set
+# CONFIG_NTFS_FS is not set
+# CONFIG_HPFS_FS is not set
+CONFIG_PROC_FS=y
+# CONFIG_DEVFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_SYSV_FS is not set
+# CONFIG_UDF_FS is not set
+# CONFIG_UFS_FS is not set
+
+#
+# Network File Systems
+#
+# CONFIG_CODA_FS is not set
+CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
+# 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=y
+# CONFIG_ACORN_PARTITION is not set
+# CONFIG_OSF_PARTITION is not set
+# CONFIG_AMIGA_PARTITION is not set
+# CONFIG_ATARI_PARTITION is not set
+# CONFIG_MAC_PARTITION is not set
+CONFIG_MSDOS_PARTITION=y
+# CONFIG_BSD_DISKLABEL is not set
+# CONFIG_SOLARIS_X86_PARTITION is not set
+# CONFIG_UNIXWARE_DISKLABEL is not set
+# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
+# CONFIG_SUN_PARTITION is not set
+CONFIG_NLS=y
+
+#
+# Native Language Support
+#
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+CONFIG_NLS_CODEPAGE_850=y
+# 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_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+CONFIG_NLS_ISO8859_1=y
+# 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_UTF8 is not set
+
+#
+# Console drivers
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_FB=y
+
+#
+# Frame-buffer support
+#
+CONFIG_FB=y
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_FB_RIVA is not set
+# CONFIG_FB_CLGEN is not set
+# CONFIG_FB_PM2 is not set
+CONFIG_FB_CYBER2000=y
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY is not set
+# CONFIG_FB_ATY128 is not set
+# CONFIG_FB_3DFX is not set
+# CONFIG_FB_SIS is not set
+# CONFIG_FB_VIRTUAL is not set
+# CONFIG_FBCON_ADVANCED is not set
+CONFIG_FBCON_CFB8=y
+CONFIG_FBCON_CFB16=y
+CONFIG_FBCON_CFB24=y
+# CONFIG_FBCON_FONTWIDTH8_ONLY is not set
+# CONFIG_FBCON_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+
+#
+# Sound
+#
+CONFIG_SOUND=m
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_ES1370 is not set
+# CONFIG_SOUND_ES1371 is not set
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+CONFIG_SOUND_OSS=m
+# CONFIG_SOUND_TRACEINIT is not set
+# CONFIG_SOUND_DMAP is not set
+# CONFIG_SOUND_AD1816 is not set
+# CONFIG_SOUND_SGALAXY is not set
+# CONFIG_SOUND_ADLIB is not set
+# CONFIG_SOUND_ACI_MIXER is not set
+# CONFIG_SOUND_CS4232 is not set
+# CONFIG_SOUND_SSCAPE is not set
+# CONFIG_SOUND_GUS is not set
+# CONFIG_SOUND_ICH is not set
+# CONFIG_SOUND_VMIDI is not set
+# CONFIG_SOUND_TRIX is not set
+# CONFIG_SOUND_MSS is not set
+# CONFIG_SOUND_MPU401 is not set
+# CONFIG_SOUND_NM256 is not set
+# CONFIG_SOUND_MAD16 is not set
+# CONFIG_SOUND_PAS is not set
+# CONFIG_SOUND_PSS is not set
+# CONFIG_SOUND_SOFTOSS is not set
+CONFIG_SOUND_SB=m
+# CONFIG_SOUND_AWE32_SYNTH is not set
+# CONFIG_SOUND_WAVEFRONT is not set
+# CONFIG_SOUND_MAUI is not set
+# CONFIG_SOUND_YM3812 is not set
+# CONFIG_SOUND_OPL3SA1 is not set
+# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMPCI is not set
+# CONFIG_SOUND_UART6850 is not set
+# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_VIDC is not set
+# CONFIG_SOUND_WAVEARTIST is not set
+
+#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_FRAME_POINTER is not set
+CONFIG_DEBUG_ERRORS=y
+CONFIG_DEBUG_USER=y
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_DEBUG_LL=y
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 9fa2e8e86..ed5115c53 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -15,10 +15,18 @@ AFLAGS_head-armo.o := -DTEXTADDR=$(TEXTADDR) -traditional
O_OBJS_arc = dma-arc.o oldlatches.o
O_OBJS_rpc = dma-rpc.o
-O_OBJS_footbridge = dma-footbridge.o hw-footbridge.o isa.o
-O_OBJS_sa1100 = hw-sa1100.o
+O_OBJS_footbridge = dma-footbridge.o isa.o
O_OBJS_l7200 = fiq.o
+leds-ebsa110 = leds-ebsa110.o
+
+pci-nexuspci = plx90x0.o
+pci-footbridge = dec21285.o
+pci-shark = via82c505.o
+
+pci-$(CONFIG_ARCH_NEXUSPCI) += ftv-pci.o
+
+
O_TARGET := kernel.o
# Object file lists.
@@ -30,21 +38,18 @@ obj-m :=
obj-n :=
obj- :=
-export-objs := armksyms.o dma.o ecard.o hw-footbridge.o \
- hw-sa1100.o leds-$(MACHINE).o oldlatches.o
+export-objs := armksyms.o dma.o ecard.o \
+ $(leds-$(MACHINE)) oldlatches.o \
+ time.o
obj-$(CONFIG_ARCH_ACORN) += ecard.o fiq.o time-acorn.o
obj-$(CONFIG_DEBUG_LL) += debug-$(PROCESSOR).o
obj-$(CONFIG_MODULES) += armksyms.o
-obj-$(CONFIG_LEDS) += leds-$(MACHINE).o
+obj-$(CONFIG_LEDS) += $(leds-$(MACHINE))
obj-$(CONFIG_ARTHUR) += arthur.o
obj-$(CONFIG_ISA_DMA) += dma-isa.o
-ifeq ($(MACHINE),nexuspci)
- obj-$(CONFIG_PCI) += plx9080.o
-else
- obj-$(CONFIG_PCI) += bios32.o dec21285.o
-endif
+obj-$(CONFIG_PCI) += bios32.o $(pci-$(MACHINE)) $(pci-y)
# Files that are both resident and modular; remove from modular.
diff --git a/arch/arm/kernel/arch.c b/arch/arm/kernel/arch.c
index e25331e03..94a71c6e3 100644
--- a/arch/arm/kernel/arch.c
+++ b/arch/arm/kernel/arch.c
@@ -1,10 +1,10 @@
/*
- * linux/arch/arm/kernel/arch.c
+ * linux/arch/arm/kernel/arch.c
*
- * 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.
+ * 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.
*/
#include <linux/config.h>
#include <linux/tty.h>
@@ -12,12 +12,12 @@
#include <linux/pm.h>
#include <linux/init.h>
-#include <asm/dec21285.h>
#include <asm/elf.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
-#include "arch.h"
+#include <asm/mach/arch.h>
+#include <asm/hardware/dec21285.h>
unsigned int vram_size;
@@ -69,6 +69,8 @@ fixup_acorn(struct machine_desc *desc, struct param_struct *params,
}
#ifdef CONFIG_ARCH_RPC
+extern void __init rpc_map_io(void);
+
MACHINE_START(RISCPC, "Acorn-RiscPC")
MAINTAINER("Russell King")
BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
@@ -76,6 +78,7 @@ MACHINE_START(RISCPC, "Acorn-RiscPC")
DISABLE_PARPORT(0)
DISABLE_PARPORT(1)
FIXUP(fixup_acorn)
+ MAPIO(rpc_map_io)
MACHINE_END
#endif
#ifdef CONFIG_ARCH_ARC
@@ -94,379 +97,6 @@ MACHINE_END
#endif
#endif
-#ifdef CONFIG_ARCH_EBSA285
-
-static void __init
-fixup_ebsa285(struct machine_desc *desc, struct param_struct *params,
- char **cmdline, struct meminfo *mi)
-{
- 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;
-}
-
-MACHINE_START(EBSA285, "EBSA285")
- MAINTAINER("Russell King")
- BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
- BOOT_PARAMS(0x00000100)
- VIDEO(0x000a0000, 0x000bffff)
- FIXUP(fixup_ebsa285)
-MACHINE_END
-#endif
-
-#ifdef CONFIG_ARCH_NETWINDER
-/*
- * 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, struct meminfo *mi)
-{
-#ifdef CONFIG_ISAPNP
- extern int isapnp_disable;
-
- /*
- * 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
-
- if (params->u1.s.nr_pages != 0x02000 &&
- params->u1.s.nr_pages != 0x04000 &&
- params->u1.s.nr_pages != 0x08000 &&
- params->u1.s.nr_pages != 0x10000) {
- 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;
- }
-}
-
-MACHINE_START(NETWINDER, "Rebel-NetWinder")
- MAINTAINER("Russell King/Rebel.com")
- BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
- BOOT_PARAMS(0x00000100)
- VIDEO(0x000a0000, 0x000bffff)
- DISABLE_PARPORT(0)
- DISABLE_PARPORT(2)
- FIXUP(fixup_netwinder)
-MACHINE_END
-#endif
-
-#ifdef CONFIG_ARCH_CATS
-/*
- * 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, struct meminfo *mi)
-{
- ORIG_VIDEO_LINES = 25;
- ORIG_VIDEO_POINTS = 16;
- ORIG_Y = 24;
-}
-
-MACHINE_START(CATS, "Chalice-CATS")
- MAINTAINER("Philip Blundell")
- BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
- SOFT_REBOOT
- FIXUP(fixup_cats)
-MACHINE_END
-#endif
-
-#ifdef CONFIG_ARCH_CO285
-
-static void __init
-fixup_coebsa285(struct machine_desc *desc, struct param_struct *params,
- char **cmdline, struct meminfo *mi)
-{
- extern unsigned long boot_memory_end;
- extern char boot_command_line[];
-
- mi->nr_banks = 1;
- mi->bank[0].start = PHYS_OFFSET;
- mi->bank[0].size = boot_memory_end;
- mi->bank[0].node = 0;
-
- *cmdline = boot_command_line;
-}
-
-MACHINE_START(CO285, "co-EBSA285")
- MAINTAINER("Mark van Doesburg")
- BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000)
- FIXUP(fixup_coebsa285)
-MACHINE_END
-#endif
-
-#ifdef CONFIG_ARCH_SA1100
-
-static void victor_power_off(void)
-{
- /* switch off power supply */
- mdelay(2000);
- GPCR = GPIO_GPIO23;
- while (1);
-}
-
-
-static void xp860_power_off(void)
-{
- GPDR |= GPIO_GPIO20;
- GPSR = GPIO_GPIO20;
- mdelay(1000);
- GPCR = GPIO_GPIO20;
- while(1);
-}
-
-
-extern void select_sa1100_io_desc(void);
-#define SET_BANK(__nr,__start,__size) \
- mi->bank[__nr].start = (__start), \
- mi->bank[__nr].size = (__size), \
- mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27)
-static void __init
-fixup_sa1100(struct machine_desc *desc, struct param_struct *params,
- char **cmdline, struct meminfo *mi)
-{
- select_sa1100_io_desc();
-
- if (machine_is_assabet()) {
- /*
- * On Assabet, we must probe for the Neponset board *before*
- * paging_init() has occured to actually determine the amount
- * of RAM available.
- */
- extern void map_sa1100_gpio_regs(void);
- extern void get_assabet_scr(void);
- map_sa1100_gpio_regs();
- get_assabet_scr();
-
- SET_BANK( 0, 0xc0000000, 32*1024*1024 );
- mi->nr_banks = 1;
-
- if (machine_has_neponset()) {
- printk("Neponset expansion board detected\n");
- /*
- * Note that Neponset RAM is slower...
- * and still untested.
- * This would be a candidate for
- * _real_ NUMA support.
- */
- //SET_BANK( 1, 0xd0000000, 32*1024*1024 );
- //mi->nr_banks = 2;
- }
-
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
- setup_ramdisk( 1, 0, 0, 8192 );
- setup_initrd( 0xc0800000, 3*1024*1024 );
- }
-
- else if (machine_is_brutus()) {
- SET_BANK( 0, 0xc0000000, 4*1024*1024 );
- SET_BANK( 1, 0xc8000000, 4*1024*1024 );
- SET_BANK( 2, 0xd0000000, 4*1024*1024 );
- SET_BANK( 3, 0xd8000000, 4*1024*1024 );
- mi->nr_banks = 4;
-
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
- setup_ramdisk( 1, 0, 0, 8192 );
- setup_initrd( __phys_to_virt(0xd8000000), 3*1024*1024 );
- }
-
- else if (machine_is_cerf()) {
- // 16Meg Ram.
- SET_BANK( 0, 0xc0000000, 8*1024*1024 );
- SET_BANK( 1, 0xc8000000, 8*1024*1024 ); // comment this out for 8MB Cerfs
- mi->nr_banks = 2;
-
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
- setup_ramdisk(1, 0, 0, 8192);
- // Save 2Meg for RAMDisk
- setup_initrd(0xc0500000, 3*1024*1024);
- }
-
- else if (machine_is_empeg()) {
- SET_BANK( 0, 0xc0000000, 4*1024*1024 );
- SET_BANK( 1, 0xc8000000, 4*1024*1024 );
- mi->nr_banks = 2;
-
- ROOT_DEV = MKDEV( 3, 1 ); /* /dev/hda1 */
- setup_ramdisk( 1, 0, 0, 4096 );
- setup_initrd( 0xd0000000+((1024-320)*1024), (320*1024) );
- }
-
- else if (machine_is_lart()) {
- /*
- * Note that LART is a special case - it doesn't use physical
- * address line A23 on the DRAM, so we effectively have 4 * 8MB
- * in two SA1100 banks.
- */
- SET_BANK( 0, 0xc0000000, 8*1024*1024 );
- SET_BANK( 1, 0xc1000000, 8*1024*1024 );
- SET_BANK( 2, 0xc8000000, 8*1024*1024 );
- SET_BANK( 3, 0xc9000000, 8*1024*1024 );
- mi->nr_banks = 4;
-
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
- setup_ramdisk(1, 0, 0, 8192);
- setup_initrd(0xc0400000, 4*1024*1024);
- }
-
- else if (machine_is_thinclient() || machine_is_graphicsclient()) {
- SET_BANK( 0, 0xc0000000, 16*1024*1024 );
- mi->nr_banks = 1;
-
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
- setup_ramdisk( 1, 0, 0, 8192 );
- setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
- }
-
- else if (machine_is_nanoengine()) {
- SET_BANK( 0, 0xc0000000, 32*1024*1024 );
- mi->nr_banks = 1;
-
- ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
- setup_ramdisk( 1, 0, 0, 8192 );
- setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
-
- /* Get command line parameters passed from the loader (if any) */
- if( *((char*)0xc0000100) )
- *cmdline = ((char *)0xc0000100);
- }
- else if (machine_is_tifon()) {
- SET_BANK( 0, 0xc0000000, 16*1024*1024 );
- SET_BANK( 1, 0xc8000000, 16*1024*1024 );
- mi->nr_banks = 2;
-
- ROOT_DEV = MKDEV(UNNAMED_MAJOR, 0);
- setup_ramdisk(1, 0, 0, 4096);
- setup_initrd( 0xd0000000 + 0x1100004, 0x140000 );
- }
-
- else if (machine_is_victor()) {
- SET_BANK( 0, 0xc0000000, 4*1024*1024 );
- mi->nr_banks = 1;
-
- ROOT_DEV = MKDEV( 60, 2 );
-
- /* Get command line parameters passed from the loader (if any) */
- if( *((char*)0xc0000000) )
- strcpy( *cmdline, ((char *)0xc0000000) );
-
- /* power off if any problem */
- strcat( *cmdline, " panic=1" );
-
- pm_power_off = victor_power_off;
- }
-
- else if (machine_is_xp860()) {
- SET_BANK( 0, 0xc0000000, 32*1024*1024 );
- mi->nr_banks = 1;
-
- pm_power_off = xp860_power_off;
- }
-}
-
-#ifdef CONFIG_SA1100_ASSABET
-MACHINE_START(ASSABET, "Intel-Assabet")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_BITSY
-MACHINE_START(BITSY, "Compaq Bitsy")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- BOOT_PARAMS(0xc0000100)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_BRUTUS
-MACHINE_START(BRUTUS, "Intel Brutus (SA1100 eval board)")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_CERF
-MACHINE_START(CERF, "Intrinsyc CerfBoard")
- MAINTAINER("Pieter Truter")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_EMPEG
-MACHINE_START(EMPEG, "empeg MP3 Car Audio Player")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_GRAPHICSCLIENT
-MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_ITSY
-MACHINE_START(ITSY, "Compaq Itsy")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- BOOT_PARAMS(0xc0000100
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_LART
-MACHINE_START(LART, "LART")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_NANOENGINE
-MACHINE_START(NANOENGINE, "BSE nanoEngine")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_PLEB
-MACHINE_START(PLEB, "PLEB")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_THINCLIENT
-MACHINE_START(THINCLIENT, "ADS ThinClient")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_TIFON
-MACHINE_START(TIFON, "Tifon")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_VICTOR
-MACHINE_START(VICTOR, "VisuAide Victor")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#ifdef CONFIG_SA1100_XP860
-MACHINE_START(XP860, "XP860")
- BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
- FIXUP(fixup_sa1100)
-MACHINE_END
-#endif
-#endif
-
#ifdef CONFIG_ARCH_L7200
static void __init
@@ -483,14 +113,20 @@ fixup_l7200(struct machine_desc *desc, struct param_struct *params,
setup_initrd( __phys_to_virt(0xf1000000), 0x00162b0d);
}
+extern void __init l7200_map_io(void);
+
MACHINE_START(L7200, "LinkUp Systems L7200SDB")
MAINTAINER("Steve Hill")
BOOT_MEM(0xf0000000, 0x80040000, 0xd0000000)
FIXUP(fixup_l7200)
+ MAPIO(l7200_map_io)
MACHINE_END
#endif
#ifdef CONFIG_ARCH_EBSA110
+
+extern void __init ebsa110_map_io(void);
+
MACHINE_START(EBSA110, "EBSA110")
MAINTAINER("Russell King")
BOOT_MEM(0x00000000, 0xe0000000, 0xe0000000)
@@ -498,18 +134,27 @@ MACHINE_START(EBSA110, "EBSA110")
DISABLE_PARPORT(0)
DISABLE_PARPORT(2)
SOFT_REBOOT
+ MAPIO(ebsa110_map_io)
MACHINE_END
#endif
#ifdef CONFIG_ARCH_NEXUSPCI
+
+extern void __init nexuspci_map_io(void);
+
MACHINE_START(NEXUSPCI, "FTV/PCI")
MAINTAINER("Philip Blundell")
BOOT_MEM(0x40000000, 0x10000000, 0xe0000000)
+ MAPIO(nexuspci_map_io)
MACHINE_END
#endif
#ifdef CONFIG_ARCH_TBOX
+
+extern void __init tbox_map_io(void);
+
MACHINE_START(TBOX, "unknown-TBOX")
MAINTAINER("Philip Blundell")
BOOT_MEM(0x80000000, 0x00400000, 0xe0000000)
+ MAPIO(tbox_map_io)
MACHINE_END
#endif
#ifdef CONFIG_ARCH_CLPS7110
@@ -528,22 +173,12 @@ MACHINE_START(LACIE_NAS, "LaCie_NAS")
MACHINE_END
#endif
#ifdef CONFIG_ARCH_CLPS7500
+
+extern void __init clps7500_map_io(void);
+
MACHINE_START(CLPS7500, "CL-PS7500")
MAINTAINER("Philip Blundell")
BOOT_MEM(0x10000000, 0x03000000, 0xe0000000)
-MACHINE_END
-#endif
-#ifdef CONFIG_ARCH_SHARK
-MACHINE_START(SHARK, "Shark")
- MAINTAINER("Alexander Schulz")
- BOOT_MEM(0x08000000, 0x40000000, 0xe0000000)
- VIDEO(0x06000000, 0x061fffff)
-MACHINE_END
-#endif
-#ifdef CONFIG_ARCH_PERSONAL_SERVER
-MACHINE_START(PERSONAL_SERVER, "Compaq Personal Server")
- MAINTAINER("Jamey Hicks / George France")
- BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
- BOOT_PARAMS(0x00000100)
+ MAPIO(clps7500_map_io)
MACHINE_END
#endif
diff --git a/arch/arm/kernel/arch.h b/arch/arm/kernel/arch.h
deleted file mode 100644
index 87494efed..000000000
--- a/arch/arm/kernel/arch.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * The size of struct machine_desc
- * (for assembler code)
- */
-#define SIZEOF_MACHINE_DESC 40
-
-#ifndef __ASSEMBLY__
-
-struct machine_desc {
- /*
- * Note! The first four elements are used
- * by assembler code in head-armv.S
- */
- unsigned int nr; /* architecture number */
- unsigned int phys_ram; /* start of physical ram */
- unsigned int phys_io; /* start of physical io */
- unsigned int virt_io; /* start of virtual io */
-
- const char *name; /* architecture name */
- unsigned int param_offset; /* parameter page */
-
- unsigned int video_start; /* start of video RAM */
- unsigned int video_end; /* end of video RAM */
-
- unsigned int reserve_lp0 :1; /* never has lp0 */
- unsigned int reserve_lp1 :1; /* never has lp1 */
- unsigned int reserve_lp2 :1; /* never has lp2 */
- unsigned int broken_hlt :1; /* hlt is broken */
- unsigned int soft_reboot :1; /* soft reboot */
- void (*fixup)(struct machine_desc *,
- struct param_struct *, char **,
- struct meminfo *);
-};
-
-/*
- * Set of macros to define architecture features. This is built into
- * a table by the linker.
- */
-#define MACHINE_START(_type,_name) \
-const struct machine_desc __mach_desc_##_type \
- __attribute__((__section__(".arch.info"))) = { \
- nr: MACH_TYPE_##_type##, \
- name: _name,
-
-#define MAINTAINER(n)
-
-#define BOOT_MEM(_pram,_pio,_vio) \
- phys_ram: _pram, \
- phys_io: _pio, \
- virt_io: _vio,
-
-#define BOOT_PARAMS(_params) \
- param_offset: _params,
-
-#define VIDEO(_start,_end) \
- video_start: _start, \
- video_end: _end,
-
-#define DISABLE_PARPORT(_n) \
- reserve_lp##_n##: 1,
-
-#define BROKEN_HLT \
- broken_hlt: 1,
-
-#define SOFT_REBOOT \
- soft_reboot: 1,
-
-#define FIXUP(_func) \
- fixup: _func,
-
-#define MACHINE_END \
-};
-
-#endif
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 8dafc4db9..a7c6d11ce 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -1,3 +1,12 @@
+/*
+ * linux/arch/arm/kernel/armksyms.c
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/user.h>
@@ -110,23 +119,6 @@ EXPORT_SYMBOL(pm_idle);
EXPORT_SYMBOL(pm_power_off);
/* processor dependencies */
-#ifdef MULTI_CPU
-EXPORT_SYMBOL(processor);
-#else
-EXPORT_SYMBOL(cpu_flush_cache_all);
-EXPORT_SYMBOL(cpu_flush_cache_area);
-EXPORT_SYMBOL(cpu_flush_cache_entry);
-EXPORT_SYMBOL(cpu_clean_cache_area);
-EXPORT_SYMBOL(cpu_flush_ram_page);
-EXPORT_SYMBOL(cpu_flush_tlb_all);
-EXPORT_SYMBOL(cpu_flush_tlb_area);
-EXPORT_SYMBOL(cpu_set_pgd);
-EXPORT_SYMBOL(cpu_set_pmd);
-EXPORT_SYMBOL(cpu_set_pte);
-EXPORT_SYMBOL(cpu_flush_icache_area);
-EXPORT_SYMBOL(cpu_cache_wback_area);
-EXPORT_SYMBOL(cpu_cache_purge_area);
-#endif
EXPORT_SYMBOL(__machine_arch_type);
/* networking */
diff --git a/arch/arm/kernel/arthur.c b/arch/arm/kernel/arthur.c
index 0547302f8..236aa5f55 100644
--- a/arch/arm/kernel/arthur.c
+++ b/arch/arm/kernel/arthur.c
@@ -1,6 +1,14 @@
/*
* Arthur personality
- * Copyright (C) 1998-1999 Philip Blundell
+ *
+ * Copyright (C) 1998, 1999, 2000 Philip Blundell
+ */
+
+/*
+ * 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/module.h>
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 0b519e9c3..e79dd71e6 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -1,25 +1,23 @@
/*
- * arch/arm/kernel/bios32.c
+ * linux/arch/arm/kernel/bios32.c
*
- * PCI bios-type initialisation for PCI machines
+ * PCI bios-type initialisation for PCI machines
*
- * Bits taken from various places.
+ * Bits taken from various places.
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
+#include <asm/page.h> /* for BUG() */
#include <asm/irq.h>
#include <asm/mach-types.h>
-
-#include "bios32.h"
+#include <asm/mach/pci.h>
static int debug_pci;
int have_isa_bridge;
-extern void hw_init(void);
-
void pcibios_report_status(u_int status_mask, int warn)
{
struct pci_dev *dev;
@@ -157,6 +155,14 @@ static void __init pci_fixup_ide_bases(struct pci_dev *dev)
}
}
+/*
+ * Put the DEC21142 to sleep
+ */
+static void __init pci_fixup_dec21142(struct pci_dev *dev)
+{
+ pci_write_config_dword(dev, 0x40, 0x80000000);
+}
+
struct pci_fixup pcibios_fixups[] = {
{
PCI_FIXUP_HEADER,
@@ -174,6 +180,10 @@ struct pci_fixup pcibios_fixups[] = {
PCI_FIXUP_HEADER,
PCI_ANY_ID, PCI_ANY_ID,
pci_fixup_ide_bases
+ }, {
+ PCI_FIXUP_HEADER,
+ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142,
+ pci_fixup_dec21142
}, { 0 }
};
@@ -277,12 +287,11 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
* SERR and PERR reporting - this chip doesn't drive the
* parity line correctly.
*/
-#if 1 /* !testing */
if (dev->vendor == PCI_VENDOR_ID_INTERG &&
dev->device == PCI_DEVICE_ID_INTERG_2000)
busdata->features &= ~(PCI_COMMAND_SERR |
PCI_COMMAND_PARITY);
-#endif
+
/*
* Calculate the maximum devsel latency.
*/
@@ -319,18 +328,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
u8 min_gnt, latency;
/*
- * architecture specific hacks. I don't really want
- * this here, but I don't see any other place for it
- * to live. Shame the device doesn't support
- * capabilities
- */
- if (machine_is_netwinder() &&
- dev->vendor == PCI_VENDOR_ID_DEC &&
- dev->device == PCI_DEVICE_ID_DEC_21142)
- /* Put the chip to sleep in case the driver isn't loaded */
- pci_write_config_dword(dev, 0x40, 0x80000000);
-
- /*
* Calculate this masters latency timer value.
* This is rather primitive - it does not take
* account of the number of masters in a system
@@ -372,184 +369,23 @@ pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *rang
ranges->mem_end -= bus->resource[1]->start;
}
-static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
+u8 __init no_swizzle(struct pci_dev *dev, u8 *pin)
{
return 0;
}
-/* ebsa285 host-specific stuff */
-
-#ifdef CONFIG_ARCH_EBSA285
-static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI };
-
-static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin)
-{
- return PCI_SLOT(dev->devfn);
-}
-
-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];
-}
-
-static struct hw_pci ebsa285_pci __initdata = {
- dc21285_init,
- 0x9000,
- 0x00100000,
- ebsa285_swizzle,
- ebsa285_map_irq
-};
-#endif
-
-#ifdef CONFIG_ARCH_CATS
-/* cats host-specific stuff */
-static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
-
-static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
- if (dev->irq >= 128)
- return dev->irq & 0x1f;
-
- if (dev->irq >= 1 && dev->irq <= 4)
- return irqmap_cats[dev->irq - 1];
-
- if (dev->irq != 0)
- printk("PCI: device %02x:%02x has unknown irq line %x\n",
- dev->bus->number, dev->devfn, dev->irq);
-
- return -1;
-}
-
-static struct hw_pci cats_pci __initdata = {
- dc21285_init,
- 0x9000,
- 0x00100000,
- no_swizzle,
- cats_map_irq
-};
-#endif
-
-#ifdef CONFIG_ARCH_NETWINDER
-/* netwinder host-specific stuff */
-static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
-#define DEV(v,d) ((v)<<16|(d))
- switch (DEV(dev->vendor, dev->device)) {
- case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142):
- 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):
- return IRQ_NETWINDER_ETHER10;
-
- case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553):
- return 0;
-
- case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105):
- return IRQ_ISA_HARDDISK1;
-
- case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000):
- case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010):
- case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000):
- return IRQ_NETWINDER_VGA;
-
- case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285):
- return 0;
-
- default:
- printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n",
- dev->bus->number, dev->devfn,
- dev->vendor, dev->device);
- return 0;
- }
-}
-
-static struct hw_pci netwinder_pci __initdata = {
- dc21285_init,
- 0x9000,
- 0x00100000,
- no_swizzle,
- netwinder_map_irq
-};
-#endif
-
-#ifdef CONFIG_ARCH_PERSONAL_SERVER
-static int irqmap_personal_server[] __initdata = {
- IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0,
- IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI
-};
-
-static int __init personal_server_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
- unsigned char line;
-
- pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
-
- if (line > 0x40 && line <= 0x5f) {
- /* line corresponds to the bit controlling this interrupt
- * in the footbridge. Ignore the first 8 interrupt bits,
- * look up the rest in the map. IN0 is bit number 8
- */
- return irqmap_personal_server[(line & 0x1f) - 8];
- } else if (line == 0) {
- /* no interrupt */
- return 0;
- } else
- return irqmap_personal_server[(line - 1) & 3];
-}
-
-static struct hw_pci personal_server_pci __initdata = {
- dc21285_init,
- 0x9000,
- 0x00100000,
- no_swizzle,
- personal_server_map_irq
-};
-
-#endif
-
-#ifdef CONFIG_ARCH_NEXUSPCI
-/*
- * Owing to a PCB cockup, issue A backplanes are wired thus:
- *
- * Slot 1 2 3 4 5 Bridge
- * IRQ D C B A A
- * A D C B B
- * B A D C C
- * C B A D D
- *
- * ID A31 A30 A29 A28 A27 A26
- */
-
-static int irqmap_ftv[] __initdata = { IRQ_PCI_A, IRQ_PCI_B, IRQ_PCI_C, IRQ_PCI_D };
-
-static int __init ftv_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
-{
- return irqmap_ftv[(slot + pin) & 3];
-}
-
-/* ftv host-specific stuff */
-static struct hw_pci ftv_pci __initdata = {
- plx90x0_init,
- 0x9000,
- 0x00100000,
- no_swizzle,
- ftv_map_irq
-};
-#endif
+extern struct hw_pci ebsa285_pci;
+extern struct hw_pci cats_pci;
+extern struct hw_pci netwinder_pci;
+extern struct hw_pci personal_server_pci;
+extern struct hw_pci ftv_pci;
+extern struct hw_pci integrator_pci;
void __init pcibios_init(void)
{
struct hw_pci *hw_pci = NULL;
+ struct arm_pci_sysdata sysdata;
+ int i;
do {
#ifdef CONFIG_ARCH_EBSA285
@@ -582,15 +418,28 @@ void __init pcibios_init(void)
break;
}
#endif
- } while (0);
+#ifdef CONFIG_ARCH_INTEGRATOR
+ if (machine_is_integrator()) {
+ hw_pci = &integrator_pci;
+ break;
+ }
+#endif
+ } while (0);
if (hw_pci == NULL)
return;
+ for (i = 0; i < MAX_NR_BUS; i++) {
+ sysdata.bus[i].features = PCI_COMMAND_FAST_BACK |
+ PCI_COMMAND_SERR |
+ PCI_COMMAND_PARITY;
+ sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST;
+ }
+
/*
* Set up the host bridge, and scan the bus.
*/
- hw_pci->init();
+ hw_pci->init(&sysdata);
/*
* Other architectures don't seem to do this... should we?
@@ -598,8 +447,7 @@ void __init pcibios_init(void)
pcibios_claim_resources();
/*
- * Assign any unassigned resources. Note that we really ought to
- * have min/max stuff here - max mem address is 0x0fffffff
+ * Assign any unassigned resources.
*/
pci_assign_unassigned_resources();
pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq);
diff --git a/arch/arm/kernel/bios32.h b/arch/arm/kernel/bios32.h
deleted file mode 100644
index 421ec6a79..000000000
--- a/arch/arm/kernel/bios32.h
+++ /dev/null
@@ -1,33 +0,0 @@
-#define MAX_NR_BUS 2
-
-struct arm_bus_sysdata {
- /*
- * bitmask of features we can turn.
- * See PCI command register for more info.
- */
- u16 features;
- /*
- * Maximum devsel for this bus.
- */
- u16 maxdevsel;
- /*
- * The maximum latency that devices on this
- * bus can withstand.
- */
- u8 max_lat;
-};
-
-struct arm_pci_sysdata {
- struct arm_bus_sysdata bus[MAX_NR_BUS];
-};
-
-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);
-void __init plx90x0_init(void);
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index eee31eeae..9d672b4e9 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -1,9 +1,13 @@
/*
- * linux/arch/arm/lib/calls.h
+ * linux/arch/arm/lib/calls.h
*
- * Copyright (C) 1995-1998 Russell King
+ * Copyright (C) 1995-1998 Russell King
*
- * This file is included twice in entry-common.S
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file is included twice in entry-common.S
*/
#ifndef NR_syscalls
#define NR_syscalls 256
diff --git a/arch/arm/kernel/debug-armo.S b/arch/arm/kernel/debug-armo.S
index 1c6aaccc3..cc10311ff 100644
--- a/arch/arm/kernel/debug-armo.S
+++ b/arch/arm/kernel/debug-armo.S
@@ -1,9 +1,13 @@
/*
- * linux/arch/arm/kernel/debug-armo.S
+ * linux/arch/arm/kernel/debug-armo.S
*
- * Copyright (C) 1999 Russell King
+ * Copyright (C) 1999 Russell King
*
- * 26-bit debugging code
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 26-bit debugging code
*/
#include <linux/linkage.h>
diff --git a/arch/arm/kernel/debug-armv.S b/arch/arm/kernel/debug-armv.S
index e0b916438..8f9501754 100644
--- a/arch/arm/kernel/debug-armv.S
+++ b/arch/arm/kernel/debug-armv.S
@@ -1,14 +1,18 @@
/*
- * linux/arch/arm/kernel/debug-armv.S
+ * linux/arch/arm/kernel/debug-armv.S
*
- * Copyright (C) 1994-1999 Russell King
+ * Copyright (C) 1994-1999 Russell King
*
- * 32-bit debugging code
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 32-bit debugging code
*/
#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/hardware.h>
-#include <asm/dec21285.h>
+#include <asm/hardware/dec21285.h>
.text
@@ -29,10 +33,10 @@
.endm
.macro busyuart,rd,rx
-1002: ldrb \rd, [\rx, #0x14]
+1001: ldrb \rd, [\rx, #0x14]
and \rd, \rd, #0x60
teq \rd, #0x60
- bne 1002b
+ bne 1001b
.endm
.macro waituart,rd,rx
@@ -189,6 +193,38 @@
tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy
bne 1001b
.endm
+
+#elif defined(CONFIG_ARCH_INTEGRATOR)
+
+#include <asm/hardware/serial_amba.h>
+
+ .equ io_virt, 0xf0000000 + (0x16000000 >> 4)
+ .equ io_phys, 0x16000000
+
+ .macro addruart,rx
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ moveq \rx, #0x16000000 @ physical base address
+ movne \rx, #0xf0000000 @ virtual base
+ addne \rx, \rx, #0x16000000 >> 4
+ .endm
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #AMBA_UARTDR]
+ .endm
+
+ .macro waituart,rd,rx
+1001: ldr \rd, [\rx, #0x18] @ UARTFLG
+ tst \rd, #1 << 5 @ UARTFLGUTXFF - 1 when full
+ bne 1001b
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldr \rd, [\rx, #0x18] @ UARTFLG
+ tst \rd, #1 << 3 @ UARTFLGUBUSY - 1 when busy
+ bne 1001b
+ .endm
+
#else
#error Unknown architecture
#endif
diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c
index 3238b3a3c..8c427b379 100644
--- a/arch/arm/kernel/dec21285.c
+++ b/arch/arm/kernel/dec21285.c
@@ -1,7 +1,11 @@
/*
- * arch/arm/kernel/dec21285.c: PCI functions for DC21285
+ * linux/arch/arm/kernel/dec21285.c: PCI functions for DC21285
*
- * Copyright (C) 1998-2000 Russell King, Phil Blundell
+ * Copyright (C) 1998-2000 Russell King, Phil Blundell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -12,12 +16,11 @@
#include <linux/init.h>
#include <linux/ioport.h>
-#include <asm/dec21285.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/system.h>
-
-#include "bios32.h"
+#include <asm/mach/pci.h>
+#include <asm/hardware/dec21285.h>
#define MAX_SLOTS 21
@@ -252,7 +255,7 @@ static void dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs)
add_timer(timer);
}
-void __init dc21285_init(void)
+void __init dc21285_init(struct arm_pci_sysdata *sysdata)
{
unsigned long cntl;
unsigned int mem_size;
@@ -279,19 +282,26 @@ void __init dc21285_init(void)
"central function" : "addin");
if (cfn_mode) {
- static struct resource csrmem, csrio;
- struct arm_pci_sysdata sysdata;
- int i;
+ static struct resource csrmem, csrio, busmem, busmempf;
+ struct pci_bus *bus;
csrio.flags = IORESOURCE_IO;
- csrio.name = "DC21285";
+ csrio.name = "Footbridge";
csrmem.flags = IORESOURCE_MEM;
- csrmem.name = "DC21285";
+ csrmem.name = "Footbridge";
+ busmem.flags = IORESOURCE_MEM;
+ busmem.name = "Footbridge non-prefetch";
+ busmempf.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
+ busmempf.name = "Footbridge prefetch";
allocate_resource(&ioport_resource, &csrio, 128,
0xff00, 0xffff, 128, NULL, NULL);
allocate_resource(&iomem_resource, &csrmem, 128,
0xf4000000, 0xf8000000, 128, NULL, NULL);
+ allocate_resource(&iomem_resource, &busmempf, 0x20000000,
+ 0x00000000, 0x80000000, 0x20000000, NULL, NULL);
+ allocate_resource(&iomem_resource, &busmem, 0x40000000,
+ 0x00000000, 0x80000000, 0x40000000, NULL, NULL);
/*
* Map our SDRAM at a known address in PCI space, just in case
@@ -302,24 +312,24 @@ void __init dc21285_init(void)
*CSR_PCICACHELINESIZE = 0x00002008;
*CSR_PCICSRBASE = csrmem.start;
*CSR_PCICSRIOBASE = csrio.start;
- *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET);
+ *CSR_PCISDRAMBASE = __virt_to_bus(PAGE_OFFSET);
*CSR_PCIROMBASE = 0;
*CSR_PCICMD = pci_cmd |
(1 << 31) | (1 << 29) | (1 << 28) | (1 << 24);
- for (i = 0; i < MAX_NR_BUS; i++) {
- sysdata.bus[i].features = PCI_COMMAND_FAST_BACK |
- PCI_COMMAND_SERR |
- PCI_COMMAND_PARITY;
- sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST;
- }
-
- pci_scan_bus(0, &dc21285_ops, &sysdata);
+ bus = pci_scan_bus(0, &dc21285_ops, sysdata);
+ /*
+ * bus->resource[0] is the IO resource for this bus
+ * bus->resource[1] is the mem resource for this bus
+ * bus->resource[2] is the prefetch mem resource for this bus
+ */
+ bus->resource[1] = &busmem;
+ bus->resource[2] = &busmempf;
- pci_cmd |= sysdata.bus[0].features;
+ pci_cmd |= sysdata->bus[0].features;
printk("PCI: Fast back to back transfers %sabled\n",
- (sysdata.bus[0].features & PCI_COMMAND_FAST_BACK) ?
+ (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ?
"en" : "dis");
/*
diff --git a/arch/arm/kernel/dma-arc.c b/arch/arm/kernel/dma-arc.c
index 25fbcccd8..2ad2edf3b 100644
--- a/arch/arm/kernel/dma-arc.c
+++ b/arch/arm/kernel/dma-arc.c
@@ -1,9 +1,13 @@
/*
- * arch/arm/kernel/dma-arc.c
+ * linux/arch/arm/kernel/dma-arc.c
*
- * Copyright (C) 1998-1999 Dave Gilbert / Russell King
+ * Copyright (C) 1998-1999 Dave Gilbert / Russell King
*
- * DMA functions specific to Archimedes and A5000 architecture
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * DMA functions specific to Archimedes and A5000 architecture
*/
#include <linux/config.h>
#include <linux/sched.h>
@@ -11,11 +15,12 @@
#include <asm/dma.h>
#include <asm/fiq.h>
+#include <asm/irq.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
-#include "dma.h"
+#include <asm/mach/dma.h>
#define DPRINTK(x...) printk(KERN_DEBUG x)
@@ -30,11 +35,11 @@ static void arc_floppy_data_enable_dma(dmach_t channel, dma_t *dma)
unsigned long flags;
DPRINTK("enable_dma fdc1772 data read\n");
save_flags(flags);
- cliIF();
+ clf();
memcpy ((void *)0x1c, (void *)&fdc1772_dma_read,
&fdc1772_dma_read_end - &fdc1772_dma_read);
- fdc1772_setupdma(dma->buf.length, __bus_to_virt(dma->buf.address)); /* Sets data pointer up */
+ fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */
enable_irq (64);
restore_flags(flags);
}
@@ -46,10 +51,10 @@ static void arc_floppy_data_enable_dma(dmach_t channel, dma_t *dma)
unsigned long flags;
DPRINTK("enable_dma fdc1772 data write\n");
save_flags(flags);
- cliIF();
+ clf();
memcpy ((void *)0x1c, (void *)&fdc1772_dma_write,
&fdc1772_dma_write_end - &fdc1772_dma_write);
- fdc1772_setupdma(dma->buf.length, __bus_to_virt(dma->buf.address)); /* Sets data pointer up */
+ fdc1772_setupdma(dma->buf.length, dma->buf.address); /* Sets data pointer up */
enable_irq (64);
restore_flags(flags);
@@ -77,7 +82,7 @@ static void arc_floppy_cmdend_enable_dma(dmach_t channel, dma_t *dma)
DPRINTK("arc_floppy_cmdend_enable_dma\n");
/*printk("enable_dma fdc1772 command end FIQ\n");*/
save_flags(flags);
- cliIF();
+ clf();
/* B fdc1772_comendhandler */
*((unsigned int *)0x1c)=0xea000000 |
@@ -150,7 +155,7 @@ static void a5k_floppy_enable_dma(dmach_t channel, dma_t *dma)
}
memcpy((void *)0x1c, fiqhandler_start, fiqhandler_length);
regs.ARM_r9 = dma->buf.length;
- regs.ARM_r10 = __bus_to_virt(dma->buf.address);
+ regs.ARM_r10 = dma->buf.address;
regs.ARM_fp = (int)PCIO_FLOPPYDMABASE;
set_fiq_regs(&regs);
enable_irq(dma->dma_irq);
@@ -173,7 +178,7 @@ static struct dma_ops a5k_floppy_dma_ops = {
/*
* This is virtual DMA - we don't need anything here
*/
-static int sound_enable_disable_dma(dmach_t channel, dma_t *dma)
+static void sound_enable_disable_dma(dmach_t channel, dma_t *dma)
{
}
@@ -195,8 +200,8 @@ void __init arch_dma_init(dma_t *dma)
#endif
#ifdef CONFIG_ARCH_A5K
if (machine_is_a5k()) {
- dma[DMA_VIRTUAL_FLOPPY].dma_irq = 64;
- dma[DMA_VIRTUAL_FLOPPY].d_ops = &a5k_floppy_dma_ops;
+ dma[DMA_VIRTUAL_FLOPPY0].dma_irq = 64;
+ dma[DMA_VIRTUAL_FLOPPY0].d_ops = &a5k_floppy_dma_ops;
}
#endif
dma[DMA_VIRTUAL_SOUND].d_ops = &sound_dma_ops;
diff --git a/arch/arm/kernel/dma-footbridge.c b/arch/arm/kernel/dma-footbridge.c
index b9d4b62fa..1674a007a 100644
--- a/arch/arm/kernel/dma-footbridge.c
+++ b/arch/arm/kernel/dma-footbridge.c
@@ -1,27 +1,24 @@
/*
- * arch/arm/kernel/dma-ebsa285.c
+ * linux/arch/arm/kernel/dma-ebsa285.c
*
- * Copyright (C) 1998 Phil Blundell
+ * Copyright (C) 1998 Phil Blundell
*
* DMA functions specific to EBSA-285/CATS architectures
*
- * Changelog:
- * 09-Nov-1998 RMK Split out ISA DMA functions to dma-isa.c
- * 17-Mar-1999 RMK Allow any EBSA285-like architecture to have
+ * Changelog:
+ * 09-Nov-1998 RMK Split out ISA DMA functions to dma-isa.c
+ * 17-Mar-1999 RMK Allow any EBSA285-like architecture to have
* ISA DMA controllers.
*/
-
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/init.h>
-#include <asm/dec21285.h>
#include <asm/dma.h>
#include <asm/io.h>
-#include "dma.h"
-
-extern void isa_init_dma(dma_t *dma);
+#include <asm/mach/dma.h>
+#include <asm/hardware/dec21285.h>
#if 0
static int fb_dma_request(dmach_t channel, dma_t *dma)
diff --git a/arch/arm/kernel/dma-isa.c b/arch/arm/kernel/dma-isa.c
index f144d0436..b3a1ea06d 100644
--- a/arch/arm/kernel/dma-isa.c
+++ b/arch/arm/kernel/dma-isa.c
@@ -1,24 +1,30 @@
/*
- * arch/arm/kernel/dma-isa.c: ISA DMA primitives
+ * linux/arch/arm/kernel/dma-isa.c
*
- * Copyright (C) 1999-2000 Russell King
+ * Copyright (C) 1999-2000 Russell King
*
- * Taken from various sources, including:
- * linux/include/asm/dma.h: Defines for using and allocating dma channels.
- * Written by Hennus Bergman, 1992.
- * High DMA channel support & info by Hannu Savolainen and John Boyd,
- * Nov. 1992.
- * arch/arm/kernel/dma-ebsa285.c
- * Copyright (C) 1998 Phil Blundell
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * ISA DMA primitives
+ * Taken from various sources, including:
+ * linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ * Written by Hennus Bergman, 1992.
+ * High DMA channel support & info by Hannu Savolainen and John Boyd,
+ * Nov. 1992.
+ * arch/arm/kernel/dma-ebsa285.c
+ * Copyright (C) 1998 Phil Blundell
*/
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/pci.h>
#include <asm/dma.h>
#include <asm/io.h>
-#include "dma.h"
+#include <asm/mach/dma.h>
#define ISA_DMA_MODE_READ 0x44
#define ISA_DMA_MODE_WRITE 0x48
@@ -60,48 +66,58 @@ static void isa_enable_dma(dmach_t channel, dma_t *dma)
{
if (dma->invalid) {
unsigned long address, length;
- unsigned int mode;
-
- address = dma->buf.address;
- length = dma->buf.length - 1;
-
- outb(address >> 16, isa_dma_port[channel][ISA_DMA_PGLO]);
- outb(address >> 24, isa_dma_port[channel][ISA_DMA_PGHI]);
-
- if (channel >= 4) {
- address >>= 1;
- length >>= 1;
- }
-
- outb(0, isa_dma_port[channel][ISA_DMA_CLRFF]);
-
- outb(address, isa_dma_port[channel][ISA_DMA_ADDR]);
- outb(address >> 8, isa_dma_port[channel][ISA_DMA_ADDR]);
-
- outb(length, isa_dma_port[channel][ISA_DMA_COUNT]);
- outb(length >> 8, isa_dma_port[channel][ISA_DMA_COUNT]);
+ unsigned int mode, direction;
mode = channel & 3;
-
switch (dma->dma_mode & DMA_MODE_MASK) {
case DMA_MODE_READ:
mode |= ISA_DMA_MODE_READ;
- dma_cache_inv(__bus_to_virt(dma->buf.address), dma->buf.length);
+ direction = PCI_DMA_FROMDEVICE;
break;
case DMA_MODE_WRITE:
mode |= ISA_DMA_MODE_WRITE;
- dma_cache_wback(__bus_to_virt(dma->buf.address), dma->buf.length);
+ direction = PCI_DMA_TODEVICE;
break;
case DMA_MODE_CASCADE:
mode |= ISA_DMA_MODE_CASCADE;
+ direction = PCI_DMA_BIDIRECTIONAL;
break;
default:
break;
}
+ if (!dma->using_sg) {
+ /*
+ * Cope with ISA-style drivers which expect cache
+ * coherence.
+ */
+ dma->buf.dma_address = pci_map_single(NULL,
+ dma->buf.address, dma->buf.length,
+ direction);
+ }
+
+ address = dma->buf.dma_address;
+ length = dma->buf.length - 1;
+
+ outb(address >> 16, isa_dma_port[channel][ISA_DMA_PGLO]);
+ outb(address >> 24, isa_dma_port[channel][ISA_DMA_PGHI]);
+
+ if (channel >= 4) {
+ address >>= 1;
+ length >>= 1;
+ }
+
+ outb(0, isa_dma_port[channel][ISA_DMA_CLRFF]);
+
+ outb(address, isa_dma_port[channel][ISA_DMA_ADDR]);
+ outb(address >> 8, isa_dma_port[channel][ISA_DMA_ADDR]);
+
+ outb(length, isa_dma_port[channel][ISA_DMA_COUNT]);
+ outb(length >> 8, isa_dma_port[channel][ISA_DMA_COUNT]);
+
if (dma->dma_mode & DMA_AUTOINIT)
mode |= ISA_DMA_AUTOINIT;
diff --git a/arch/arm/kernel/dma-rpc.c b/arch/arm/kernel/dma-rpc.c
index c7eecfe42..b46ca7753 100644
--- a/arch/arm/kernel/dma-rpc.c
+++ b/arch/arm/kernel/dma-rpc.c
@@ -1,25 +1,30 @@
/*
- * arch/arm/kernel/dma-rpc.c
+ * linux/arch/arm/kernel/dma-rpc.c
*
- * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998 Russell King
*
- * DMA functions specific to RiscPC architecture
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * DMA functions specific to RiscPC architecture
*/
#include <linux/sched.h>
#include <linux/malloc.h>
#include <linux/mman.h>
#include <linux/init.h>
+#include <linux/pci.h>
#include <asm/page.h>
#include <asm/dma.h>
#include <asm/fiq.h>
#include <asm/io.h>
-#include <asm/iomd.h>
#include <asm/irq.h>
#include <asm/hardware.h>
#include <asm/uaccess.h>
-#include "dma.h"
+#include <asm/mach/dma.h>
+#include <asm/hardware/iomd.h>
#if 0
typedef enum {
@@ -47,13 +52,13 @@ typedef struct {
#define state_wait_a 1
#define state_wait_b 2
-static void iomd_get_next_sg(dmasg_t *sg, dma_t *dma)
+static void iomd_get_next_sg(struct scatterlist *sg, dma_t *dma)
{
unsigned long end, offset, flags = 0;
if (dma->sg) {
- sg->address = dma->sg->address;
- offset = sg->address & ~PAGE_MASK;
+ sg->dma_address = dma->sg->dma_address;
+ offset = sg->dma_address & ~PAGE_MASK;
end = offset + dma->sg->length;
@@ -66,7 +71,7 @@ static void iomd_get_next_sg(dmasg_t *sg, dma_t *dma)
sg->length = end - TRANSFER_SIZE;
dma->sg->length -= end - offset;
- dma->sg->address += end - offset;
+ dma->sg->dma_address += end - offset;
if (dma->sg->length == 0) {
if (dma->sgcount > 1) {
@@ -79,22 +84,22 @@ static void iomd_get_next_sg(dmasg_t *sg, dma_t *dma)
}
} else {
flags = DMA_END_S | DMA_END_L;
- sg->address = 0;
+ sg->dma_address = 0;
sg->length = 0;
}
sg->length |= flags;
}
-static inline void iomd_setup_dma_a(dmasg_t *sg, dma_t *dma)
+static inline void iomd_setup_dma_a(struct scatterlist *sg, dma_t *dma)
{
- outl_t(sg->address, dma->dma_base + CURA);
+ outl_t(sg->dma_address, dma->dma_base + CURA);
outl_t(sg->length, dma->dma_base + ENDA);
}
-static inline void iomd_setup_dma_b(dmasg_t *sg, dma_t *dma)
+static inline void iomd_setup_dma_b(struct scatterlist *sg, dma_t *dma)
{
- outl_t(sg->address, dma->dma_base + CURB);
+ outl_t(sg->dma_address, dma->dma_base + CURB);
outl_t(sg->length, dma->dma_base + ENDB);
}
@@ -160,17 +165,8 @@ static void iomd_dma_handle(int irq, void *dev_id, struct pt_regs *regs)
static int iomd_request_dma(dmach_t channel, dma_t *dma)
{
- unsigned long flags;
- int ret;
-
- save_flags_cli(flags);
- ret = request_irq(dma->dma_irq, iomd_dma_handle,
- SA_INTERRUPT, dma->device_id, dma);
- if (!ret)
- disable_irq(dma->dma_irq);
- restore_flags(flags);
-
- return ret;
+ return request_irq(dma->dma_irq, iomd_dma_handle,
+ SA_INTERRUPT, dma->device_id, dma);
}
static void iomd_free_dma(dmach_t channel, dma_t *dma)
@@ -186,6 +182,17 @@ static void iomd_enable_dma(dmach_t channel, dma_t *dma)
if (dma->invalid) {
dma->invalid = 0;
+ /*
+ * Cope with ISA-style drivers which expect cache
+ * coherence.
+ */
+ if (!dma->using_sg) {
+ dma->buf.dma_address = pci_map_single(NULL,
+ dma->buf.address, dma->buf.length,
+ dma->dma_mode == DMA_MODE_READ ?
+ PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
+ }
+
outb_t(DMA_CR_C, dma_base + CR);
dma->state = state_prog_a;
}
@@ -279,8 +286,8 @@ static void floppy_enable_dma(dmach_t channel, dma_t *dma)
}
regs.ARM_r9 = dma->buf.length;
- regs.ARM_r10 = __bus_to_virt(dma->buf.address);
- regs.ARM_fp = (int)PCIO_FLOPPYDMABASE;
+ regs.ARM_r10 = (unsigned long)dma->buf.address;
+ regs.ARM_fp = (unsigned long)PCIO_FLOPPYDMABASE;
if (claim_fiq(&fh)) {
printk("floppydma: couldn't claim FIQ.\n");
diff --git a/arch/arm/kernel/dma.c b/arch/arm/kernel/dma.c
index 6fe844db4..ad311020f 100644
--- a/arch/arm/kernel/dma.c
+++ b/arch/arm/kernel/dma.c
@@ -1,11 +1,15 @@
/*
- * linux/arch/arm/kernel/dma.c
+ * linux/arch/arm/kernel/dma.c
*
- * Copyright (C) 1995-2000 Russell King
+ * Copyright (C) 1995-2000 Russell King
*
- * Front-end to the DMA handling. This handles the allocation/freeing
- * of DMA channels, and provides a unified interface to the machines
- * DMA facilities.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Front-end to the DMA handling. This handles the allocation/freeing
+ * of DMA channels, and provides a unified interface to the machines
+ * DMA facilities.
*/
#include <linux/module.h>
#include <linux/malloc.h>
@@ -16,7 +20,7 @@
#include <asm/dma.h>
-#include "dma.h"
+#include <asm/mach/dma.h>
spinlock_t dma_spin_lock = SPIN_LOCK_UNLOCKED;
@@ -111,12 +115,13 @@ bad_dma:
/* Set DMA Scatter-Gather list
*/
-void set_dma_sg (dmach_t channel, dmasg_t *sg, int nr_sg)
+void set_dma_sg (dmach_t channel, struct scatterlist *sg, int nr_sg)
{
dma_t *dma = dma_chan + channel;
dma->sg = sg;
dma->sgcount = nr_sg;
+ dma->using_sg = 1;
dma->invalid = 1;
}
@@ -134,7 +139,8 @@ void set_dma_addr (dmach_t channel, unsigned long physaddr)
dma->sg = &dma->buf;
dma->sgcount = 1;
- dma->buf.address = physaddr;
+ dma->buf.address = bus_to_virt(physaddr);
+ dma->using_sg = 0;
dma->invalid = 1;
}
@@ -153,6 +159,7 @@ void set_dma_count (dmach_t channel, unsigned long count)
dma->sg = &dma->buf;
dma->sgcount = 1;
dma->buf.length = count;
+ dma->using_sg = 0;
dma->invalid = 1;
}
diff --git a/arch/arm/kernel/dma.h b/arch/arm/kernel/dma.h
deleted file mode 100644
index 6cd96ed97..000000000
--- a/arch/arm/kernel/dma.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * linux/arch/arm/kernel/dma.h
- *
- * Copyright (C) 1998-2000 Russell King
- *
- * This header file describes the interface between the generic DMA handler
- * (dma.c) and the architecture-specific DMA backends (dma-*.c)
- */
-
-struct dma_struct;
-typedef struct dma_struct dma_t;
-
-struct dma_ops {
- int (*request)(dmach_t, dma_t *); /* optional */
- void (*free)(dmach_t, dma_t *); /* optional */
- void (*enable)(dmach_t, dma_t *); /* mandatory */
- void (*disable)(dmach_t, dma_t *); /* mandatory */
- int (*residue)(dmach_t, dma_t *); /* optional */
- int (*setspeed)(dmach_t, dma_t *, int); /* optional */
- char *type;
-};
-
-struct dma_struct {
- dmasg_t buf; /* single DMA */
- int sgcount; /* number of DMA SG */
- dmasg_t *sg; /* DMA Scatter-Gather List */
-
- unsigned int active:1; /* Transfer active */
- unsigned int invalid:1; /* Address/Count changed */
- dmamode_t dma_mode; /* DMA mode */
- int speed; /* DMA speed */
-
- unsigned int lock; /* Device is allocated */
- const char *device_id; /* Device name */
-
- unsigned int dma_base; /* Controller base address */
- int dma_irq; /* Controller IRQ */
- int state; /* Controller state */
- dmasg_t cur_sg; /* Current controller buffer */
-
- struct dma_ops *d_ops;
-};
-
-/* Prototype: void arch_dma_init(dma)
- * Purpose : Initialise architecture specific DMA
- * Params : dma - pointer to array of DMA structures
- */
-void arch_dma_init(dma_t *dma);
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index 6d9b425ea..3584c3227 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -1,27 +1,30 @@
/*
- * linux/arch/arm/kernel/ecard.c
+ * linux/arch/arm/kernel/ecard.c
*
- * Find all installed expansion cards, and handle interrupts from them.
+ * Copyright 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
- * Copyright 1995-1998 Russell King
+ * Find all installed expansion cards, and handle interrupts from them.
*
- * Created from information from Acorns RiscOS3 PRMs
+ * Created from information from Acorns RiscOS3 PRMs
*
- * 08-Dec-1996 RMK Added code for the 9'th expansion card - the ether
+ * 08-Dec-1996 RMK Added code for the 9'th expansion card - the ether
* podule slot.
- * 06-May-1997 RMK Added blacklist for cards whose loader doesn't work.
- * 12-Sep-1997 RMK Created new handling of interrupt enables/disables
+ * 06-May-1997 RMK Added blacklist for cards whose loader doesn't work.
+ * 12-Sep-1997 RMK Created new handling of interrupt enables/disables
* - cards can now register their own routine to control
* interrupts (recommended).
- * 29-Sep-1997 RMK Expansion card interrupt hardware not being re-enabled
+ * 29-Sep-1997 RMK Expansion card interrupt hardware not being re-enabled
* on reset from Linux. (Caused cards not to respond
* under RiscOS without hard reset).
- * 15-Feb-1998 RMK Added DMA support
- * 12-Sep-1998 RMK Added EASI support
- * 10-Jan-1999 RMK Run loaders in a simulated RISC OS environment.
- * 17-Apr-1999 RMK Support for EASI Type C cycles.
+ * 15-Feb-1998 RMK Added DMA support
+ * 12-Sep-1998 RMK Added EASI support
+ * 10-Jan-1999 RMK Run loaders in a simulated RISC OS environment.
+ * 17-Apr-1999 RMK Support for EASI Type C cycles.
*/
-
#define ECARD_C
#define __KERNEL_SYSCALLS__
@@ -137,15 +140,10 @@ ecard_task_reset(struct ecard_request *req)
if (req->ec == NULL) {
ecard_t *ec;
- for (ec = cards; ec; ec = ec->next) {
- printk(KERN_DEBUG "Resetting card %d\n",
- ec->slot_no);
-
+ for (ec = cards; ec; ec = ec->next)
if (ec->loader)
ecard_loader_reset(POD_INT_ADDR(ec->podaddr),
ec->loader);
- }
- printk(KERN_DEBUG "All cards reset\n");
} else if (req->ec->loader)
ecard_loader_reset(POD_INT_ADDR(req->ec->podaddr),
req->ec->loader);
@@ -318,7 +316,7 @@ ecard_task(void * unused)
* We don't want /any/ signals, not even SIGKILL
*/
sigfillset(&tsk->blocked);
- sigemptyset(&tsk->signal);
+ sigemptyset(&tsk->pending.signal);
recalc_sigpending(tsk);
strcpy(tsk->comm, "kecardd");
@@ -335,7 +333,7 @@ ecard_task(void * unused)
req = xchg(&ecard_req, NULL);
if (req == NULL) {
- sigemptyset(&tsk->signal);
+ sigemptyset(&tsk->pending.signal);
interruptible_sleep_on(&ecard_wait);
}
} while (req == NULL);
diff --git a/arch/arm/kernel/entry-armo.S b/arch/arm/kernel/entry-armo.S
index ab0f4e69e..e4df9fe1a 100644
--- a/arch/arm/kernel/entry-armo.S
+++ b/arch/arm/kernel/entry-armo.S
@@ -1,25 +1,29 @@
/*
- * linux/arch/arm/kernel/entry-armo.S
+ * linux/arch/arm/kernel/entry-armo.S
*
- * Copyright (C) 1995,1996,1997,1998 Russell King.
+ * Copyright (C) 1995,1996,1997,1998 Russell King.
*
- * Low-level vector interface routines
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
- * Design issues:
- * - We have several modes that each vector can be called from,
- * each with its own set of registers. On entry to any vector,
- * we *must* save the registers used in *that* mode.
+ * Low-level vector interface routines
*
- * - This code must be as fast as possible.
+ * Design issues:
+ * - We have several modes that each vector can be called from,
+ * each with its own set of registers. On entry to any vector,
+ * we *must* save the registers used in *that* mode.
*
- * There are a few restrictions on the vectors:
- * - the SWI vector cannot be called from *any* non-user mode
+ * - This code must be as fast as possible.
*
- * - the FP emulator is *never* called from *any* non-user mode undefined
- * instruction.
+ * There are a few restrictions on the vectors:
+ * - the SWI vector cannot be called from *any* non-user mode
*
- * Ok, so this file may be a mess, but its as efficient as possible while
- * adhering to the above criteria.
+ * - the FP emulator is *never* called from *any* non-user mode undefined
+ * instruction.
+ *
+ * Ok, so this file may be a mess, but its as efficient as possible while
+ * adhering to the above criteria.
*/
#include <linux/linkage.h>
#include <linux/config.h>
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 002c39933..c8c737404 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -1,13 +1,17 @@
/*
- * linux/arch/arm/kernel/entry-armv.S
+ * linux/arch/arm/kernel/entry-armv.S
*
- * Copyright (C) 1996,1997,1998 Russell King.
- * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk)
+ * Copyright (C) 1996,1997,1998 Russell King.
+ * ARM700 fix by Matthew Godbolt (linux-user@willothewisp.demon.co.uk)
*
- * Low-level vector interface routines
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
- * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes
- * it to save wrong values... Be aware!
+ * Low-level vector interface routines
+ *
+ * Note: there is a StrongARM bug in the STMIA rn, {regs}^ instruction that causes
+ * it to save wrong values... Be aware!
*/
#include <linux/config.h> /* for CONFIG_ARCH_xxxx */
#include <linux/linkage.h>
@@ -68,7 +72,7 @@
#ifdef IOC_BASE
/* IOC / IOMD based hardware */
-#include <asm/iomd.h>
+#include <asm/hardware/iomd.h>
.equ ioc_base_high, IOC_BASE & 0xff000000
.equ ioc_base_low, IOC_BASE & 0x00ff0000
@@ -226,7 +230,7 @@ irq_prio_ebsa110:
.endm
#elif defined(CONFIG_FOOTBRIDGE)
-#include <asm/dec21285.h>
+#include <asm/hardware/dec21285.h>
.macro disable_fiq
.endm
@@ -425,9 +429,9 @@ ENTRY(soft_irq_mask)
.endm
.macro get_irqnr_and_base, irqnr, irqstat, base
- mov r4, #irq_base_addr @ Virt addr IRQ regs
- add r4, r4, #0x00001000 @ Status reg
- ldr \irqstat, [r4] @ get interrupts
+ mov \irqstat, #irq_base_addr @ Virt addr IRQ regs
+ add \irqstat, \irqstat, #0x00001000 @ Status reg
+ ldr \irqstat, [\irqstat, #0] @ get interrupts
mov \irqnr, #0
1001: tst \irqstat, #1
addeq \irqnr, \irqnr, #1
@@ -440,6 +444,32 @@ ENTRY(soft_irq_mask)
.macro irq_prio_table
.endm
+#elif defined(CONFIG_ARCH_INTEGRATOR)
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base
+/* FIXME: should not be using soo many LDRs here */
+ ldr \irqnr, =IO_ADDRESS(INTEGRATOR_IC_BASE)
+ ldr \irqstat, [\irqnr, #IRQ_STATUS] @ get masked status
+ ldr \irqnr, =IO_ADDRESS(INTEGRATOR_HDR_BASE)
+ ldr \irqnr, [\irqnr, #(INTEGRATOR_HDR_IC_OFFSET+IRQ_STATUS)]
+ orr \irqstat, \irqstat, \irqnr, lsl #INTEGRATOR_CM_INT0
+
+ mov \irqnr, #0
+1001: tst \irqstat, #1
+ bne 1002f
+ add \irqnr, \irqnr, #1
+ mov \irqstat, \irqstat, lsr #1
+ cmp \irqnr, #22
+ bcc 1001b
+1002: /* EQ will be set if we reach 22 */
+ .endm
+
+ .macro irq_prio_table
+ .endm
+
#else
#error Unknown architecture
#endif
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index b22720cd5..8fe41f38c 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -1,3 +1,12 @@
+/*
+ * linux/arch/arm/kernel/entry-common.S
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
#include <linux/config.h>
#define PT_TRACESYS 0x00000002
diff --git a/arch/arm/kernel/ftv-pci.c b/arch/arm/kernel/ftv-pci.c
new file mode 100644
index 000000000..11369bc58
--- /dev/null
+++ b/arch/arm/kernel/ftv-pci.c
@@ -0,0 +1,51 @@
+/*
+ * linux/arch/arm/kernel/ftv-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+/*
+ * Owing to a PCB cockup, issue A backplanes are wired thus:
+ *
+ * Slot 1 2 3 4 5 Bridge S1 S2 S3 S4
+ * IRQ D C B A A C B A D
+ * A D C B B D C B A
+ * B A D C C A D C B
+ * C B A D D B A D C
+ *
+ * ID A31 A30 A29 A28 A27 A26 DEV4 DEV5 DEV6 DEV7
+ *
+ * Actually, this isn't too bad, because with the processor card
+ * in slot 5 on the primary bus, the IRQs rotate on both sides
+ * as you'd expect.
+ */
+
+static int irqmap_ftv[] __initdata = { IRQ_PCI_D, IRQ_PCI_C, IRQ_PCI_B, IRQ_PCI_A };
+
+static int __init ftv_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (slot > 0x10)
+ slot--;
+ return irqmap_ftv[(slot - pin) & 3];
+}
+
+static u8 __init ftv_swizzle(struct pci_dev *dev, u8 *pin)
+{
+ return PCI_SLOT(dev->devfn);
+}
+
+/* ftv host-specific stuff */
+struct hw_pci ftv_pci __initdata = {
+ init: plx90x0_init,
+ swizzle: ftv_swizzle,
+ map_irq: ftv_map_irq,
+};
+
diff --git a/arch/arm/kernel/head-armo.S b/arch/arm/kernel/head-armo.S
index f0360a3d9..f42f3337d 100644
--- a/arch/arm/kernel/head-armo.S
+++ b/arch/arm/kernel/head-armo.S
@@ -1,9 +1,13 @@
/*
- * linux/arch/arm/kernel/head-armo.S
+ * linux/arch/arm/kernel/head-armo.S
*
- * Copyright (C) 1994-2000 Russell King
+ * Copyright (C) 1994-2000 Russell King
*
- * 26-bit kernel startup code
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 26-bit kernel startup code
*/
#include <linux/config.h>
#include <linux/linkage.h>
@@ -72,6 +76,7 @@ detect_arch_type:
mov pc, lr
detect_proc_type:
+ mov ip, lr
mov r2, #0xea000000 @ Point undef instr to continuation
adr r0, continue - 12
orr r0, r2, r0, lsr #2
@@ -80,8 +85,9 @@ detect_proc_type:
ldr r0, arm2_id
swp r2, r2, [r1] @ check for swp (ARM2 can't)
ldr r0, arm250_id
- mrc 15, 0, r0, c0, c0 @ check for CP#15 (ARM250 can't)
+ mrc 15, 0, r3, c0, c0 @ check for CP#15 (ARM250 can't)
+ mov r0, r3
continue: mov r2, #0xeb000000 @ Make undef vector loop
sub r2, r2, #2
str r2, [r1, #4]
- mov pc, lr
+ mov pc, ip
diff --git a/arch/arm/kernel/head-armv.S b/arch/arm/kernel/head-armv.S
index e253c7efa..5e141bf51 100644
--- a/arch/arm/kernel/head-armv.S
+++ b/arch/arm/kernel/head-armv.S
@@ -1,26 +1,36 @@
/*
- * linux/arch/arm/kernel/head-armv.S
+ * linux/arch/arm/kernel/head-armv.S
*
- * Copyright (C) 1994-1999 Russell King
+ * Copyright (C) 1994-1999 Russell King
*
- * 32-bit kernel startup code for all architectures
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 32-bit kernel startup code for all architectures
*/
#include <linux/config.h>
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include <asm/hardware.h>
-#include <asm/dec21285.h>
-
-#include "arch.h"
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
#if (TEXTADDR & 0xffff) != 0x8000
#error TEXTADDR must start at 0xXXXX8000
#endif
-#define SWAPPER_PGDIR_OFFSET 0x4000
#define K(a,b,c) ((a) << 24 | (b) << 12 | (c))
+/*
+ * swapper_pg_dir is the virtual address of the "init_task" page tables.
+ * SWAPPER_PGDIR_OFFSET is the offset from the start of memory of the
+ * page tables.
+ *
+ * Note that at the moment, we assume TEXTADDR is the virtual equivalent
+ * of start of memory + 0x8000
+ */
+#define SWAPPER_PGDIR_OFFSET 0x4000
.globl SYMBOL_NAME(swapper_pg_dir)
.equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x8000 + SWAPPER_PGDIR_OFFSET
@@ -50,7 +60,7 @@ ENTRY(_stext)
* ideal, but in this case, it should ONLY set r0 and r1 to the
* appropriate value.
*/
-#ifdef CONFIG_ARCH_NETWINDER
+#if defined(CONFIG_ARCH_NETWINDER) || defined(CONFIG_ARCH_INTEGRATOR)
/*
* Compatability cruft for old NetWinder NeTTroms. This
* code is currently scheduled for destruction in 2.5.xx
@@ -85,18 +95,23 @@ ENTRY(_stext)
mov r5, #0
movne pc, r0
- mov r1, #5 @ (will go in 2.5)
- mov r12, #2 << 24 @ scheduled for removal in 2.5.xx
+ mov r1, #MACH_TYPE_NETWINDER @ (will go in 2.5)
+ mov r12, #2 << 24 @ scheduled for removal in 2.5.xx
orr r12, r12, #5 << 12
+__entry:
#endif
-#ifdef CONFIG_ARCH_L7200
+#if defined(CONFIG_ARCH_L7200)
/*
* FIXME - No bootloader, so manually set 'r1' with our architecture number.
*/
- mov r1, #19
+ mov r1, #MACH_TYPE_L7200
+#elif defined(CONFIG_ARCH_INTEGRATOR)
+ mov r1, #MACH_TYPE_INTEGRATOR
#endif
-__entry: bl __lookup_processor_type
+ mov r0, #F_BIT | I_BIT | MODE_SVC @ make sure svc mode
+ msr cpsr_c, r0 @ and all irqs diabled
+ bl __lookup_processor_type
teq r10, #0 @ invalid processor?
moveq r0, #'p' @ yes, error 'p'
beq __error
@@ -140,7 +155,7 @@ __mmap_switched:
@ sp = stack pointer
str r12, [r2]
- mov fp, #0 @ Clear BSS
+ mov fp, #0 @ Clear BSS (and zero fp)
1: cmp r4, r5
strcc fp, [r4],#4
bcc 1b
@@ -182,17 +197,19 @@ __create_page_tables:
bne 1b
/*
* Create identity mapping for first MB of kernel.
- * map in four sections (4MB) for kernel.
- * these are marked cacheable and bufferable.
+ * This is marked cacheable and bufferable.
*
* The identity mapping will be removed by paging_init()
*/
- mov r3, #0x0c @ cacheable, bufferable
- orr r3, r3, r8 @ | pagetable flags
- add r3, r3, r5 @ + start of RAM
+ add r3, r8, r5 @ mmuflags + start of RAM
add r0, r4, r5, lsr #18
str r3, [r0] @ identity mapping
- add r0, r4, #(TEXTADDR - 0x8000) >> 18 @ start of kernel
+ /*
+ * Now setup the pagetables for our kernel direct
+ * mapped region. We round TEXTADDR down to the
+ * nearest megabyte boundary.
+ */
+ add r0, r4, #(TEXTADDR & 0xfff00000) >> 18 @ start of kernel
str r3, [r0], #4 @ PAGE_OFFSET + 0MB
add r3, r3, #1 << 20
str r3, [r0], #4 @ PAGE_OFFSET + 1MB
@@ -200,6 +217,9 @@ __create_page_tables:
str r3, [r0], #4 @ PAGE_OFFSET + 2MB
add r3, r3, #1 << 20
str r3, [r0], #4 @ PAGE_OFFSET + 3MB
+
+ bic r8, r8, #0x0c @ turn off cacheable
+ @ and bufferable bits
#ifdef CONFIG_DEBUG_LL
/*
* Map in IO space for serial debugging.
diff --git a/arch/arm/kernel/init_task.c b/arch/arm/kernel/init_task.c
index 1a379ee10..480c025fb 100644
--- a/arch/arm/kernel/init_task.c
+++ b/arch/arm/kernel/init_task.c
@@ -1,6 +1,10 @@
+/*
+ * linux/arch/arm/kernel/init_task.c
+ */
#include <linux/mm.h>
#include <linux/fs.h>
#include <linux/sched.h>
+#include <linux/init.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 69b72624d..3c6899264 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -4,16 +4,18 @@
* Copyright (C) 1992 Linus Torvalds
* Modifications for ARM processor Copyright (C) 1995-1998 Russell King.
*
- * This file contains the code used by various IRQ handling routines:
- * asking for different IRQ's should be done through these routines
- * instead of just grabbing them. Thus setups with different IRQ numbers
- * shouldn't result in any weird surprises, and installing new handlers
- * should be easier.
- */
-
-/*
- * IRQ's are in fact implemented a bit like signal handlers for the kernel.
- * Naturally it's not a 1:1 relation, but there are similarities.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains the code used by various IRQ handling routines:
+ * asking for different IRQ's should be done through these routines
+ * instead of just grabbing them. Thus setups with different IRQ numbers
+ * shouldn't result in any weird surprises, and installing new handlers
+ * should be easier.
+ *
+ * IRQ's are in fact implemented a bit like signal handlers for the kernel.
+ * Naturally it's not a 1:1 relation, but there are similarities.
*/
#include <linux/config.h>
#include <linux/ptrace.h>
diff --git a/arch/arm/kernel/isa.c b/arch/arm/kernel/isa.c
index 17696acb0..c9b9526d2 100644
--- a/arch/arm/kernel/isa.c
+++ b/arch/arm/kernel/isa.c
@@ -1,9 +1,16 @@
/*
- * arch/arm/kernel/isa.c
+ * linux/arch/arm/kernel/isa.c
*
- * ISA shared memory and I/O port support
+ * Copyright (C) 1999 Phil Blundell
*
- * Copyright (C) 1999 Phil Blundell
+ * ISA shared memory and I/O port support
+ */
+
+/*
+ * 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.
*/
/*
diff --git a/arch/arm/kernel/leds-ebsa110.c b/arch/arm/kernel/leds-ebsa110.c
index 7b2c886ef..17cb356e4 100644
--- a/arch/arm/kernel/leds-ebsa110.c
+++ b/arch/arm/kernel/leds-ebsa110.c
@@ -1,23 +1,32 @@
/*
- * arch/arm/kernel/leds-ebsa110.c
+ * linux/arch/arm/kernel/leds-ebsa110.c
*
- * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998 Russell King
*
- * EBSA-110 LED control routines. We use the led as follows:
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
- * - Red - toggles state every 50 timer interrupts
+ * EBSA-110 LED control routines. We use the led as follows:
+ *
+ * - Red - toggles state every 50 timer interrupts
*/
#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/init.h>
#include <asm/hardware.h>
#include <asm/leds.h>
#include <asm/system.h>
+#include <asm/mach-types.h>
+
+static spinlock_t leds_lock;
static void ebsa110_leds_event(led_event_t ledevt)
{
unsigned long flags;
- save_flags_cli(flags);
+ spin_lock_irqsave(&leds_lock, flags);
switch(ledevt) {
case led_timer:
@@ -28,9 +37,15 @@ static void ebsa110_leds_event(led_event_t ledevt)
break;
}
- restore_flags(flags);
+ spin_unlock_irqrestore(&leds_lock, flags);
}
-void (*leds_event)(led_event_t) = ebsa110_leds_event;
+static int __init leds_init(void)
+{
+ if (machine_is_ebsa110())
+ leds_event = ebsa110_leds_event;
+
+ return 0;
+}
-EXPORT_SYMBOL(leds_event);
+__initcall(leds_init);
diff --git a/arch/arm/kernel/leds-ftvpci.c b/arch/arm/kernel/leds-ftvpci.c
new file mode 100644
index 000000000..a1cf22dd8
--- /dev/null
+++ b/arch/arm/kernel/leds-ftvpci.c
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/arm/kernel/leds-ftvpci.c
+ *
+ * Copyright (C) 1999 FutureTV Labs Ltd
+ */
+
+#include <linux/module.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+static void ftvpci_leds_event(led_event_t ledevt)
+{
+ static int led_state = 0;
+
+ switch(ledevt) {
+ case led_timer:
+ led_state ^= 1;
+ raw_writeb(0x1a | led_state, INTCONT_BASE);
+ break;
+
+ default:
+ break;
+ }
+}
+
+void (*leds_event)(led_event_t) = ftvpci_leds_event;
+
+EXPORT_SYMBOL(leds_event);
diff --git a/arch/arm/kernel/oldlatches.c b/arch/arm/kernel/oldlatches.c
index 91b9e5d62..fe40c58b5 100644
--- a/arch/arm/kernel/oldlatches.c
+++ b/arch/arm/kernel/oldlatches.c
@@ -1,7 +1,14 @@
-/* Support for the latches on the old Archimedes which control the floppy,
- * hard disc and printer
+/*
+ * linux/arch/arm/kernel/oldlatches.c
*
- * (c) David Alan Gilbert 1995/1996,2000
+ * Copyright (C) David Alan Gilbert 1995/1996,2000
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Support for the latches on the old Archimedes which control the floppy,
+ * hard disc and printer
*/
#include <linux/module.h>
#include <linux/kernel.h>
diff --git a/arch/arm/kernel/plx90x0.c b/arch/arm/kernel/plx90x0.c
new file mode 100644
index 000000000..47ec9a8d2
--- /dev/null
+++ b/arch/arm/kernel/plx90x0.c
@@ -0,0 +1,198 @@
+/*
+ * Driver for PLX Technology PCI9000-series host bridge.
+ *
+ * Copyright (C) 1997, 1998, 1999, 2000 FutureTV Labs Ltd
+ */
+
+/*
+ * 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/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/ptrace.h>
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+/*
+ * Since the following functions are all very similar, the common parts
+ * are pulled out into these macros.
+ */
+
+#define PLX_CLEAR_CONFIG \
+ __raw_writel(0, PLX_BASE + 0xac); \
+ local_irq_restore(flags); }
+
+#define PLX_SET_CONFIG \
+ { unsigned long flags; \
+ local_irq_save(flags); \
+ __raw_writel((1<<31 | (dev->bus->number << 16) \
+ | (dev->devfn << 8) | (where & ~3) \
+ | ((dev->bus->number == 0)?0:1)), PLX_BASE + 0xac); \
+
+#define PLX_CONFIG_WRITE(size) \
+ PLX_SET_CONFIG \
+ __raw_write##size(value, PCIO_BASE + (where & 3)); \
+ if (__raw_readw(PLX_BASE + 0x6) & 0x2000) \
+ __raw_writew(0x2000, PLX_BASE + 0x6); \
+ PLX_CLEAR_CONFIG \
+ return PCIBIOS_SUCCESSFUL;
+
+#define PLX_CONFIG_READ(size) \
+ PLX_SET_CONFIG \
+ *value = __raw_read##size(PCIO_BASE + (where & 3)); \
+ if (__raw_readw(PLX_BASE + 0x6) & 0x2000) { \
+ __raw_writew(0x2000, PLX_BASE + 0x6); \
+ *value = 0xffffffffUL; \
+ } \
+ PLX_CLEAR_CONFIG \
+ return PCIBIOS_SUCCESSFUL;
+
+/* Configuration space access routines */
+
+static int
+plx90x0_read_config_byte (struct pci_dev *dev,
+ int where, u8 *value)
+{
+ PLX_CONFIG_READ(b)
+}
+
+static int
+plx90x0_read_config_word (struct pci_dev *dev,
+ int where, u16 *value)
+{
+ PLX_CONFIG_READ(w)
+}
+
+static int
+plx90x0_read_config_dword (struct pci_dev *dev,
+ int where, u32 *value)
+{
+ PLX_CONFIG_READ(l)
+}
+
+static int
+plx90x0_write_config_byte (struct pci_dev *dev,
+ int where, u8 value)
+{
+ PLX_CONFIG_WRITE(b)
+}
+
+static int
+plx90x0_write_config_word (struct pci_dev *dev,
+ int where, u16 value)
+{
+ PLX_CONFIG_WRITE(w)
+}
+
+static int
+plx90x0_write_config_dword (struct pci_dev *dev,
+ int where, u32 value)
+{
+ PLX_CONFIG_WRITE(l)
+}
+
+static void
+plx_syserr_handler(int irq, void *handle, struct pt_regs *regs)
+{
+ printk("PLX90x0: machine check %04x (pc=%08lx)\n",
+ readw(PLX_BASE + 6), regs->ARM_pc);
+ __raw_writew(0xf000, PLX_BASE + 6);
+}
+
+static struct pci_ops
+plx90x0_ops =
+{
+ plx90x0_read_config_byte,
+ plx90x0_read_config_word,
+ plx90x0_read_config_dword,
+ plx90x0_write_config_byte,
+ plx90x0_write_config_word,
+ plx90x0_write_config_dword,
+};
+
+/*
+ * Initialise the PCI system.
+ */
+
+void __init
+plx90x0_init(struct arm_sysdata *sysdata)
+{
+ static const unsigned long int base = PLX_BASE;
+ char *what;
+ unsigned long bar = (unsigned long)virt_to_bus((void *)PAGE_OFFSET);
+ unsigned int pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
+
+ /* Have a sniff around and see which PLX device is present. */
+ unsigned long id = __raw_readl(base + 0xf0);
+
+#if 0
+ /* This check was a good idea, but can fail. The PLX9060 puts no
+ default value in these registers unless NB# is asserted (which it
+ isn't on these cards). */
+ if ((id & 0xffff) != PCI_VENDOR_ID_PLX)
+ return; /* Nothing found */
+#endif
+
+ /* Found one - now work out what it is. */
+ switch (id >> 16) {
+ case 0: /* PCI_DEVICE_ID_PLX_9060 */
+ what = "PCI9060";
+ break;
+ case PCI_DEVICE_ID_PLX_9060ES:
+ what = "PCI9060ES";
+ break;
+ case PCI_DEVICE_ID_PLX_9060SD:
+ what = "PCI9060SD"; /* uhuhh.. */
+ break;
+ case PCI_DEVICE_ID_PLX_9080:
+ what = "PCI9080";
+ break;
+ default:
+ printk("PCI: Unknown PLX device %04lx found -- ignored.\n",
+ id >> 16);
+ return;
+ }
+
+ printk("PCI: PLX Technology %s host bridge found.\n", what);
+
+ /* Now set it up for both master and slave accesses. */
+ __raw_writel(0xffff0147, base + 0x4);
+ __raw_writeb(32, base + 0xd);
+ __raw_writel(0x8 | bar, base + 0x18);
+ __raw_writel(0xf8000008, base + 0x80);
+ __raw_writel(0x40000001, base + 0x84);
+ __raw_writel(0, base + 0x88);
+ __raw_writel(0, base + 0x8c);
+ __raw_writel(0x11, base + 0x94);
+ __raw_writel(0xC3 + (4 << 28)
+ + (8 << 11) + (1 << 10)
+ + (1 << 24), base + 0x98);
+ __raw_writel(0xC0000000, base + 0x9c);
+ __raw_writel(PLX_MEM_START, base + 0xa0);
+ __raw_writel(PLX_IO_START, base + 0xa4);
+ __raw_writel(0x3, base + 0xa8);
+ __raw_writel(0, base + 0xac);
+ __raw_writel(0x10001, base + 0xe8);
+ __raw_writel(0x8000767e, base + 0xec);
+
+ request_irq(IRQ_SYSERR, plx_syserr_handler, 0,
+ "system error", NULL);
+
+ pci_scan_bus(0, &plx90x0_ops, sysdata);
+
+ pci_cmd |= sysdata->bus[0].features;
+
+ printk("PCI: Fast back to back transfers %sabled\n",
+ (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ?
+ "en" : "dis");
+}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 478810936..9f50ab6fd 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -3,8 +3,11 @@
*
* Copyright (C) 1996-2000 Russell King - Converted to ARM.
* Origional Copyright (C) 1995 Linus Torvalds
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-
#include <stdarg.h>
#include <linux/config.h>
@@ -173,10 +176,11 @@ void show_regs(struct pt_regs * regs)
flags & CC_Z_BIT ? 'Z' : 'z',
flags & CC_C_BIT ? 'C' : 'c',
flags & CC_V_BIT ? 'V' : 'v');
- printk(" IRQs %s FIQs %s Mode %s Segment %s\n",
+ printk(" IRQs %s FIQs %s Mode %s%s Segment %s\n",
interrupts_enabled(regs) ? "on" : "off",
fast_interrupts_enabled(regs) ? "on" : "off",
processor_modes[processor_mode(regs)],
+ thumb_mode(regs) ? " (T)" : "",
get_fs() == get_ds() ? "kernel" : "user");
#if defined(CONFIG_CPU_32)
{
@@ -280,8 +284,8 @@ void exit_thread(void)
void flush_thread(void)
{
- memset(&current->thread.debug, 0, sizeof(current->thread.debug));
- memset(&current->thread.fpstate, 0, sizeof(current->thread.fpstate));
+ memset(&current->thread.debug, 0, sizeof(struct debug_info));
+ memset(&current->thread.fpstate, 0, sizeof(union fp_state));
current->used_math = 0;
current->flags &= ~PF_USEDFPU;
}
@@ -291,6 +295,7 @@ void release_thread(struct task_struct *dead_task)
}
int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
+ unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
@@ -326,19 +331,21 @@ int dump_fpu (struct pt_regs *regs, struct user_fp *fp)
*/
void dump_thread(struct pt_regs * regs, struct user * dump)
{
+ struct task_struct *tsk = current;
+
dump->magic = CMAGIC;
- dump->start_code = current->mm->start_code;
+ dump->start_code = tsk->mm->start_code;
dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
- dump->u_tsize = (current->mm->end_code - current->mm->start_code) >> PAGE_SHIFT;
- dump->u_dsize = (current->mm->brk - current->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
+ dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
+ dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
dump->u_ssize = 0;
- dump->u_debugreg[0] = current->thread.debug.bp[0].address;
- dump->u_debugreg[1] = current->thread.debug.bp[1].address;
- dump->u_debugreg[2] = current->thread.debug.bp[0].insn;
- dump->u_debugreg[3] = current->thread.debug.bp[1].insn;
- dump->u_debugreg[4] = current->thread.debug.nsaved;
+ dump->u_debugreg[0] = tsk->thread.debug.bp[0].address;
+ dump->u_debugreg[1] = tsk->thread.debug.bp[1].address;
+ dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn;
+ dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn;
+ dump->u_debugreg[4] = tsk->thread.debug.nsaved;
if (dump->start_stack < 0x04000000)
dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index e45e03fcb..2d20c9271 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -1,8 +1,14 @@
-/* ptrace.c */
-/* By Ross Biro 1/23/92 */
-/* edited by Linus Torvalds */
-/* edited for ARM by Russell King */
-
+/*
+ * linux/arch/arm/kernel/ptrace.c
+ *
+ * By Ross Biro 1/23/92
+ * edited by Linus Torvalds
+ * ARM modifications Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -61,9 +67,18 @@ static inline long get_stack_long(struct task_struct *task, int offset)
static inline int
put_stack_long(struct task_struct *task, int offset, long data)
{
- get_user_regs(task)->uregs[offset] = data;
+ struct pt_regs newregs, *regs = get_user_regs(task);
+ int ret = -EINVAL;
+
+ newregs = *regs;
+ newregs.uregs[offset] = data;
+
+ if (valid_user_regs(&newregs)) {
+ regs->uregs[offset] = data;
+ ret = 0;
+ }
- return 0;
+ return ret;
}
static inline int
@@ -406,7 +421,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
break;
- if (addr < sizeof (struct pt_regs))
+ if (addr < sizeof(struct pt_regs))
ret = put_stack_long(child, (int)addr >> 2, data);
break;
@@ -499,12 +514,19 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat
* Set all gp regs in the child.
*/
case PTRACE_SETREGS: {
- struct pt_regs *regs = get_user_regs(child);
-
- ret = 0;
- if (copy_from_user(regs, (void *)data,
- sizeof(struct pt_regs)))
- ret = -EFAULT;
+ struct pt_regs newregs;
+
+ ret = -EFAULT;
+ if (copy_from_user(&newregs, (void *)data,
+ sizeof(struct pt_regs)) == 0) {
+ struct pt_regs *regs = get_user_regs(child);
+
+ ret = -EINVAL;
+ if (valid_user_regs(&newregs)) {
+ *regs = newregs;
+ ret = 0;
+ }
+ }
break;
}
diff --git a/arch/arm/kernel/ptrace.h b/arch/arm/kernel/ptrace.h
index feae0acd8..ec1789aa4 100644
--- a/arch/arm/kernel/ptrace.h
+++ b/arch/arm/kernel/ptrace.h
@@ -1,3 +1,12 @@
+/*
+ * linux/arch/arm/kernel/ptrace.h
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
extern void __ptrace_cancel_bpt(struct task_struct *);
extern int ptrace_set_bpt(struct task_struct *);
diff --git a/arch/arm/kernel/semaphore.c b/arch/arm/kernel/semaphore.c
index d29f8cf1f..e01a6417e 100644
--- a/arch/arm/kernel/semaphore.c
+++ b/arch/arm/kernel/semaphore.c
@@ -1,11 +1,15 @@
/*
- * ARM semaphore implementation, taken from
+ * ARM semaphore implementation, taken from
*
- * i386 semaphore implementation.
+ * i386 semaphore implementation.
*
- * (C) Copyright 1999 Linus Torvalds
+ * (C) Copyright 1999 Linus Torvalds
*
- * Modified for ARM by Russell King
+ * Modified for ARM by Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/sched.h>
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index c20ffab21..9a917b171 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -2,6 +2,10 @@
* linux/arch/arm/kernel/setup.c
*
* Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/kernel.h>
@@ -21,7 +25,7 @@
#include <asm/setup.h>
#include <asm/mach-types.h>
-#include "arch.h"
+#include <asm/mach/arch.h>
#ifndef MEM_SIZE
#define MEM_SIZE (16*1024*1024)
@@ -31,7 +35,7 @@
#define CONFIG_CMDLINE ""
#endif
-extern void paging_init(struct meminfo *);
+extern void paging_init(struct meminfo *, struct machine_desc *desc);
extern void bootmem_init(struct meminfo *);
extern void reboot_setup(char *str);
extern void disable_hlt(void);
@@ -163,7 +167,7 @@ static struct machine_desc * __init setup_architecture(unsigned int nr)
printk("Architecture: %s\n", list->name);
if (compat)
- printk(KERN_WARNING "Using compatability code "
+ printk(KERN_WARNING "Using compatibility code "
"scheduled for removal in v%d.%d.%d\n",
compat >> 24, (compat >> 12) & 0x3ff,
compat & 0x3ff);
@@ -378,7 +382,7 @@ void __init setup_arch(char **cmdline_p)
saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
parse_cmdline(&meminfo, cmdline_p, from);
bootmem_init(&meminfo);
- paging_init(&meminfo);
+ paging_init(&meminfo, mdesc);
request_standard_resources(&meminfo, mdesc);
#ifdef CONFIG_VT
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 5c2e240b7..1af2abd84 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -2,8 +2,11 @@
* linux/arch/arm/kernel/signal.c
*
* Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/mm.h>
@@ -587,7 +590,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
/* FALLTHRU */
default:
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c
index 6d49e1427..36bbf3ac8 100644
--- a/arch/arm/kernel/sys_arm.c
+++ b/arch/arm/kernel/sys_arm.c
@@ -1,14 +1,17 @@
/*
- * linux/arch/arm/kernel/sys_arm.c
+ * linux/arch/arm/kernel/sys_arm.c
*
- * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c
- * Copyright (C) 1995, 1996 Russell King.
- *
- * This file contains various random system calls that
- * have a non-standard calling sequence on the Linux/arm
- * platform.
+ * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c
+ * Copyright (C) 1995, 1996 Russell King.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This file contains various random system calls that
+ * have a non-standard calling sequence on the Linux/arm
+ * platform.
*/
-
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/malloc.h>
@@ -203,7 +206,7 @@ asmlinkage int sys_ipc (uint call, int first, int second, int third, void *ptr,
*/
asmlinkage int sys_fork(struct pt_regs *regs)
{
- return do_fork(SIGCHLD, regs->ARM_sp, regs);
+ return do_fork(SIGCHLD, regs->ARM_sp, regs, 0);
}
/* Clone a task - this clones the calling program thread.
@@ -213,12 +216,12 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, struct
{
if (!newsp)
newsp = regs->ARM_sp;
- return do_fork(clone_flags, newsp, regs);
+ return do_fork(clone_flags, newsp, regs, 0);
}
asmlinkage int sys_vfork(struct pt_regs *regs)
{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs);
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->ARM_sp, regs, 0);
}
/* sys_execve() executes a new program.
diff --git a/arch/arm/kernel/time-acorn.c b/arch/arm/kernel/time-acorn.c
index 8a7d964fc..05de01e85 100644
--- a/arch/arm/kernel/time-acorn.c
+++ b/arch/arm/kernel/time-acorn.c
@@ -1,12 +1,16 @@
/*
- * linux/arch/arm/kernel/time-acorn.c
+ * linux/arch/arm/kernel/time-acorn.c
*
- * Copyright (c) 1996-2000 Russell King.
+ * Copyright (c) 1996-2000 Russell King.
*
- * Changelog:
- * 24-Sep-1996 RMK Created
- * 10-Oct-1996 RMK Brought up to date with arch-sa110eval
- * 04-Dec-1997 RMK Updated for new arch/arm/time.c
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 24-Sep-1996 RMK Created
+ * 10-Oct-1996 RMK Brought up to date with arch-sa110eval
+ * 04-Dec-1997 RMK Updated for new arch/arm/time.c
*/
#include <linux/sched.h>
#include <linux/interrupt.h>
@@ -14,8 +18,8 @@
#include <asm/hardware.h>
#include <asm/io.h>
-#include <asm/ioc.h>
#include <asm/irq.h>
+#include <asm/hardware/ioc.h>
extern unsigned long (*gettimeoffset)(void);
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index da437639f..926cdff2f 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -4,15 +4,20 @@
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
* Modifications for ARM (C) 1994, 1995, 1996,1997 Russell King
*
- * This file contains the ARM-specific time handling details:
- * reading the RTC at bootup, etc...
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
- * 1994-07-02 Alan Modra
- * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
- * 1998-12-20 Updated NTP code according to technical memorandum Jan '96
- * "A Kernel Model for Precision Timekeeping" by Dave Mills
+ * This file contains the ARM-specific time handling details:
+ * reading the RTC at bootup, etc...
+ *
+ * 1994-07-02 Alan Modra
+ * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
+ * 1998-12-20 Updated NTP code according to technical memorandum Jan '96
+ * "A Kernel Model for Precision Timekeeping" by Dave Mills
*/
#include <linux/config.h>
+#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/interrupt.h>
@@ -64,37 +69,6 @@ static unsigned long dummy_gettimeoffset(void)
*/
unsigned long (*gettimeoffset)(void) = dummy_gettimeoffset;
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-unsigned long
-mktime(unsigned int year, unsigned int mon, unsigned int day,
- unsigned int hour, unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
/*
* Handle kernel profile stuff...
*/
@@ -151,6 +125,16 @@ static inline void do_set_rtc(void)
#include <asm/leds.h>
+static void dummy_leds_event(led_event_t evt)
+{
+}
+
+void (*leds_event)(led_event_t) = dummy_leds_event;
+
+#ifdef CONFIG_MODULES
+EXPORT_SYMBOL(leds_event);
+#endif
+
static void do_leds(void)
{
#ifdef CONFIG_LEDS_CPU
@@ -234,7 +218,7 @@ void do_settimeofday(struct timeval *tv)
}
static struct irqaction timer_irq = {
- NULL, 0, 0, "timer", NULL, NULL
+ name: "timer",
};
/*
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 197107138..8e8e3675f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -3,12 +3,14 @@
*
* Copyright (C) 1995, 1996 Russell King
* Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds
- */
-
-/*
- * 'traps.c' handles hardware exceptions after we have saved some state in
- * 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably
- * kill the offending process.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 'traps.c' handles hardware exceptions after we have saved some state in
+ * 'linux/arch/arm/lib/traps.S'. Mostly a debugging aid, but will probably
+ * kill the offending process.
*/
#include <linux/config.h>
#include <linux/types.h>
@@ -314,7 +316,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
case 2: /* sys_cacheflush */
#ifdef CONFIG_CPU_32
/* r0 = start, r1 = end, r2 = flags */
- cpu_flush_cache_area(regs->ARM_r0, regs->ARM_r1, 1);
+ cpu_cache_clean_invalidate_range(regs->ARM_r0, regs->ARM_r1, 1);
#endif
break;
diff --git a/arch/arm/kernel/via82c505.c b/arch/arm/kernel/via82c505.c
new file mode 100644
index 000000000..42a2bb448
--- /dev/null
+++ b/arch/arm/kernel/via82c505.c
@@ -0,0 +1,186 @@
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/ptrace.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+
+#include <asm/mach/pci.h>
+
+#define MAX_SLOTS 7
+
+#define CONFIG_CMD(dev, where) (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))
+
+static int
+via82c505_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+ outl(CONFIG_CMD(dev,where),0xCF8);
+ *value=inb(0xCFC + (where&3));
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+via82c505_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+ outl(CONFIG_CMD(dev,where),0xCF8);
+ *value=inw(0xCFC + (where&2));
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+via82c505_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+ outl(CONFIG_CMD(dev,where),0xCF8);
+ *value=inl(0xCFC);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+via82c505_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+ outl(CONFIG_CMD(dev,where),0xCF8);
+ outb(value, 0xCFC + (where&3));
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+via82c505_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+ outl(CONFIG_CMD(dev,where),0xCF8);
+ outw(value, 0xCFC + (where&2));
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+via82c505_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ outl(CONFIG_CMD(dev,where),0xCF8);
+ outl(value, 0xCFC);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops via82c505_ops = {
+ via82c505_read_config_byte,
+ via82c505_read_config_word,
+ via82c505_read_config_dword,
+ via82c505_write_config_byte,
+ via82c505_write_config_word,
+ via82c505_write_config_dword,
+};
+
+#ifdef CONFIG_ARCH_SHARK
+
+static char size_wanted = 0;
+
+static int
+dummy_read_config_byte(struct pci_dev *dev, int where, u8 *value)
+{
+ *value=0;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dummy_read_config_word(struct pci_dev *dev, int where, u16 *value)
+{
+ *value=0;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dummy_read_config_dword(struct pci_dev *dev, int where, u32 *value)
+{
+ if (dev->devfn != 0) *value = 0;
+ else
+ switch(where) {
+ case PCI_VENDOR_ID:
+ *value = PCI_VENDOR_ID_INTERG | PCI_DEVICE_ID_INTERG_2010 << 16;
+ break;
+ case PCI_CLASS_REVISION:
+ *value = PCI_CLASS_DISPLAY_VGA << 16;
+ break;
+ case PCI_BASE_ADDRESS_0:
+ if (size_wanted) {
+ /* 0x00900000 bytes long */
+ *value = 0xff700000;
+ size_wanted = 0;
+ } else {
+ *value = FB_START;
+ }
+ break;
+ case PCI_INTERRUPT_LINE:
+ *value = 6;
+ break;
+ default:
+ *value=0;
+ }
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dummy_write_config_byte(struct pci_dev *dev, int where, u8 value)
+{
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dummy_write_config_word(struct pci_dev *dev, int where, u16 value)
+{
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int
+dummy_write_config_dword(struct pci_dev *dev, int where, u32 value)
+{
+ if ((dev->devfn == 0) && (where == PCI_BASE_ADDRESS_0) && (value == 0xffffffff))
+ size_wanted = 1;
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops dummy_ops = {
+ dummy_read_config_byte,
+ dummy_read_config_word,
+ dummy_read_config_dword,
+ dummy_write_config_byte,
+ dummy_write_config_word,
+ dummy_write_config_dword,
+};
+#endif
+
+void __init via82c505_init(struct arm_pci_sysdata *sysdata)
+{
+ unsigned int pci_cmd = PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
+ PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
+ struct pci_dev *dev;
+ struct pci_bus *bus;
+
+ printk(KERN_DEBUG "PCI: VIA 82c505\n");
+ request_region(0xA8,2,"via config");
+ request_region(0xCF8,8,"pci config");
+
+ /* Enable compatible Mode */
+ outb(0x96,0xA8);
+ outb(0x18,0xA9);
+ outb(0x93,0xA8);
+ outb(0xd0,0xA9);
+
+ pci_scan_bus(0, &via82c505_ops, sysdata);
+
+ pci_cmd |= sysdata->bus[0].features;
+
+ printk("PCI: Fast back to back transfers %sabled\n",
+ (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ? "en" : "dis");
+
+#ifdef CONFIG_ARCH_SHARK
+ /*
+ * Initialize a fake pci-bus number 1 for the CyberPro
+ * on the vlbus
+ */
+ bus = pci_scan_bus(1, &dummy_ops, sysdata);
+#endif
+}
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index cfa371d5e..b7e29ca55 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -9,9 +9,9 @@ USE_STANDARD_AS_RULE := true
L_TARGET := lib.a
L_OBJS := changebit.o csumipv6.o csumpartial.o csumpartialcopy.o \
csumpartialcopyuser.o clearbit.o copy_page.o findbit.o \
- memchr.o memcpy.o memset.o memzero.o setbit.o strchr.o \
- strrchr.o testchangebit.o testclearbit.o testsetbit.o \
- uaccess.o
+ memchr.o memcpy.o memset.o memzero.o setbit.o \
+ strncpy_from_user.o strnlen_user.o strchr.o strrchr.o \
+ testchangebit.o testclearbit.o testsetbit.o uaccess.o
O_TARGET := lib.o
O_OBJS := backtrace.o delay.o
@@ -25,6 +25,7 @@ L_OBJS_l7200 := io-acorn.o
L_OBJS_nexuspci := io-footbridge.o
L_OBJS_sa1100 := io-footbridge.o
L_OBJS_shark := io-shark.o
+L_OBJS_integrator := io-shark.o
ifeq ($(PROCESSOR),armo)
L_OBJS += uaccess-armo.o
diff --git a/arch/arm/lib/backtrace.S b/arch/arm/lib/backtrace.S
index e871f2615..5fe3c066e 100644
--- a/arch/arm/lib/backtrace.S
+++ b/arch/arm/lib/backtrace.S
@@ -1,7 +1,11 @@
/*
- * linux/arch/arm/lib/backtrace.S
+ * linux/arch/arm/lib/backtrace.S
*
- * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/linkage.h>
diff --git a/arch/arm/lib/changebit.S b/arch/arm/lib/changebit.S
index adb847670..6feb62783 100644
--- a/arch/arm/lib/changebit.S
+++ b/arch/arm/lib/changebit.S
@@ -1,9 +1,12 @@
/*
- * linux/arch/arm/lib/changebit.S
+ * linux/arch/arm/lib/changebit.S
*
- * Copyright (C) 1995-1996 Russell King
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
diff --git a/arch/arm/lib/clearbit.S b/arch/arm/lib/clearbit.S
index d63947520..225aa6fb9 100644
--- a/arch/arm/lib/clearbit.S
+++ b/arch/arm/lib/clearbit.S
@@ -1,9 +1,12 @@
/*
- * linux/arch/arm/lib/clearbit.S
+ * linux/arch/arm/lib/clearbit.S
*
- * Copyright (C) 1995-1996 Russell King
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S
index 16c43268a..d7cf6fe45 100644
--- a/arch/arm/lib/copy_page.S
+++ b/arch/arm/lib/copy_page.S
@@ -1,35 +1,38 @@
/*
- * linux/arch/arm/lib/copypage.S
+ * linux/arch/arm/lib/copypage.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-1999 Russell King
*
- * ASM optimised string functions
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
+ * ASM optimised string functions
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#include "constants.h"
- .text
+ .text
+ .align 5
/*
* StrongARM optimised copy_page routine
- * now 1.72bytes/cycle, was 1.60 bytes/cycle
- * (50MHz bus -> 86MB/s)
+ * now 1.78bytes/cycle, was 1.60 bytes/cycle (50MHz bus -> 89MB/s)
+ * Note that we probably achieve closer to the 100MB/s target with
+ * the core clock switching.
*/
-
ENTRY(copy_page)
stmfd sp!, {r4, lr} @ 2
mov r2, #PAGE_SZ/64 @ 1
-1: ldmia r1!, {r3, r4, ip, lr} @ 4
- subs r2, r2, #1 @ 1
- stmia r0!, {r3, r4, ip, lr} @ 4
ldmia r1!, {r3, r4, ip, lr} @ 4+1
- stmia r0!, {r3, r4, ip, lr} @ 4
+1: stmia r0!, {r3, r4, ip, lr} @ 4
ldmia r1!, {r3, r4, ip, lr} @ 4+1
stmia r0!, {r3, r4, ip, lr} @ 4
ldmia r1!, {r3, r4, ip, lr} @ 4+1
stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmia r1!, {r3, r4, ip, lr} @ 4
+ subs r2, r2, #1 @ 1
+ stmia r0!, {r3, r4, ip, lr} @ 4
+ ldmneia r1!, {r3, r4, ip, lr} @ 4
bne 1b @ 1
LOADREGS(fd, sp!, {r4, pc}) @ 3
-
-
diff --git a/arch/arm/lib/csumipv6.S b/arch/arm/lib/csumipv6.S
index 76e7d26d8..7065a20ee 100644
--- a/arch/arm/lib/csumipv6.S
+++ b/arch/arm/lib/csumipv6.S
@@ -1,7 +1,11 @@
/*
- * linux/arch/arm/lib/csumipv6.S
+ * linux/arch/arm/lib/csumipv6.S
*
- * Copyright (C) 1995-1998 Russell King
+ * Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
diff --git a/arch/arm/lib/csumpartial.S b/arch/arm/lib/csumpartial.S
index 2406dfb38..dea2c389c 100644
--- a/arch/arm/lib/csumpartial.S
+++ b/arch/arm/lib/csumpartial.S
@@ -1,7 +1,11 @@
/*
- * linux/arch/arm/lib/csumpartial.S
+ * linux/arch/arm/lib/csumpartial.S
*
- * Copyright (C) 1995-1998 Russell King
+ * Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
diff --git a/arch/arm/lib/csumpartialcopy.S b/arch/arm/lib/csumpartialcopy.S
index fc52662a8..005bc9332 100644
--- a/arch/arm/lib/csumpartialcopy.S
+++ b/arch/arm/lib/csumpartialcopy.S
@@ -1,7 +1,11 @@
/*
- * linux/arch/arm/lib/csumpartialcopy.S
+ * linux/arch/arm/lib/csumpartialcopy.S
*
- * Copyright (C) 1995-1998 Russell King
+ * Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
diff --git a/arch/arm/lib/csumpartialcopyuser.S b/arch/arm/lib/csumpartialcopyuser.S
index cde500440..3799ccaec 100644
--- a/arch/arm/lib/csumpartialcopyuser.S
+++ b/arch/arm/lib/csumpartialcopyuser.S
@@ -1,7 +1,11 @@
/*
- * linux/arch/arm/lib/csumpartialcopyuser.S
+ * linux/arch/arm/lib/csumpartialcopyuser.S
*
- * Copyright (C) 1995-1998 Russell King
+ * Copyright (C) 1995-1998 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/linkage.h>
@@ -396,6 +400,12 @@ ENTRY(csum_partial_copy_from_user)
mov r4, r4, lsr #8
b .exit
+/*
+ * FIXME: minor buglet here
+ * We don't return the checksum for the data present in the buffer. To do
+ * so properly, we would have to add in whatever registers were loaded before
+ * the fault, which, with the current asm above is not predictable.
+ */
#if defined(CONFIG_CPU_32)
.section .fixup,"ax"
#endif
diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay.S
index 72dab5a95..caf8ec1dc 100644
--- a/arch/arm/lib/delay.S
+++ b/arch/arm/lib/delay.S
@@ -1,7 +1,11 @@
/*
- * linux/arch/arm/lib/delay.S
+ * linux/arch/arm/lib/delay.S
*
- * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
@@ -40,4 +44,3 @@ ENTRY(__delay)
subs r0, r0, #1
bcs SYMBOL_NAME(__delay)
RETINSTR(mov,pc,lr)
-
diff --git a/arch/arm/lib/findbit.S b/arch/arm/lib/findbit.S
index 5b570f199..279230292 100644
--- a/arch/arm/lib/findbit.S
+++ b/arch/arm/lib/findbit.S
@@ -1,9 +1,12 @@
/*
- * linux/arch/arm/lib/findbit.S
+ * linux/arch/arm/lib/findbit.S
*
- * Copyright (C) 1995-2000 Russell King
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
diff --git a/arch/arm/lib/floppydma.S b/arch/arm/lib/floppydma.S
index 778d3e574..9073e54ef 100644
--- a/arch/arm/lib/floppydma.S
+++ b/arch/arm/lib/floppydma.S
@@ -1,7 +1,11 @@
/*
- * linux/arch/arm/lib/floppydma.S
+ * linux/arch/arm/lib/floppydma.S
*
- * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
diff --git a/arch/arm/lib/getconsdata.c b/arch/arm/lib/getconsdata.c
index aa5efa1cd..ee8040be7 100644
--- a/arch/arm/lib/getconsdata.c
+++ b/arch/arm/lib/getconsdata.c
@@ -1,7 +1,11 @@
/*
- * linux/arch/arm/lib/getconsdata.c
+ * linux/arch/arm/lib/getconsdata.c
*
- * Copyright (C) 1995-2000 Russell King
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/sched.h>
diff --git a/arch/arm/lib/io-acorn.S b/arch/arm/lib/io-acorn.S
index bf2dd6333..bc40496ac 100644
--- a/arch/arm/lib/io-acorn.S
+++ b/arch/arm/lib/io-acorn.S
@@ -1,7 +1,11 @@
/*
- * linux/arch/arm/lib/io.S
+ * linux/arch/arm/lib/io-acorn.S
*
- * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/config.h> /* for CONFIG_CPU_nn */
#include <linux/linkage.h>
diff --git a/arch/arm/lib/io-ebsa110.S b/arch/arm/lib/io-ebsa110.S
index b29276ff7..b1c507886 100644
--- a/arch/arm/lib/io-ebsa110.S
+++ b/arch/arm/lib/io-ebsa110.S
@@ -1,7 +1,11 @@
/*
- * linux/arch/arm/lib/io-ebsa.S
+ * linux/arch/arm/lib/io-ebsa.S
*
- * Copyright (C) 1995, 1996 Russell King
+ * Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
diff --git a/arch/arm/lib/io-shark.c b/arch/arm/lib/io-shark.c
index 41595bc6f..b68faa700 100644
--- a/arch/arm/lib/io-shark.c
+++ b/arch/arm/lib/io-shark.c
@@ -1,11 +1,15 @@
/*
- * linux/arch/arm/lib/io-shark.c
+ * linux/arch/arm/lib/io-shark.c
*
- * by Alexander.Schulz@stud.uni-karlsruhe.de
+ * by Alexander.Schulz@stud.uni-karlsruhe.de
*
* derived from:
* linux/arch/arm/lib/io-ebsa.S
* Copyright (C) 1995, 1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/kernel.h>
diff --git a/arch/arm/lib/memchr.S b/arch/arm/lib/memchr.S
index d52abe57f..4eed74a7e 100644
--- a/arch/arm/lib/memchr.S
+++ b/arch/arm/lib/memchr.S
@@ -1,24 +1,25 @@
/*
- * linux/arch/arm/lib/memchr.S
+ * linux/arch/arm/lib/memchr.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-2000 Russell King
*
- * ASM optimised string functions
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
+ * ASM optimised string functions
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include "constants.h"
- .text
+ .text
+ .align 5
ENTRY(memchr)
- str lr, [sp, #-4]!
-1: ldrb r3, [r0], #1
- teq r3, r1
- beq 2f
- subs r2, r2, #1
- bpl 1b
-2: movne r0, #0
- subeq r0, r0, #1
- LOADREGS(fd, sp!, {pc})
-
+1: ldrb r3, [r0], #1
+ teq r3, r1
+ beq 2f
+ subs r2, r2, #1
+ bpl 1b
+2: movne r0, #0
+ subeq r0, r0, #1
+ RETINSTR(mov,pc,lr)
diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S
index ae5307d4b..e652b5276 100644
--- a/arch/arm/lib/memcpy.S
+++ b/arch/arm/lib/memcpy.S
@@ -1,10 +1,13 @@
/*
- * linux/arch/arm/lib/memcpy.S
+ * linux/arch/arm/lib/memcpy.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-1999 Russell King
*
- * ASM optimised string functions
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
+ * ASM optimised string functions
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
@@ -314,5 +317,3 @@ ENTRY(memmove)
b 24b
.align
-
-
diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S
index b7202e867..a1795f599 100644
--- a/arch/arm/lib/memset.S
+++ b/arch/arm/lib/memset.S
@@ -1,88 +1,80 @@
/*
- * linux/arch/arm/lib/memset.S
+ * linux/arch/arm/lib/memset.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-2000 Russell King
*
- * ASM optimised string functions
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
+ * ASM optimised string functions
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include "constants.h"
- .text
- .align 5
-ENTRY(memset)
- mov r3, r0
- cmp r2, #16
- blt 6f
- ands ip, r3, #3
- beq 1f
- cmp ip, #2
- strltb r1, [r3], #1 @ Align destination
- strleb r1, [r3], #1
- strb r1, [r3], #1
- rsb ip, ip, #4
- sub r2, r2, ip
-1: orr r1, r1, r1, lsl #8
- orr r1, r1, r1, lsl #16
- cmp r2, #256
- blt 4f
- stmfd sp!, {r4, r5, lr}
- mov r4, r1
- mov r5, r1
- mov lr, r1
- mov ip, r2, lsr #6
- sub r2, r2, ip, lsl #6
-2: stmia r3!, {r1, r4, r5, lr} @ 64 bytes at a time.
- stmia r3!, {r1, r4, r5, lr}
- stmia r3!, {r1, r4, r5, lr}
- stmia r3!, {r1, r4, r5, lr}
- subs ip, ip, #1
- bne 2b
- teq r2, #0
- LOADREGS(eqfd, sp!, {r4, r5, pc}) @ Now <64 bytes to go.
- tst r2, #32
- stmneia r3!, {r1, r4, r5, lr}
- stmneia r3!, {r1, r4, r5, lr}
- tst r2, #16
- stmneia r3!, {r1, r4, r5, lr}
- ldmia sp!, {r4, r5}
-3: tst r2, #8
- stmneia r3!, {r1, lr}
- tst r2, #4
- strne r1, [r3], #4
- tst r2, #2
- strneb r1, [r3], #1
- strneb r1, [r3], #1
- tst r2, #1
- strneb r1, [r3], #1
- LOADREGS(fd, sp!, {pc})
+ .text
+ .align 5
+ .word 0
-4: movs ip, r2, lsr #3
- beq 3b
- sub r2, r2, ip, lsl #3
- str lr, [sp, #-4]!
- mov lr, r1
- subs ip, ip, #4
-5: stmgeia r3!, {r1, lr}
- stmgeia r3!, {r1, lr}
- stmgeia r3!, {r1, lr}
- stmgeia r3!, {r1, lr}
- subges ip, ip, #4
- bge 5b
- tst ip, #2
- stmneia r3!, {r1, lr}
- stmneia r3!, {r1, lr}
- tst ip, #1
- stmneia r3!, {r1, lr}
- teq r2, #0
- LOADREGS(eqfd, sp!, {pc})
- b 3b
+1: subs r2, r2, #4 @ 1 do we have enough
+ blt 5f @ 1 bytes to align with?
+ cmp r3, #2 @ 1
+ strltb r1, [r0], #1 @ 1
+ strleb r1, [r0], #1 @ 1
+ strb r1, [r0], #1 @ 1
+ add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted. Try doing the
+ * memzero again.
+ */
-6: subs r2, r2, #1
- strgeb r1, [r3], #1
- bgt 6b
- RETINSTR(mov, pc, lr)
+ENTRY(memset)
+ ands r3, r0, #3 @ 1 unaligned?
+ bne 1b @ 1
+/*
+ * we know that the pointer in r0 is aligned to a word boundary.
+ */
+ orr r1, r1, r1, lsl #8
+ orr r1, r1, r1, lsl #16
+ mov r3, r1
+ cmp r2, #16
+ blt 4f
+/*
+ * We need an extra register for this loop - save the return address and
+ * use the LR
+ */
+ str lr, [sp, #-4]!
+ mov ip, r1
+ mov lr, r1
+2: subs r2, r2, #64
+ stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time.
+ stmgeia r0!, {r1, r3, ip, lr}
+ stmgeia r0!, {r1, r3, ip, lr}
+ stmgeia r0!, {r1, r3, ip, lr}
+ bgt 2b
+ LOADREGS(eqfd, sp!, {pc}) @ Now <64 bytes to go.
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+ tst r2, #32
+ stmneia r0!, {r1, r3, ip, lr}
+ stmneia r0!, {r1, r3, ip, lr}
+ tst r2, #16
+ stmneia r0!, {r1, r3, ip, lr}
+ ldr lr, [sp], #4
+4: tst r2, #8
+ stmneia r0!, {r1, r3}
+ tst r2, #4
+ strne r1, [r0], #4
+/*
+ * When we get here, we've got less than 4 bytes to zero. We
+ * may have an unaligned pointer as well.
+ */
+5: tst r2, #2
+ strneb r1, [r0], #1
+ strneb r1, [r0], #1
+ tst r2, #1
+ strneb r1, [r0], #1
+ RETINSTR(mov,pc,lr)
diff --git a/arch/arm/lib/memzero.S b/arch/arm/lib/memzero.S
index 59ec36574..51ccc6016 100644
--- a/arch/arm/lib/memzero.S
+++ b/arch/arm/lib/memzero.S
@@ -1,80 +1,80 @@
/*
- * linux/arch/arm/lib/memzero.S
+ * linux/arch/arm/lib/memzero.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include "constants.h"
-
- .text
+ .text
+ .align 5
+ .word 0
/*
- * Prototype: void memzero(void *d, size_t n)
+ * Align the pointer in r0. r3 contains the number of bytes that we are
+ * mis-aligned by, and r1 is the number of bytes. If r1 < 4, then we
+ * don't bother; we use byte stores instead.
+ */
+1: subs r1, r1, #4 @ 1 do we have enough
+ blt 5f @ 1 bytes to align with?
+ cmp r3, #2 @ 1
+ strltb r2, [r0], #1 @ 1
+ strleb r2, [r0], #1 @ 1
+ strb r2, [r0], #1 @ 1
+ add r1, r1, r3 @ 1 (r1 = r1 - (4 - r3))
+/*
+ * The pointer is now aligned and the length is adjusted. Try doing the
+ * memzero again.
*/
-1: @ 4 <= r1
- cmp ip, #2 @ 1
- strltb r2, [r0], #1 @ 1
- strleb r2, [r0], #1 @ 1
- strb r2, [r0], #1 @ 1
- rsb ip, ip, #4 @ 1
- sub r1, r1, ip @ 1
- cmp r1, #3 @ 1
- bgt 2f @ 1 @ +8
- b 4f @ 1 @ +9
-
- .align 5
ENTRY(__memzero)
- mov r2, #0 @ 1
- cmp r1, #4 @ 1
- blt 4f @ 1 @ = 3
-
- @ r1 >= 4
-
- ands ip, r0, #3 @ 1
- bne 1b @ 1 @ = 5
-
-2: @ r1 >= 4 && (r0 & 3) = 0 @ = 5 or 11
-
- str lr, [sp, #-4]! @ 1
- mov r3, #0 @ 1
- mov ip, #0 @ 1
- mov lr, #0 @ 1
-
- @ 4 <= r1 <= 32 @ = 9 or 15
-
-3: subs r1, r1, #32 @ 1
- stmgeia r0!, {r2, r3, ip, lr} @ 4
- stmgeia r0!, {r2, r3, ip, lr} @ 4
- bgt 3b @ 1
- LOADREGS(eqfd, sp!, {pc}) @ 1/2
-
- @ -28 <= r1 <= -1
-
- cmp r1, #-16 @ 1
- stmgeia r0!, {r2, r3, ip, lr} @ 4
- ldr lr, [sp], #4 @ 1
- addlts r1, r1, #16 @ 1
- RETINSTR(moveq,pc,lr) @ 1
-
- @ -12 <= r1 <= -1
-
- cmp r1, #-8 @ 1
- stmgeia r0!, {r2, r3} @ 2
- addlts r1, r1, #8 @ 1
- RETINSTR(moveq,pc,lr) @ 1
-
- @ -4 <= r1 <= -1
-
- cmp r1, #-4 @ 1
- strge r2, [r0], #4 @ 1
- adds r1, r1, #4 @ 1
- RETINSTR(moveq,pc,lr) @ 1
-
-4: @ 1 <= r1 <= 3
- cmp r1, #2 @ 1
- strgtb r2, [r0], #1 @ 1
- strgeb r2, [r0], #1 @ 1
- strb r2, [r0], #1 @ 1
- RETINSTR(mov,pc,lr) @ 1
+ mov r2, #0 @ 1
+ ands r3, r0, #3 @ 1 unaligned?
+ bne 1b @ 1
+/*
+ * r3 = 0, and we know that the pointer in r0 is aligned to a word boundary.
+ */
+ cmp r1, #16 @ 1 we can skip this chunk if we
+ blt 4f @ 1 have < 16 bytes
+/*
+ * We need an extra register for this loop - save the return address and
+ * use the LR
+ */
+ str lr, [sp, #-4]! @ 1
+ mov ip, r2 @ 1
+ mov lr, r2 @ 1
+
+3: subs r1, r1, #64 @ 1 write 32 bytes out per loop
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ stmgeia r0!, {r2, r3, ip, lr} @ 4
+ bgt 3b @ 1
+ LOADREGS(eqfd, sp!, {pc}) @ 1/2 quick exit
+/*
+ * No need to correct the count; we're only testing bits from now on
+ */
+ tst r1, #32 @ 1
+ stmneia r0!, {r2, r3, ip, lr} @ 4
+ stmneia r0!, {r2, r3, ip, lr} @ 4
+ tst r1, #16 @ 1 16 bytes or more?
+ stmneia r0!, {r2, r3, ip, lr} @ 4
+ ldr lr, [sp], #4 @ 1
+
+4: tst r1, #8 @ 1 8 bytes or more?
+ stmneia r0!, {r2, r3} @ 2
+ tst r1, #4 @ 1 4 bytes or more?
+ strne r2, [r0], #4 @ 1
+/*
+ * When we get here, we've got less than 4 bytes to zero. We
+ * may have an unaligned pointer as well.
+ */
+5: tst r1, #2 @ 1 2 bytes or more?
+ strneb r2, [r0], #1 @ 1
+ strneb r2, [r0], #1 @ 1
+ tst r1, #1 @ 1 a byte left over
+ strneb r2, [r0], #1 @ 1
+ RETINSTR(mov,pc,lr) @ 1
diff --git a/arch/arm/lib/setbit.S b/arch/arm/lib/setbit.S
index 745bdce4e..5e51b27a8 100644
--- a/arch/arm/lib/setbit.S
+++ b/arch/arm/lib/setbit.S
@@ -1,9 +1,12 @@
/*
- * linux/arch/arm/lib/setbit.S
+ * linux/arch/arm/lib/setbit.S
*
- * Copyright (C) 1995-1996 Russell King
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
diff --git a/arch/arm/lib/strchr.S b/arch/arm/lib/strchr.S
index fbde2483f..49b96bc02 100644
--- a/arch/arm/lib/strchr.S
+++ b/arch/arm/lib/strchr.S
@@ -1,19 +1,20 @@
/*
- * linux/arch/arm/lib/strchr.S
+ * linux/arch/arm/lib/strchr.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-2000 Russell King
*
- * ASM optimised string functions
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
+ * ASM optimised string functions
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include "constants.h"
.text
+ .align 5
ENTRY(strchr)
- str lr, [sp, #-4]!
- mov r3, #0
1: ldrb r2, [r0], #1
teq r2, r1
teqne r2, #0
@@ -21,6 +22,4 @@ ENTRY(strchr)
teq r2, #0
moveq r0, #0
subne r0, r0, #1
- LOADREGS(fd, sp!, {pc})
-
-
+ RETINSTR(mov,pc,lr)
diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S
new file mode 100644
index 000000000..629cc8775
--- /dev/null
+++ b/arch/arm/lib/strncpy_from_user.S
@@ -0,0 +1,43 @@
+/*
+ * linux/arch/arm/lib/strncpy_from_user.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+
+ .text
+ .align 5
+
+/*
+ * Copy a string from user space to kernel space.
+ * r0 = dst, r1 = src, r2 = byte length
+ * returns the number of characters copied (strlen of copied string),
+ * -EFAULT on exception, or "len" if we fill the whole buffer
+ */
+ENTRY(__arch_strncpy_from_user)
+ save_lr
+ mov ip, r1
+1: subs r2, r2, #1
+USER( ldrplbt r3, [r1], #1)
+ bmi 2f
+ strb r3, [r0], #1
+ teq r3, #0
+ bne 1b
+ sub r1, r1, #1 @ take NUL character out of count
+2: sub r0, r1, ip
+ restore_pc
+
+ .section .fixup,"ax"
+ .align 0
+9001: mov r3, #0
+ strb r3, [r0, #0] @ null terminate
+ mov r0, #-EFAULT
+ restore_pc
+ .previous
+
diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S
new file mode 100644
index 000000000..67bcd8268
--- /dev/null
+++ b/arch/arm/lib/strnlen_user.S
@@ -0,0 +1,40 @@
+/*
+ * linux/arch/arm/lib/strnlen_user.S
+ *
+ * Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/errno.h>
+
+ .text
+ .align 5
+
+/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n)
+ * Purpose : get length of a string in user memory
+ * Params : str - address of string in user memory
+ * Returns : length of string *including terminator*
+ * or zero on exception, or n + 1 if too long
+ */
+ENTRY(__arch_strnlen_user)
+ save_lr
+ mov r2, r0
+1:
+USER( ldrbt r3, [r0], #1)
+ teq r3, #0
+ beq 2f
+ subs r1, r1, #1
+ bne 1b
+ add r0, r0, #1
+2: sub r0, r0, r2
+ restore_pc
+
+ .section .fixup,"ax"
+ .align 0
+9001: mov r0, #0
+ restore_pc
+ .previous
diff --git a/arch/arm/lib/strrchr.S b/arch/arm/lib/strrchr.S
index c9145d7af..7ef7fa439 100644
--- a/arch/arm/lib/strrchr.S
+++ b/arch/arm/lib/strrchr.S
@@ -1,18 +1,20 @@
/*
- * linux/arch/arm/lib/strrchr.S
+ * linux/arch/arm/lib/strrchr.S
*
- * Copyright (C) 1995-1999 Russell King
+ * Copyright (C) 1995-2000 Russell King
*
- * ASM optimised string functions
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*
+ * ASM optimised string functions
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
-#include "constants.h"
.text
+ .align 5
ENTRY(strrchr)
- str lr, [sp, #-4]!
mov r3, #0
1: ldrb r2, [r0], #1
teq r2, r1
@@ -20,6 +22,4 @@ ENTRY(strrchr)
teq r2, #0
bne 1b
mov r0, r3
- LOADREGS(fd, sp!, {pc})
-
-
+ RETINSTR(mov,pc,lr)
diff --git a/arch/arm/lib/testchangebit.S b/arch/arm/lib/testchangebit.S
index c627cf99d..3131538d8 100644
--- a/arch/arm/lib/testchangebit.S
+++ b/arch/arm/lib/testchangebit.S
@@ -1,9 +1,12 @@
/*
- * linux/arch/arm/lib/testchangebit.S
+ * linux/arch/arm/lib/testchangebit.S
*
- * Copyright (C) 1995-1996 Russell King
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
diff --git a/arch/arm/lib/testclearbit.S b/arch/arm/lib/testclearbit.S
index 3a678e7ff..d6c612fe1 100644
--- a/arch/arm/lib/testclearbit.S
+++ b/arch/arm/lib/testclearbit.S
@@ -1,9 +1,12 @@
/*
- * linux/arch/arm/lib/testclearbit.S
+ * linux/arch/arm/lib/testclearbit.S
*
- * Copyright (C) 1995-1996 Russell King
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
diff --git a/arch/arm/lib/testsetbit.S b/arch/arm/lib/testsetbit.S
index 2b59febea..b022c324f 100644
--- a/arch/arm/lib/testsetbit.S
+++ b/arch/arm/lib/testsetbit.S
@@ -1,9 +1,12 @@
/*
- * linux/arch/arm/lib/testsetbit.S
+ * linux/arch/arm/lib/testsetbit.S
*
- * Copyright (C) 1995-1996 Russell King
+ * Copyright (C) 1995-1996 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
diff --git a/arch/arm/lib/uaccess-armo.S b/arch/arm/lib/uaccess-armo.S
index 695fdf0c1..2ffdf4dbb 100644
--- a/arch/arm/lib/uaccess-armo.S
+++ b/arch/arm/lib/uaccess-armo.S
@@ -1,23 +1,20 @@
/*
- * arch/arm/lib/uaccess-armo.S
+ * linux/arch/arm/lib/uaccess-armo.S
*
- * Copyright (C) 1998 Russell King
+ * Copyright (C) 1998 Russell King
*
- * Note! Some code fragments found in here have a special calling
- * convention - they are not APCS compliant!
+ * Note! Some code fragments found in here have a special calling
+ * convention - they are not APCS compliant!
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
-#define USER(x...) \
-9999: x; \
- .section __ex_table,"a"; \
- .align 3; \
- .long 9999b,9001f; \
- .previous
-
.globl SYMBOL_NAME(uaccess_user)
SYMBOL_NAME(uaccess_user):
.word uaccess_user_put_byte
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
index f2ea3231d..13af269c6 100644
--- a/arch/arm/lib/uaccess.S
+++ b/arch/arm/lib/uaccess.S
@@ -1,11 +1,15 @@
/*
- * linux/arch/arm/lib/uaccess.S
+ * linux/arch/arm/lib/uaccess.S
*
- * Copyright (C) 1995, 1996,1997,1998 Russell King
+ * Copyright (C) 1995, 1996,1997,1998 Russell King
*
- * Routines to block copy data to/from user memory
- * These are highly optimised both for the 4k page size
- * and for various alignments.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Routines to block copy data to/from user memory
+ * These are highly optimised both for the 4k page size
+ * and for various alignments.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
@@ -13,13 +17,6 @@
.text
-#define USER(x...) \
-9999: x; \
- .section __ex_table,"a"; \
- .align 3; \
- .long 9999b,9001f; \
- .previous
-
#define PAGE_SHIFT 12
/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n)
@@ -590,62 +587,3 @@ USER( strnebt r2, [r0], #1)
9001: LOADREGS(fd,sp!, {r0, pc})
.previous
-/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n)
- * Purpose : get length of a string in user memory
- * Params : str - address of string in user memory
- * Returns : length of string *including terminator*
- * or zero on exception, or n + 1 if too long
- */
-ENTRY(__arch_strnlen_user)
- str lr, [sp, #-4]!
- mov r2, r0
-1:
-USER( ldrbt r3, [r0], #1)
- teq r3, #0
- beq 2f
- subs r1, r1, #1
- bne 1b
- add r0, r0, #1
-2: sub r0, r0, r2
- LOADREGS(fd,sp!, {pc})
-
- .section .fixup,"ax"
- .align 0
-9001: mov r0, #0
- LOADREGS(fd,sp!,{pc})
- .previous
-
-/* Prototype: size_t __arch_strncpy_from_user(char *dst, char *src, size_t len)
- * Purpose : copy a string from user memory to kernel memory
- * Params : dst - kernel memory destination
- * : src - user memory source
- * : len - maximum length of string
- * Returns : number of characters copied
- */
-ENTRY(__arch_strncpy_from_user)
- str lr, [sp, #-4]!
- add ip, r1, #1
-1: subs r2, r2, #1
- bmi 2f
-USER( ldrbt r3, [r1], #1)
- strb r3, [r0], #1
- teq r3, #0
- bne 1b
- sub r0, r1, ip
- LOADREGS(fd, sp!, {pc})
-2: sub ip, ip, #1
- sub r0, r1, ip
- LOADREGS(fd, sp!, {pc})
-
- .section .fixup,"ax"
- .align 0
-9001: mov ip, #0
-1: strb ip, [r0], #1
- subs r2, r2, #1
- bpl 1b
- mov r0, #-EFAULT
- LOADREGS(fd, sp!, {pc})
- .previous
-
- .align
-
diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile
new file mode 100644
index 000000000..c21caa6f6
--- /dev/null
+++ b/arch/arm/mach-footbridge/Makefile
@@ -0,0 +1,46 @@
+#
+# Makefile for the linux kernel.
+#
+# 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).
+
+O_TARGET := footbridge.o
+
+# Object file lists.
+
+obj-y := arch.o #dma.o mm.o
+obj-m :=
+obj-n :=
+obj- :=
+
+export-objs := netwinder-hw.o
+
+ifeq ($(CONFIG_PCI),y)
+obj-$(CONFIG_ARCH_CATS) += cats-pci.o
+obj-$(CONFIG_ARCH_EBSA285) += ebsa285-pci.o
+obj-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o
+obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o
+endif
+
+ifeq ($(CONFIG_LEDS),y)
+obj-$(CONFIG_ARCH_CO285) += ebsa285-leds.o
+obj-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o
+obj-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o
+endif
+
+obj-$(CONFIG_ARCH_CATS) += cats-hw.o
+obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o
+
+# Files that are both resident and modular; remove from modular.
+
+obj-m := $(filter-out $(obj-y), $(obj-m))
+
+# Translate to Rules.make lists.
+
+O_OBJS := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS := $(filter $(export-objs), $(obj-y))
+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/arm/mach-footbridge/arch.c b/arch/arm/mach-footbridge/arch.c
new file mode 100644
index 000000000..d91c9b14b
--- /dev/null
+++ b/arch/arm/mach-footbridge/arch.c
@@ -0,0 +1,152 @@
+/*
+ * linux/arch/arm/mach-footbridge/arch.c
+ *
+ * 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.
+ */
+#include <linux/config.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/hardware/dec21285.h>
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+extern void setup_initrd(unsigned int start, unsigned int size);
+extern void setup_ramdisk(int doload, int prompt, int start, unsigned int rd_sz);
+extern void __init footbridge_map_io(void);
+
+#ifdef CONFIG_ARCH_EBSA285
+
+static void __init
+fixup_ebsa285(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline, struct meminfo *mi)
+{
+ 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;
+}
+
+MACHINE_START(EBSA285, "EBSA285")
+ MAINTAINER("Russell King")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
+ BOOT_PARAMS(0x00000100)
+ VIDEO(0x000a0000, 0x000bffff)
+ FIXUP(fixup_ebsa285)
+ MAPIO(footbridge_map_io)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_NETWINDER
+/*
+ * 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, struct meminfo *mi)
+{
+#ifdef CONFIG_ISAPNP
+ extern int isapnp_disable;
+
+ /*
+ * 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
+
+ if (params->u1.s.nr_pages != 0x02000 &&
+ params->u1.s.nr_pages != 0x04000 &&
+ params->u1.s.nr_pages != 0x08000 &&
+ params->u1.s.nr_pages != 0x10000) {
+ 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;
+ }
+}
+
+MACHINE_START(NETWINDER, "Rebel-NetWinder")
+ MAINTAINER("Russell King/Rebel.com")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
+ BOOT_PARAMS(0x00000100)
+ VIDEO(0x000a0000, 0x000bffff)
+ DISABLE_PARPORT(0)
+ DISABLE_PARPORT(2)
+ FIXUP(fixup_netwinder)
+ MAPIO(footbridge_map_io)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_CATS
+/*
+ * 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, struct meminfo *mi)
+{
+ ORIG_VIDEO_LINES = 25;
+ ORIG_VIDEO_POINTS = 16;
+ ORIG_Y = 24;
+}
+
+MACHINE_START(CATS, "Chalice-CATS")
+ MAINTAINER("Philip Blundell")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
+ SOFT_REBOOT
+ FIXUP(fixup_cats)
+ MAPIO(footbridge_map_io)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_CO285
+
+static void __init
+fixup_coebsa285(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline, struct meminfo *mi)
+{
+ extern unsigned long boot_memory_end;
+ extern char boot_command_line[];
+
+ mi->nr_banks = 1;
+ mi->bank[0].start = PHYS_OFFSET;
+ mi->bank[0].size = boot_memory_end;
+ mi->bank[0].node = 0;
+
+ *cmdline = boot_command_line;
+}
+
+MACHINE_START(CO285, "co-EBSA285")
+ MAINTAINER("Mark van Doesburg")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000)
+ FIXUP(fixup_coebsa285)
+ MAPIO(footbridge_map_io)
+MACHINE_END
+#endif
+
+#ifdef CONFIG_ARCH_PERSONAL_SERVER
+MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer")
+ MAINTAINER("Jamey Hicks / George France")
+ BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000)
+ BOOT_PARAMS(0x00000100)
+ MAPIO(footbridge_map_io)
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c
new file mode 100644
index 000000000..160b0307f
--- /dev/null
+++ b/arch/arm/mach-footbridge/cats-hw.c
@@ -0,0 +1,65 @@
+/*
+ * linux/arch/arm/mach-footbridge/cats-hw.c
+ *
+ * CATS machine fixup
+ *
+ * Copyright (C) 1998, 1999 Russell King, Phil Blundell
+ */
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/mach-types.h>
+
+#define CFG_PORT 0x370
+#define INDEX_PORT (CFG_PORT)
+#define DATA_PORT (CFG_PORT + 1)
+
+static int __init cats_hw_init(void)
+{
+ if (machine_is_cats()) {
+ /* Set Aladdin to CONFIGURE mode */
+ outb(0x51, CFG_PORT);
+ outb(0x23, CFG_PORT);
+
+ /* Select logical device 3 */
+ outb(0x07, INDEX_PORT);
+ outb(0x03, DATA_PORT);
+
+ /* Set parallel port to DMA channel 3, ECP+EPP1.9,
+ enable EPP timeout */
+ outb(0x74, INDEX_PORT);
+ outb(0x03, DATA_PORT);
+
+ outb(0xf0, INDEX_PORT);
+ outb(0x0f, DATA_PORT);
+
+ outb(0xf1, INDEX_PORT);
+ outb(0x07, DATA_PORT);
+
+ /* Select logical device 4 */
+ outb(0x07, INDEX_PORT);
+ outb(0x04, DATA_PORT);
+
+ /* UART1 high speed mode */
+ outb(0xf0, INDEX_PORT);
+ outb(0x02, DATA_PORT);
+
+ /* Select logical device 5 */
+ outb(0x07, INDEX_PORT);
+ outb(0x05, DATA_PORT);
+
+ /* UART2 high speed mode */
+ outb(0xf0, INDEX_PORT);
+ outb(0x02, DATA_PORT);
+
+ /* Set Aladdin to RUN mode */
+ outb(0xbb, CFG_PORT);
+ }
+
+ return 0;
+}
+
+__initcall(cats_hw_init);
diff --git a/arch/arm/mach-footbridge/cats-pci.c b/arch/arm/mach-footbridge/cats-pci.c
new file mode 100644
index 000000000..1f9e198ba
--- /dev/null
+++ b/arch/arm/mach-footbridge/cats-pci.c
@@ -0,0 +1,37 @@
+/*
+ * linux/arch/arm/mach-footbridge/cats-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+/* cats host-specific stuff */
+static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
+
+static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (dev->irq >= 128)
+ return dev->irq & 0x1f;
+
+ if (dev->irq >= 1 && dev->irq <= 4)
+ return irqmap_cats[dev->irq - 1];
+
+ if (dev->irq != 0)
+ printk("PCI: device %02x:%02x has unknown irq line %x\n",
+ dev->bus->number, dev->devfn, dev->irq);
+
+ return -1;
+}
+
+struct hw_pci cats_pci __initdata = {
+ init: dc21285_init,
+ swizzle: no_swizzle,
+ map_irq: cats_map_irq,
+};
diff --git a/arch/arm/kernel/leds-footbridge.c b/arch/arm/mach-footbridge/ebsa285-leds.c
index 3de4c96f9..46ce71423 100644
--- a/arch/arm/kernel/leds-footbridge.c
+++ b/arch/arm/mach-footbridge/ebsa285-leds.c
@@ -1,19 +1,18 @@
/*
- * arch/arm/kernel/leds-footbridge.c
+ * linux/arch/arm/mach-footbridge/ebsa285-leds.c
*
- * Copyright (C) 1998-1999 Russell King
+ * Copyright (C) 1998-1999 Russell King
*
- * EBSA-285 and NetWinder LED control routines.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ * EBSA-285 control routines.
*
* The EBSA-285 uses the leds as follows:
* - Green - toggles state every 50 timer interrupts
* - Amber - On if system is not idle
* - Red - currently unused
*
- * The Netwinder uses the leds as follows:
- * - Green - toggles state every 50 timer interrupts
- * - Red - On if the system is not idle
- *
* Changelog:
* 02-05-1999 RMK Various cleanups
*/
@@ -34,9 +33,6 @@ static char led_state;
static char hw_led_state;
static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED;
-extern spinlock_t gpio_lock;
-
-#if defined(CONFIG_ARCH_EBSA285) || defined(CONFIG_ARCH_CO285)
static void ebsa285_leds_event(led_event_t evt)
{
@@ -131,123 +127,10 @@ static void ebsa285_leds_event(led_event_t evt)
spin_unlock_irqrestore(&leds_lock, flags);
}
-#endif
-
-#ifdef CONFIG_ARCH_NETWINDER
-
-static void netwinder_leds_event(led_event_t evt)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&leds_lock, flags);
-
- switch (evt) {
- case led_start:
- led_state |= LED_STATE_ENABLED;
- hw_led_state = GPIO_GREEN_LED;
- break;
-
- case led_stop:
- led_state &= ~LED_STATE_ENABLED;
- break;
-
- case led_claim:
- led_state |= LED_STATE_CLAIMED;
- hw_led_state = 0;
- break;
-
- case led_release:
- led_state &= ~LED_STATE_CLAIMED;
- hw_led_state = 0;
- break;
-
-#ifdef CONFIG_LEDS_TIMER
- case led_timer:
- if (!(led_state & LED_STATE_CLAIMED))
- hw_led_state ^= GPIO_GREEN_LED;
- break;
-#endif
-
-#ifdef CONFIG_LEDS_CPU
- case led_idle_start:
- if (!(led_state & LED_STATE_CLAIMED))
- hw_led_state &= ~GPIO_RED_LED;
- break;
-
- case led_idle_end:
- if (!(led_state & LED_STATE_CLAIMED))
- hw_led_state |= GPIO_RED_LED;
- break;
-#endif
-
- case led_halted:
- if (!(led_state & LED_STATE_CLAIMED))
- hw_led_state |= GPIO_RED_LED;
- break;
-
- case led_green_on:
- if (led_state & LED_STATE_CLAIMED)
- hw_led_state |= GPIO_GREEN_LED;
- break;
-
- case led_green_off:
- if (led_state & LED_STATE_CLAIMED)
- hw_led_state &= ~GPIO_GREEN_LED;
- break;
-
- case led_amber_on:
- if (led_state & LED_STATE_CLAIMED)
- hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED;
- break;
-
- case led_amber_off:
- if (led_state & LED_STATE_CLAIMED)
- hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED);
- break;
-
- case led_red_on:
- if (led_state & LED_STATE_CLAIMED)
- hw_led_state |= GPIO_RED_LED;
- break;
-
- case led_red_off:
- if (led_state & LED_STATE_CLAIMED)
- hw_led_state &= ~GPIO_RED_LED;
- break;
-
- default:
- break;
- }
-
- spin_unlock_irqrestore(&leds_lock, flags);
-
- if (led_state & LED_STATE_ENABLED) {
- spin_lock_irqsave(&gpio_lock, flags);
- gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state);
- spin_unlock_irqrestore(&gpio_lock, flags);
- }
-}
-
-#endif
-
-static void dummy_leds_event(led_event_t evt)
-{
-}
-
-void (*leds_event)(led_event_t) = dummy_leds_event;
-
-EXPORT_SYMBOL(leds_event);
-
static int __init leds_init(void)
{
-#if defined(CONFIG_ARCH_EBSA285) || defined(CONFIG_ARCH_CO285)
if (machine_is_ebsa285() || machine_is_co285())
leds_event = ebsa285_leds_event;
-#endif
-#ifdef CONFIG_ARCH_NETWINDER
- if (machine_is_netwinder())
- leds_event = netwinder_leds_event;
-#endif
leds_event(led_start);
diff --git a/arch/arm/mach-footbridge/ebsa285-pci.c b/arch/arm/mach-footbridge/ebsa285-pci.c
new file mode 100644
index 000000000..304079040
--- /dev/null
+++ b/arch/arm/mach-footbridge/ebsa285-pci.c
@@ -0,0 +1,39 @@
+/*
+ * linux/arch/arm/mach-footbridge/ebsa285-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI };
+
+static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin)
+{
+ return PCI_SLOT(dev->devfn);
+}
+
+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];
+}
+
+struct hw_pci ebsa285_pci __initdata = {
+ init: dc21285_init,
+ swizzle: ebsa285_swizzle,
+ map_irq: ebsa285_map_irq,
+};
diff --git a/arch/arm/kernel/hw-footbridge.c b/arch/arm/mach-footbridge/netwinder-hw.c
index 41ff450a5..4b47b6e47 100644
--- a/arch/arm/kernel/hw-footbridge.c
+++ b/arch/arm/mach-footbridge/netwinder-hw.c
@@ -1,7 +1,7 @@
/*
- * arch/arm/kernel/hw-footbridge.c
+ * linux/arch/arm/mach-footbridge/netwinder-hw.c
*
- * Footbridge-dependent machine fixup
+ * Netwinder machine fixup
*
* Copyright (C) 1998, 1999 Russell King, Phil Blundell
*/
@@ -29,11 +29,6 @@
#endif
/*
- * Netwinder stuff
- */
-#ifdef CONFIG_ARCH_NETWINDER
-
-/*
* Winbond WB83977F accessibility stuff
*/
static inline void wb977_open(void)
@@ -609,13 +604,6 @@ EXPORT_SYMBOL(cpld_modify);
*/
static int __init nw_hw_init(void)
{
- /*
- * this ought to have a better home...
- * Since this calls the above routines, which are
- * compiled only if CONFIG_ARCH_NETWINDER is set,
- * these should only be parsed by the compiler
- * in the same circumstance.
- */
if (machine_is_netwinder()) {
unsigned long flags;
@@ -631,62 +619,3 @@ static int __init nw_hw_init(void)
}
__initcall(nw_hw_init);
-#endif
-
-/*
- * CATS stuff
- */
-#ifdef CONFIG_ARCH_CATS
-
-#define CONFIG_PORT 0x370
-#define INDEX_PORT (CONFIG_PORT)
-#define DATA_PORT (CONFIG_PORT + 1)
-
-static int __init cats_hw_init(void)
-{
- if (machine_is_cats()) {
- /* Set Aladdin to CONFIGURE mode */
- outb(0x51, CONFIG_PORT);
- outb(0x23, CONFIG_PORT);
-
- /* Select logical device 3 */
- outb(0x07, INDEX_PORT);
- outb(0x03, DATA_PORT);
-
- /* Set parallel port to DMA channel 3, ECP+EPP1.9,
- enable EPP timeout */
- outb(0x74, INDEX_PORT);
- outb(0x03, DATA_PORT);
-
- outb(0xf0, INDEX_PORT);
- outb(0x0f, DATA_PORT);
-
- outb(0xf1, INDEX_PORT);
- outb(0x07, DATA_PORT);
-
- /* Select logical device 4 */
- outb(0x07, INDEX_PORT);
- outb(0x04, DATA_PORT);
-
- /* UART1 high speed mode */
- outb(0xf0, INDEX_PORT);
- outb(0x02, DATA_PORT);
-
- /* Select logical device 5 */
- outb(0x07, INDEX_PORT);
- outb(0x05, DATA_PORT);
-
- /* UART2 high speed mode */
- outb(0xf0, INDEX_PORT);
- outb(0x02, DATA_PORT);
-
- /* Set Aladdin to RUN mode */
- outb(0xbb, CONFIG_PORT);
- }
-
- return 0;
-}
-
-__initcall(cats_hw_init);
-#endif
-
diff --git a/arch/arm/mach-footbridge/netwinder-leds.c b/arch/arm/mach-footbridge/netwinder-leds.c
new file mode 100644
index 000000000..bcf6e6a7c
--- /dev/null
+++ b/arch/arm/mach-footbridge/netwinder-leds.c
@@ -0,0 +1,141 @@
+/*
+ * linux/arch/arm/mach-footbridge/netwinder-leds.c
+ *
+ * Copyright (C) 1998-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * NetWinder LED control routines.
+ *
+ * The Netwinder uses the leds as follows:
+ * - Green - toggles state every 50 timer interrupts
+ * - Red - On if the system is not idle
+ *
+ * Changelog:
+ * 02-05-1999 RMK Various cleanups
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+
+#include <asm/hardware.h>
+#include <asm/leds.h>
+#include <asm/mach-types.h>
+#include <asm/system.h>
+
+#define LED_STATE_ENABLED 1
+#define LED_STATE_CLAIMED 2
+static char led_state;
+static char hw_led_state;
+
+static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED;
+extern spinlock_t gpio_lock;
+
+static void netwinder_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&leds_lock, flags);
+
+ switch (evt) {
+ case led_start:
+ led_state |= LED_STATE_ENABLED;
+ hw_led_state = GPIO_GREEN_LED;
+ break;
+
+ case led_stop:
+ led_state &= ~LED_STATE_ENABLED;
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= GPIO_GREEN_LED;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~GPIO_RED_LED;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= GPIO_RED_LED;
+ break;
+#endif
+
+ case led_halted:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= GPIO_RED_LED;
+ break;
+
+ case led_green_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= GPIO_GREEN_LED;
+ break;
+
+ case led_green_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~GPIO_GREEN_LED;
+ break;
+
+ case led_amber_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED;
+ break;
+
+ case led_amber_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED);
+ break;
+
+ case led_red_on:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state |= GPIO_RED_LED;
+ break;
+
+ case led_red_off:
+ if (led_state & LED_STATE_CLAIMED)
+ hw_led_state &= ~GPIO_RED_LED;
+ break;
+
+ default:
+ break;
+ }
+
+ spin_unlock_irqrestore(&leds_lock, flags);
+
+ if (led_state & LED_STATE_ENABLED) {
+ spin_lock_irqsave(&gpio_lock, flags);
+ gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state);
+ spin_unlock_irqrestore(&gpio_lock, flags);
+ }
+}
+
+static int __init leds_init(void)
+{
+ if (machine_is_netwinder())
+ leds_event = netwinder_leds_event;
+
+ leds_event(led_start);
+
+ return 0;
+}
+
+__initcall(leds_init);
diff --git a/arch/arm/mach-footbridge/netwinder-pci.c b/arch/arm/mach-footbridge/netwinder-pci.c
new file mode 100644
index 000000000..6bad74680
--- /dev/null
+++ b/arch/arm/mach-footbridge/netwinder-pci.c
@@ -0,0 +1,54 @@
+/*
+ * linux/arch/arm/mach-footbridge/netwinder-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+/* netwinder host-specific stuff */
+static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+#define DEV(v,d) ((v)<<16|(d))
+ switch (DEV(dev->vendor, dev->device)) {
+ case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142):
+ 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):
+ return IRQ_NETWINDER_ETHER10;
+
+ case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553):
+ return 0;
+
+ case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105):
+ return IRQ_ISA_HARDDISK1;
+
+ case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000):
+ case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010):
+ case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000):
+ return IRQ_NETWINDER_VGA;
+
+ case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285):
+ return 0;
+
+ default:
+ printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n",
+ dev->bus->number, dev->devfn,
+ dev->vendor, dev->device);
+ return 0;
+ }
+}
+
+struct hw_pci netwinder_pci __initdata = {
+ init: dc21285_init,
+ swizzle: no_swizzle,
+ map_irq: netwinder_map_irq,
+};
diff --git a/arch/arm/mach-footbridge/personal-pci.c b/arch/arm/mach-footbridge/personal-pci.c
new file mode 100644
index 000000000..8d810a22f
--- /dev/null
+++ b/arch/arm/mach-footbridge/personal-pci.c
@@ -0,0 +1,43 @@
+/*
+ * linux/arch/arm/mach-footbridge/personal-pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+static int irqmap_personal_server[] __initdata = {
+ IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0,
+ IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI
+};
+
+static int __init personal_server_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ unsigned char line;
+
+ pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line);
+
+ if (line > 0x40 && line <= 0x5f) {
+ /* line corresponds to the bit controlling this interrupt
+ * in the footbridge. Ignore the first 8 interrupt bits,
+ * look up the rest in the map. IN0 is bit number 8
+ */
+ return irqmap_personal_server[(line & 0x1f) - 8];
+ } else if (line == 0) {
+ /* no interrupt */
+ return 0;
+ } else
+ return irqmap_personal_server[(line - 1) & 3];
+}
+
+struct hw_pci personal_server_pci __initdata = {
+ init: dc21285_init,
+ swizzle: no_swizzle,
+ map_irq: personal_server_map_irq,
+};
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
new file mode 100644
index 000000000..441608295
--- /dev/null
+++ b/arch/arm/mach-sa1100/Makefile
@@ -0,0 +1,34 @@
+#
+# Makefile for the linux kernel.
+#
+# 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).
+
+USE_STANDARD_AS_RULE := true
+
+O_TARGET := sa1100.o
+
+# Object file lists.
+
+obj-y := arch.o hw.o #dma.o mm.o
+obj-m :=
+obj-n :=
+obj- :=
+
+export-objs := hw.o leds.o
+
+obj-$(CONFIG_LEDS) += leds.o
+
+# Files that are both resident and modular; remove from modular.
+
+obj-m := $(filter-out $(obj-y), $(obj-m))
+
+# Translate to Rules.make lists.
+
+O_OBJS := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS := $(filter $(export-objs), $(obj-y))
+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/arm/mach-sa1100/arch.c b/arch/arm/mach-sa1100/arch.c
new file mode 100644
index 000000000..32ac72379
--- /dev/null
+++ b/arch/arm/mach-sa1100/arch.c
@@ -0,0 +1,291 @@
+/*
+ * linux/arch/arm/mach-sa1100/arch.c
+ *
+ * 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.
+ */
+#include <linux/config.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/elf.h>
+#include <asm/hardware.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+extern void setup_initrd(unsigned int start, unsigned int size);
+extern void setup_ramdisk(int doload, int prompt, int start, unsigned int rd_sz);
+
+static void victor_power_off(void)
+{
+ /* switch off power supply */
+ mdelay(2000);
+ GPCR = GPIO_GPIO23;
+ while (1);
+}
+
+
+static void xp860_power_off(void)
+{
+ GPDR |= GPIO_GPIO20;
+ GPSR = GPIO_GPIO20;
+ mdelay(1000);
+ GPCR = GPIO_GPIO20;
+ while(1);
+}
+
+
+extern void __init sa1100_map_io(void);
+
+#define SET_BANK(__nr,__start,__size) \
+ mi->bank[__nr].start = (__start), \
+ mi->bank[__nr].size = (__size), \
+ mi->bank[__nr].node = (((unsigned)(__start) - PHYS_OFFSET) >> 27)
+static void __init
+fixup_sa1100(struct machine_desc *desc, struct param_struct *params,
+ char **cmdline, struct meminfo *mi)
+{
+ if (machine_is_assabet()) {
+ /*
+ * On Assabet, we must probe for the Neponset board *before*
+ * paging_init() has occured to actually determine the amount
+ * of RAM available.
+ */
+ extern void map_sa1100_gpio_regs(void);
+ extern void get_assabet_scr(void);
+ map_sa1100_gpio_regs();
+ get_assabet_scr();
+
+ SET_BANK( 0, 0xc0000000, 32*1024*1024 );
+ mi->nr_banks = 1;
+
+ if (machine_has_neponset()) {
+ printk("Neponset expansion board detected\n");
+ /*
+ * Note that Neponset RAM is slower...
+ * and still untested.
+ * This would be a candidate for
+ * _real_ NUMA support.
+ */
+ //SET_BANK( 1, 0xd0000000, 32*1024*1024 );
+ //mi->nr_banks = 2;
+ }
+
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk( 1, 0, 0, 8192 );
+ setup_initrd( 0xc0800000, 3*1024*1024 );
+ }
+
+ else if (machine_is_brutus()) {
+ SET_BANK( 0, 0xc0000000, 4*1024*1024 );
+ SET_BANK( 1, 0xc8000000, 4*1024*1024 );
+ SET_BANK( 2, 0xd0000000, 4*1024*1024 );
+ SET_BANK( 3, 0xd8000000, 4*1024*1024 );
+ mi->nr_banks = 4;
+
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk( 1, 0, 0, 8192 );
+ setup_initrd( __phys_to_virt(0xd8000000), 3*1024*1024 );
+ }
+
+ else if (machine_is_cerf()) {
+ // 16Meg Ram.
+ SET_BANK( 0, 0xc0000000, 8*1024*1024 );
+ SET_BANK( 1, 0xc8000000, 8*1024*1024 ); // comment this out for 8MB Cerfs
+ mi->nr_banks = 2;
+
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk(1, 0, 0, 8192);
+ // Save 2Meg for RAMDisk
+ setup_initrd(0xc0500000, 3*1024*1024);
+ }
+
+ else if (machine_is_empeg()) {
+ SET_BANK( 0, 0xc0000000, 4*1024*1024 );
+ SET_BANK( 1, 0xc8000000, 4*1024*1024 );
+ mi->nr_banks = 2;
+
+ ROOT_DEV = MKDEV( 3, 1 ); /* /dev/hda1 */
+ setup_ramdisk( 1, 0, 0, 4096 );
+ setup_initrd( 0xd0000000+((1024-320)*1024), (320*1024) );
+ }
+
+ else if (machine_is_lart()) {
+ /*
+ * Note that LART is a special case - it doesn't use physical
+ * address line A23 on the DRAM, so we effectively have 4 * 8MB
+ * in two SA1100 banks.
+ */
+ SET_BANK( 0, 0xc0000000, 8*1024*1024 );
+ SET_BANK( 1, 0xc1000000, 8*1024*1024 );
+ SET_BANK( 2, 0xc8000000, 8*1024*1024 );
+ SET_BANK( 3, 0xc9000000, 8*1024*1024 );
+ mi->nr_banks = 4;
+
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk(1, 0, 0, 8192);
+ setup_initrd(0xc0400000, 4*1024*1024);
+ }
+
+ else if (machine_is_thinclient() || machine_is_graphicsclient()) {
+ SET_BANK( 0, 0xc0000000, 16*1024*1024 );
+ mi->nr_banks = 1;
+
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk( 1, 0, 0, 8192 );
+ setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
+ }
+
+ else if (machine_is_nanoengine()) {
+ SET_BANK( 0, 0xc0000000, 32*1024*1024 );
+ mi->nr_banks = 1;
+
+ ROOT_DEV = MKDEV(RAMDISK_MAJOR,0);
+ setup_ramdisk( 1, 0, 0, 8192 );
+ setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
+
+ /* Get command line parameters passed from the loader (if any) */
+ if( *((char*)0xc0000100) )
+ *cmdline = ((char *)0xc0000100);
+ }
+ else if (machine_is_tifon()) {
+ SET_BANK( 0, 0xc0000000, 16*1024*1024 );
+ SET_BANK( 1, 0xc8000000, 16*1024*1024 );
+ mi->nr_banks = 2;
+
+ ROOT_DEV = MKDEV(UNNAMED_MAJOR, 0);
+ setup_ramdisk(1, 0, 0, 4096);
+ setup_initrd( 0xd0000000 + 0x1100004, 0x140000 );
+ }
+
+ else if (machine_is_victor()) {
+ SET_BANK( 0, 0xc0000000, 4*1024*1024 );
+ mi->nr_banks = 1;
+
+ ROOT_DEV = MKDEV( 60, 2 );
+
+ /* Get command line parameters passed from the loader (if any) */
+ if( *((char*)0xc0000000) )
+ strcpy( *cmdline, ((char *)0xc0000000) );
+
+ /* power off if any problem */
+ strcat( *cmdline, " panic=1" );
+
+ pm_power_off = victor_power_off;
+ }
+
+ else if (machine_is_xp860()) {
+ SET_BANK( 0, 0xc0000000, 32*1024*1024 );
+ mi->nr_banks = 1;
+
+ pm_power_off = xp860_power_off;
+ }
+}
+
+#ifdef CONFIG_SA1100_ASSABET
+MACHINE_START(ASSABET, "Intel-Assabet")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_BITSY
+MACHINE_START(BITSY, "Compaq Bitsy")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ BOOT_PARAMS(0xc0000100)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_BRUTUS
+MACHINE_START(BRUTUS, "Intel Brutus (SA1100 eval board)")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_CERF
+MACHINE_START(CERF, "Intrinsyc CerfBoard")
+ MAINTAINER("Pieter Truter")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_EMPEG
+MACHINE_START(EMPEG, "empeg MP3 Car Audio Player")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_GRAPHICSCLIENT
+MACHINE_START(GRAPHICSCLIENT, "ADS GraphicsClient")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_ITSY
+MACHINE_START(ITSY, "Compaq Itsy")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ BOOT_PARAMS(0xc0000100
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_LART
+MACHINE_START(LART, "LART")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_NANOENGINE
+MACHINE_START(NANOENGINE, "BSE nanoEngine")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_PLEB
+MACHINE_START(PLEB, "PLEB")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_THINCLIENT
+MACHINE_START(THINCLIENT, "ADS ThinClient")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_TIFON
+MACHINE_START(TIFON, "Tifon")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_VICTOR
+MACHINE_START(VICTOR, "VisuAide Victor")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
+#ifdef CONFIG_SA1100_XP860
+MACHINE_START(XP860, "XP860")
+ BOOT_MEM(0xc0000000, 0x80000000, 0xf8000000)
+ FIXUP(fixup_sa1100)
+ MAPIO(sa1100_map_io)
+MACHINE_END
+#endif
diff --git a/arch/arm/kernel/hw-sa1100.c b/arch/arm/mach-sa1100/hw.c
index 5acfab1e2..1ccc61fe3 100644
--- a/arch/arm/kernel/hw-sa1100.c
+++ b/arch/arm/mach-sa1100/hw.c
@@ -67,13 +67,13 @@ void __init get_assabet_scr(void)
{
unsigned long flags, scr, i;
- save_flags_cli(flags);
+ local_irq_save(flags);
GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */
GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */
GPDR &= ~(0x3fc); /* Configure GPIO 9:2 as inputs */
for(i = 100; i--; scr = GPLR); /* Read GPIO 9:2 */
GPDR |= 0x3fc; /* restore correct pin direction */
- restore_flags(flags);
+ local_irq_restore(flags);
scr &= 0x3fc; /* save as system configuration byte. */
SCR_value = scr;
@@ -81,10 +81,11 @@ void __init get_assabet_scr(void)
#endif /* CONFIG_SA1100_ASSABET */
+
+#if defined(CONFIG_SA1100_BITSY)
/*
* Bitsy has extended, write-only memory-mapped GPIO's
*/
-#if defined(CONFIG_SA1100_BITSY)
static int bitsy_egpio = EGPIO_BITSY_RS232_ON;
void clr_bitsy_egpio(unsigned long x)
{
@@ -100,9 +101,10 @@ EXPORT_SYMBOL(clr_bitsy_egpio);
EXPORT_SYMBOL(set_bitsy_egpio);
#endif
+
#ifdef CONFIG_SA1111
-void __init sa1111_init(void){
+static void __init sa1111_init(void){
unsigned long id=SKID;
if((id & SKID_ID_MASK) == SKID_SA1111_ID)
@@ -160,6 +162,8 @@ void __init sa1111_init(void){
}
}
+#else
+#define sa1111_init() printk( "Warning: missing SA1111 support\n" )
#endif
diff --git a/arch/arm/kernel/leds-sa1100.c b/arch/arm/mach-sa1100/leds.c
index fc4662c2a..be36e94a3 100644
--- a/arch/arm/kernel/leds-sa1100.c
+++ b/arch/arm/mach-sa1100/leds.c
@@ -55,7 +55,7 @@ static void assabet_leds_event(led_event_t evt)
{
unsigned long flags;
- save_flags_cli(flags);
+ local_irq_save(flags);
switch (evt) {
case led_start:
@@ -132,7 +132,7 @@ static void assabet_leds_event(led_event_t evt)
if (led_state & LED_STATE_ENABLED)
BCR = BCR_value = (BCR_value & ~BCR_LED_MASK) | hw_led_state;
- restore_flags(flags);
+ local_irq_restore(flags);
}
#endif /* CONFIG_SA1100_ASSABET */
@@ -148,7 +148,7 @@ static void brutus_leds_event(led_event_t evt)
{
unsigned long flags;
- save_flags_cli(flags);
+ local_irq_save(flags);
switch (evt) {
case led_start:
@@ -222,7 +222,7 @@ static void brutus_leds_event(led_event_t evt)
GPCR = hw_led_state ^ LED_MASK;
}
- restore_flags(flags);
+ local_irq_restore(flags);
}
#endif /* CONFIG_SA1100_BRUTUS */
@@ -237,7 +237,7 @@ static void lart_leds_event(led_event_t evt)
{
unsigned long flags;
- save_flags_cli(flags);
+ local_irq_save(flags);
switch(evt) {
case led_start:
@@ -301,7 +301,7 @@ static void lart_leds_event(led_event_t evt)
GPCR = hw_led_state ^ LED_MASK;
}
- restore_flags(flags);
+ local_irq_restore(flags);
}
#endif /* CONFIG_SA1100_LART */
@@ -317,7 +317,7 @@ static void cerf_leds_event(led_event_t evt)
{
unsigned long flags;
- save_flags_cli(flags);
+ local_irq_save(flags);
switch (evt) {
case led_start:
@@ -395,19 +395,11 @@ static void cerf_leds_event(led_event_t evt)
GPCR = hw_led_state ^ LED_MASK;
}
- restore_flags(flags);
+ local_irq_restore(flags);
}
#endif /* CONFIG_SA1100_CERF */
-static void dummy_leds_event(led_event_t evt)
-{
-}
-
-void (*leds_event)(led_event_t) = dummy_leds_event;
-
-EXPORT_SYMBOL(leds_event);
-
static int __init
sa1100_leds_init(void)
{
diff --git a/arch/arm/mach-shark/Makefile b/arch/arm/mach-shark/Makefile
new file mode 100644
index 000000000..414d0c2e1
--- /dev/null
+++ b/arch/arm/mach-shark/Makefile
@@ -0,0 +1,32 @@
+#
+# Makefile for the linux kernel.
+#
+# 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).
+
+O_TARGET := shark.o
+
+# Object file lists.
+
+obj-y := arch.o dma.o mm.o pci.o
+obj-m :=
+obj-n :=
+obj- :=
+
+export-objs :=
+
+#obj-$(CONFIG_LEDS) += leds.o
+
+# Files that are both resident and modular; remove from modular.
+
+obj-m := $(filter-out $(obj-y), $(obj-m))
+
+# Translate to Rules.make lists.
+
+O_OBJS := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS := $(filter $(export-objs), $(obj-y))
+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
+
+include $(TOPDIR)/Rules.make
diff --git a/arch/arm/mach-shark/arch.c b/arch/arm/mach-shark/arch.c
new file mode 100644
index 000000000..87ebe0270
--- /dev/null
+++ b/arch/arm/mach-shark/arch.c
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/arm/mach-shark/arch.c
+ *
+ * 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.
+ */
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/init.h>
+
+#include <asm/hardware/dec21285.h>
+#include <asm/elf.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+
+#include <asm/mach/arch.h>
+
+extern void setup_initrd(unsigned int start, unsigned int size);
+extern void setup_ramdisk(int doload, int prompt, int start, unsigned int rd_sz);
+extern void __init footbridge_map_io(void);
+extern void __init shark_map_io(void);
+
+MACHINE_START(SHARK, "Shark")
+ MAINTAINER("Alexander Schulz")
+ BOOT_MEM(0x08000000, 0x40000000, 0xe0000000)
+ VIDEO(0x06000000, 0x061fffff)
+ MAPIO(shark_map_io)
+MACHINE_END
diff --git a/arch/arm/mach-shark/dma.c b/arch/arm/mach-shark/dma.c
new file mode 100644
index 000000000..9e80dfb7b
--- /dev/null
+++ b/arch/arm/mach-shark/dma.c
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/arm/mach-shark/dma.c
+ *
+ * by Alexander.Schulz@stud.uni-karlsruhe.de
+ *
+ * derived from:
+ * arch/arm/kernel/dma-ebsa285.c
+ * Copyright (C) 1998 Phil Blundell
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+
+#include <asm/dma.h>
+#include <asm/io.h>
+
+#include <asm/mach/dma.h>
+
+void __init arch_dma_init(dma_t *dma)
+{
+#ifdef CONFIG_ISA_DMA
+ isa_init_dma(dma);
+#endif
+}
diff --git a/arch/arm/mach-shark/mm.c b/arch/arm/mach-shark/mm.c
new file mode 100644
index 000000000..f3092fb8a
--- /dev/null
+++ b/arch/arm/mach-shark/mm.c
@@ -0,0 +1,30 @@
+/*
+ * linux/arch/arm/mach-shark/mm.c
+ *
+ * by Alexander.Schulz@stud.uni-karlsruhe.de
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/pgtable.h>
+#include <asm/page.h>
+#include <asm/io.h>
+
+#include <asm/mach/map.h>
+
+static struct map_desc shark_io_desc[] __initdata = {
+ { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
+ { FB_BASE , FB_START , FB_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
+ { FBREG_BASE , FBREG_START , FBREG_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
+ LAST_DESC
+};
+
+void __init shark_map_io(void)
+{
+ iotable_init(shark_io_desc);
+}
diff --git a/arch/arm/mach-shark/pci.c b/arch/arm/mach-shark/pci.c
new file mode 100644
index 000000000..601922ce8
--- /dev/null
+++ b/arch/arm/mach-shark/pci.c
@@ -0,0 +1,27 @@
+/*
+ * linux/arch/arm/mach-shark/pci.c
+ *
+ * PCI bios-type initialisation for PCI machines
+ *
+ * Bits taken from various places.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+
+#include <asm/irq.h>
+#include <asm/mach/pci.h>
+
+static int __init shark_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ if (dev->bus->number == 0)
+ if (dev->devfn == 0) return 255;
+ else return 11;
+ else return 6;
+}
+
+struct hw_pci shark_pci __initdata = {
+ init: via82c505_init,
+ swizzle: no_swizzle,
+ map_irq: shark_map_irq
+};
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 075193467..fe3cf5eac 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -9,40 +9,61 @@
USE_STANDARD_AS_RULE := true
+EXTRA_AFLAGS := -traditional
O_TARGET := mm.o
-O_OBJS := extable.o fault-$(PROCESSOR).o init.o \
+
+# Object file lists.
+
+obj-y := extable.o fault-$(PROCESSOR).o init.o \
mm-$(PROCESSOR).o small_page.o
+obj-m :=
+obj-n :=
+obj- :=
+export-objs := proc-syms.o
-ifeq ($(CONFIG_CPU_26),y)
- O_OBJS += proc-arm2,3.o
-endif
+p-$(CONFIG_CPU_26) += proc-arm2,3.o
+p-$(CONFIG_CPU_ARM6) += proc-arm6,7.o
+p-$(CONFIG_CPU_ARM7) += proc-arm6,7.o
+p-$(CONFIG_CPU_ARM720) += proc-arm720.o
+p-$(CONFIG_CPU_ARM920) += proc-arm920.o
+p-$(CONFIG_CPU_ARM10) += proc-arm10.o
+p-$(CONFIG_CPU_SA110) += proc-sa110.o
+p-$(CONFIG_CPU_SA1100) += proc-sa110.o
+obj-$(CONFIG_CPU_32) += consistent.o ioremap.o
ifeq ($(CONFIG_CPU_32),y)
- ifeq ($(CONFIG_CPU_ARM6),y)
- P_OBJS += proc-arm6,7.o
- endif
- ifeq ($(CONFIG_CPU_ARM7),y)
- P_OBJS += proc-arm6,7.o
- endif
- ifeq ($(CONFIG_CPU_ARM720),y)
- P_OBJS += proc-arm720.o
- endif
- ifeq ($(CONFIG_CPU_SA110),y)
- P_OBJS += proc-sa110.o
- endif
- ifeq ($(CONFIG_CPU_SA1100),y)
- P_OBJS += proc-sa110.o
- endif
- O_OBJS += mm-$(MACHINE).o consistent.o ioremap.o $(sort $(P_OBJS))
+obj-$(CONFIG_MODULES) += proc-syms.o
+endif
+
+# Integrator follows "new style"
+# Soon, others will do too, and we can get rid of this
+MMMACH := mm-$(MACHINE).o
+ifeq ($(MMMACH),$(wildcard $(MMMACH)))
+obj-$(CONFIG_CPU_32) += $(MMMACH)
endif
+obj-y += $(sort $(p-y))
+
+# Files that are both resident and modular; remove from modular.
+
+obj-m := $(filter-out $(obj-y), $(obj-m))
+
+# Translate to Rules.make lists.
+
+O_OBJS := $(filter-out $(export-objs), $(obj-y))
+OX_OBJS := $(filter $(export-objs), $(obj-y))
+M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m)))
+MX_OBJS := $(sort $(filter $(export-objs), $(obj-m)))
+
include $(TOPDIR)/Rules.make
# Special dependencies
-fault-armv.o: fault-common.c
-fault-armo.o: fault-common.c
+fault-armv.o: fault-common.c
+fault-armo.o: fault-common.c
proc-arm2,3.o: ../lib/constants.h
proc-arm6,7.o: ../lib/constants.h
proc-arm720.o: ../lib/constants.h
+proc-arm920.o: ../lib/constants.h
+proc-arm10.o: ../lib/constants.h
proc-sa110.o: ../lib/constants.h
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index b21bc1d8a..4b06c4cad 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -1,5 +1,13 @@
/*
- * Dynamic DMA mapping support.
+ * linux/arch/arm/mm/consistent.c
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Dynamic DMA mapping support.
*/
#include <linux/config.h>
#include <linux/types.h>
@@ -43,18 +51,19 @@ void *consistent_alloc(int gfp, size_t size, dma_addr_t *dma_handle)
ret = __ioremap(virt_to_phys((void *)page), size, 0);
if (ret) {
/* free wasted pages */
- unsigned long end = page + (PAGE_SIZE << order);
+ unsigned long end;
/*
* we need to ensure that there are no
* cachelines in use, or worse dirty in
* this area.
*/
- dma_cache_inv(page, size);
- dma_cache_inv(ret, size);
+ invalidate_dcache_range(page, page + size);
+ invalidate_dcache_range((unsigned long)ret, (unsigned long)ret + size);
- *dma_handle = virt_to_bus((void *)page);
+ *dma_handle = __virt_to_bus(page);
+ end = page + (PAGE_SIZE << order);
page += size;
while (page < end) {
free_page(page);
@@ -102,17 +111,20 @@ void consistent_free(void *vaddr)
*/
void consistent_sync(void *vaddr, size_t size, int direction)
{
+ unsigned long start = (unsigned long)vaddr;
+ unsigned long end = start + size;
+
switch (direction) {
case PCI_DMA_NONE:
BUG();
case PCI_DMA_FROMDEVICE: /* invalidate only */
- dma_cache_inv(vaddr, size);
+ invalidate_dcache_range(start, end);
break;
case PCI_DMA_TODEVICE: /* writeback only */
- dma_cache_wback(vaddr, size);
+ clean_dcache_range(start, end);
break;
case PCI_DMA_BIDIRECTIONAL: /* writeback and invalidate */
- dma_cache_wback_inv(vaddr, size);
+ flush_dcache_range(start, end);
break;
}
}
diff --git a/arch/arm/mm/extable.c b/arch/arm/mm/extable.c
index e603b6362..e32d40c8e 100644
--- a/arch/arm/mm/extable.c
+++ b/arch/arm/mm/extable.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/arm/mm/extable.c
+ * linux/arch/arm/mm/extable.c
*/
#include <linux/config.h>
diff --git a/arch/arm/mm/fault-armo.c b/arch/arm/mm/fault-armo.c
index 19a1fff7c..85b2dc2f4 100644
--- a/arch/arm/mm/fault-armo.c
+++ b/arch/arm/mm/fault-armo.c
@@ -3,8 +3,11 @@
*
* Copyright (C) 1995 Linus Torvalds
* Modifications for ARM processor (c) 1995-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/kernel.h>
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index c3d03f251..f184b4e68 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -3,8 +3,11 @@
*
* Copyright (C) 1995 Linus Torvalds
* Modifications for ARM processor (c) 1995-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
-
#include <linux/config.h>
#include <linux/signal.h>
#include <linux/sched.h>
@@ -399,7 +402,11 @@ do_DataAbort(unsigned long addr, int error_code, struct pt_regs *regs, int fsr)
return;
bad:
force_sig(inf->sig, current);
- die_if_kernel(inf->name, regs, fsr);
+
+ printk(KERN_ALERT "Unhandled fault: %s (%X) at 0x%08lx\n",
+ inf->name, fsr, addr);
+ show_pte(current->mm, addr);
+ die_if_kernel("Oops", regs, 0);
return;
weirdness:
diff --git a/arch/arm/mm/fault-common.c b/arch/arm/mm/fault-common.c
index 519f1965a..0e198ab8a 100644
--- a/arch/arm/mm/fault-common.c
+++ b/arch/arm/mm/fault-common.c
@@ -3,6 +3,10 @@
*
* Copyright (C) 1995 Linus Torvalds
* Modifications for ARM processor (c) 1995-1999 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/config.h>
@@ -12,7 +16,7 @@ extern void die(const char *msg, struct pt_regs *regs, int err);
* This is useful to dump out the page tables associated with
* 'addr' in mm 'mm'.
*/
-static void show_pte(struct mm_struct *mm, unsigned long addr)
+void show_pte(struct mm_struct *mm, unsigned long addr)
{
pgd_t *pgd;
@@ -31,7 +35,7 @@ static void show_pte(struct mm_struct *mm, unsigned long addr)
break;
if (pgd_bad(*pgd)) {
- printk("(bad)\n");
+ printk("(bad)");
break;
}
@@ -42,7 +46,7 @@ static void show_pte(struct mm_struct *mm, unsigned long addr)
break;
if (pmd_bad(*pmd)) {
- printk("(bad)\n");
+ printk("(bad)");
break;
}
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index ba58e8bad..a235232d9 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -2,6 +2,10 @@
* linux/arch/arm/mm/init.c
*
* Copyright (C) 1995-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
*/
#include <linux/config.h>
#include <linux/signal.h>
@@ -27,7 +31,8 @@
#include <asm/hardware.h>
#include <asm/setup.h>
-#include "map.h"
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
#ifndef CONFIG_DISCONTIGMEM
#define NR_NODES 1
@@ -387,6 +392,12 @@ static inline void reserve_node_zero(unsigned int bootmap_pfn, unsigned int boot
*/
reserve_bootmem_node(0, __pa(swapper_pg_dir),
PTRS_PER_PGD * sizeof(void *));
+#else
+ /*
+ * Stop this memory from being grabbed - its special DMA
+ * memory that is required for the screen.
+ */
+ reserve_bootmem_node(0, 0x02000000, 0x00080000);
#endif
/*
* And don't forget to reserve the allocator bitmap,
@@ -466,7 +477,7 @@ void __init bootmem_init(struct meminfo *mi)
* paging_init() sets up the page tables, initialises the zone memory
* maps, and sets up the zero page, bad page and bad page tables.
*/
-void __init paging_init(struct meminfo *mi)
+void __init paging_init(struct meminfo *mi, struct machine_desc *mdesc)
{
void *zero_page, *bad_page, *bad_table;
int node;
@@ -474,16 +485,19 @@ void __init paging_init(struct meminfo *mi)
memcpy(&meminfo, mi, sizeof(meminfo));
/*
- * allocate what we need for the bad pages
+ * allocate what we need for the bad pages.
+ * note that we count on this going ok.
*/
zero_page = alloc_bootmem_low_pages(PAGE_SIZE);
bad_page = alloc_bootmem_low_pages(PAGE_SIZE);
bad_table = alloc_bootmem_low_pages(TABLE_SIZE);
/*
- * initialise the page tables
+ * initialise the page tables.
*/
- pagetable_init(mi);
+ memtable_init(mi);
+ if (mdesc->map_io)
+ mdesc->map_io();
flush_tlb_all();
/*
@@ -528,7 +542,7 @@ void __init paging_init(struct meminfo *mi)
zhole_size[0] -= mi->bank[i].size >> PAGE_SHIFT;
}
- free_area_init_node(node, pgdat, zone_size,
+ free_area_init_node(node, pgdat, 0, zone_size,
bdata->node_boot_start, zhole_size);
}
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index d59b4e16c..e90c25018 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -1,5 +1,5 @@
/*
- * arch/arm/mm/ioremap.c
+ * linux/arch/arm/mm/ioremap.c
*
* Re-map IO memory to kernel address space so that we can access it.
*
diff --git a/arch/arm/mm/map.h b/arch/arm/mm/map.h
deleted file mode 100644
index 1d071748d..000000000
--- a/arch/arm/mm/map.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * linux/arch/arm/mm/map.h
- *
- * Copyright (C) 1999 Russell King
- *
- * Page table mapping constructs and function prototypes
- */
-struct map_desc {
- unsigned long virtual;
- unsigned long physical;
- unsigned long length;
- int domain:4,
- prot_read:1,
- prot_write:1,
- cacheable:1,
- bufferable:1;
-};
-
-extern struct map_desc io_desc[];
-extern unsigned int io_desc_size;
-
-struct meminfo;
-
-extern void create_memmap_holes(struct meminfo *);
-extern void pagetable_init(struct meminfo *);
diff --git a/arch/arm/mm/mm-armo.c b/arch/arm/mm/mm-armo.c
index dc1647a2d..9a426fc18 100644
--- a/arch/arm/mm/mm-armo.c
+++ b/arch/arm/mm/mm-armo.c
@@ -1,9 +1,13 @@
/*
- * arch/arm/mm/mm-armo.c
+ * linux/arch/arm/mm/mm-armo.c
*
- * Page table sludge for older ARM processor architectures.
+ * Copyright (C) 1998-2000 Russell King
*
- * Copyright (C) 1998-2000 Russell King
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Page table sludge for older ARM processor architectures.
*/
#include <linux/sched.h>
#include <linux/mm.h>
@@ -15,7 +19,7 @@
#include <asm/page.h>
#include <asm/arch/memory.h>
-#include "map.h"
+#include <asm/mach/map.h>
#define MEMC_TABLE_SIZE (256*sizeof(unsigned long))
#define PGD_TABLE_SIZE (PTRS_PER_PGD * BYTES_PER_PTR)
@@ -147,7 +151,7 @@ void setup_mm_for_reboot(char mode)
* some more work to get it to fit into our separate processor and
* architecture structure.
*/
-void __init pagetable_init(struct meminfo *mi)
+void __init memtable_init(struct meminfo *mi)
{
pte_t *pte;
int i;
@@ -162,6 +166,11 @@ void __init pagetable_init(struct meminfo *mi)
pgd_val(swapper_pg_dir[i]) = 0;
}
+void __init iotable_init(struct map_desc *io_desc)
+{
+ /* nothing to do */
+}
+
/*
* We never have holes in the memmap
*/
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
index e656a25d2..9ddcc84bc 100644
--- a/arch/arm/mm/mm-armv.c
+++ b/arch/arm/mm/mm-armv.c
@@ -1,9 +1,13 @@
/*
* linux/arch/arm/mm/mm-armv.c
*
- * Page table sludge for ARM v3 and v4 processor architectures.
- *
* Copyright (C) 1998-2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Page table sludge for ARM v3 and v4 processor architectures.
*/
#include <linux/sched.h>
#include <linux/mm.h>
@@ -16,7 +20,7 @@
#include <asm/io.h>
#include <asm/setup.h>
-#include "map.h"
+#include <asm/mach/map.h>
unsigned long *valid_addr_bitmap;
@@ -62,6 +66,10 @@ __setup("nowb", nowrite_setup);
#define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD)
+#define clean_cache_area(start,size) \
+ cpu_cache_clean_invalidate_range((unsigned long)start, ((unsigned long)start) + size, 0);
+
+
/*
* need to get a 16k page for level 1
*/
@@ -72,10 +80,13 @@ pgd_t *get_pgd_slow(void)
if (pgd) {
pgd_t *init = pgd_offset_k(0);
-
+
memzero(pgd, FIRST_KERNEL_PGD_NR * sizeof(pgd_t));
memcpy(pgd + FIRST_KERNEL_PGD_NR, init + FIRST_KERNEL_PGD_NR,
(PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t));
+ /*
+ * FIXME: this should not be necessary
+ */
clean_cache_area(pgd, PTRS_PER_PGD * sizeof(pgd_t));
/*
@@ -310,18 +321,17 @@ void setup_mm_for_reboot(char mode)
}
}
-void __init pagetable_init(struct meminfo *mi)
+/*
+ * Setup initial mappings. We use the page we allocated for zero page to hold
+ * the mappings, which will get overwritten by the vectors in traps_init().
+ * The mappings must be in virtual address order.
+ */
+void __init memtable_init(struct meminfo *mi)
{
struct map_desc *init_maps, *p, *q;
unsigned long address = 0;
int i;
- /*
- * Setup initial mappings. We use the page we allocated
- * for zero page to hold the mappings, which will get
- * overwritten by the vectors in traps_init(). The
- * mappings must be in virtual address order.
- */
init_maps = p = alloc_bootmem_low_pages(PAGE_SIZE);
p->physical = virt_to_phys(init_maps);
@@ -401,16 +411,21 @@ void __init pagetable_init(struct meminfo *mi)
}
} while (address != 0);
- /*
- * Create the architecture specific mappings
- */
- for (i = 0; i < io_desc_size; i++)
- create_mapping(io_desc + i);
-
flush_cache_all();
}
-static inline void free_memmap(unsigned long start, unsigned long end)
+/*
+ * Create the architecture specific mappings
+ */
+void __init iotable_init(struct map_desc *io_desc)
+{
+ int i;
+
+ for (i = 0; io_desc[i].last == 0; i++)
+ create_mapping(io_desc + i);
+}
+
+static inline void free_memmap(int node, unsigned long start, unsigned long end)
{
unsigned long pg, pgend;
@@ -422,10 +437,8 @@ static inline void free_memmap(unsigned long start, unsigned long end)
start = __virt_to_phys(pg);
end = __virt_to_phys(pgend);
- /*
- * The mem_map is always stored in node 0
- */
- free_bootmem_node(0, start, end - start);
+
+ free_bootmem_node(node, start, end - start);
}
static inline void free_unused_memmap_node(int node, struct meminfo *mi)
@@ -449,7 +462,7 @@ static inline void free_unused_memmap_node(int node, struct meminfo *mi)
* between the current bank and the previous, free it.
*/
if (prev_bank_end && prev_bank_end != bank_start)
- free_memmap(prev_bank_end, bank_start);
+ free_memmap(node, prev_bank_end, bank_start);
prev_bank_end = PAGE_ALIGN(mi->bank[i].start +
mi->bank[i].size);
diff --git a/arch/arm/mm/mm-clps7500.c b/arch/arm/mm/mm-clps7500.c
index b9199de80..765367c47 100644
--- a/arch/arm/mm/mm-clps7500.c
+++ b/arch/arm/mm/mm-clps7500.c
@@ -1,12 +1,11 @@
/*
- * arch/arm/mm/mm-cl7500.c
+ * linux/arch/arm/mm/mm-cl7500.c
*
- * Extra MM routines for CL7500 architecture
+ * Copyright (C) 1998 Russell King
+ * Copyright (C) 1999 Nexus Electronics Ltd
*
- * Copyright (C) 1998 Russell King
- * Copyright (C) 1999 Nexus Electronics Ltd
+ * Extra MM routines for CL7500 architecture
*/
-
#include <linux/init.h>
#include <asm/hardware.h>
@@ -14,15 +13,17 @@
#include <asm/proc/domain.h>
#include <asm/setup.h>
-#include "map.h"
-
-#define SIZE(x) (sizeof(x) / sizeof(x[0]))
+#include <asm/mach/map.h>
-struct map_desc io_desc[] __initdata = {
+static struct map_desc cl7500_io_desc[] __initdata = {
{ IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1 }, /* IO space */
{ ISA_BASE, ISA_START, ISA_SIZE , DOMAIN_IO, 0, 1 }, /* ISA space */
{ FLASH_BASE, FLASH_START, FLASH_SIZE, DOMAIN_IO, 0, 1 }, /* Flash */
- { LED_BASE, LED_START, LED_SIZE , DOMAIN_IO, 0, 1 } /* LED */
+ { LED_BASE, LED_START, LED_SIZE , DOMAIN_IO, 0, 1 }, /* LED */
+ LAST_DESC
};
-unsigned int __initdata io_desc_size = SIZE(io_desc);
+void __init clps7500_map_io(void)
+{
+ iotable_init(cl7500_io_desc);
+}
diff --git a/arch/arm/mm/mm-ebsa110.c b/arch/arm/mm/mm-ebsa110.c
index f16c93793..9402dfb8f 100644
--- a/arch/arm/mm/mm-ebsa110.c
+++ b/arch/arm/mm/mm-ebsa110.c
@@ -1,9 +1,13 @@
/*
- * arch/arm/mm/mm-ebsa110.c
+ * linux/arch/arm/mm/mm-ebsa110.c
*
- * Extra MM routines for the EBSA-110 architecture
+ * Copyright (C) 1998-1999 Russell King
*
- * Copyright (C) 1998-1999 Russell King
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Extra MM routines for the EBSA-110 architecture
*/
#include <linux/mm.h>
#include <linux/init.h>
@@ -12,13 +16,15 @@
#include <asm/pgtable.h>
#include <asm/page.h>
-#include "map.h"
+#include <asm/mach/map.h>
-#define SIZE(x) (sizeof(x) / sizeof(x[0]))
-
-struct map_desc io_desc[] __initdata = {
+static struct map_desc ebsa110_io_desc[] __initdata = {
{ IO_BASE - PGDIR_SIZE, 0xc0000000, PGDIR_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
- { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }
+ { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
+ LAST_DESC
};
-unsigned int __initdata io_desc_size = SIZE(io_desc);
+void __init ebsa110_map_io(void)
+{
+ iotable_init(ebsa110_io_desc);
+}
diff --git a/arch/arm/mm/mm-footbridge.c b/arch/arm/mm/mm-footbridge.c
index 2c555f46d..b0eff7485 100644
--- a/arch/arm/mm/mm-footbridge.c
+++ b/arch/arm/mm/mm-footbridge.c
@@ -1,9 +1,13 @@
/*
- * arch/arm/mm/mm-footbridge.c
+ * linux/arch/arm/mm/mm-footbridge.c
*
- * Extra MM routines for the EBSA285 architecture
+ * Copyright (C) 1998-2000 Russell King, Dave Gilbert.
*
- * Copyright (C) 1998-1999 Russell King, Dave Gilbert.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Extra MM routines for the EBSA285 architecture
*/
#include <linux/config.h>
#include <linux/sched.h>
@@ -13,73 +17,83 @@
#include <asm/pgtable.h>
#include <asm/page.h>
#include <asm/io.h>
-#include <asm/dec21285.h>
-
-#include "map.h"
+#include <asm/hardware/dec21285.h>
+#include <asm/mach-types.h>
-#define SIZE(x) (sizeof(x) / sizeof(x[0]))
+#include <asm/mach/map.h>
/*
- * The first entry allows us to fiddle with the EEPROM from user-space.
- * This entry will go away in time, once the fmu32 can mmap() the
- * flash. It can't at the moment.
- *
- * If you want to fiddle with PCI VGA cards from user space, then
- * change the '0, 1 }' for the PCI MEM and PCI IO to '1, 1 }'
- * You can then access the PCI bus at 0xe0000000 and 0xffe00000.
+ * Common mapping for all systems. Note that the outbound write flush is
+ * commented out since there is a "No Fix" problem with it. Not mapping
+ * it means that we have extra bullet protection on our feet.
*/
-
-#ifdef CONFIG_FOOTBRIDGE_HOST
+static struct map_desc fb_common_io_desc[] __initdata = {
+ { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
+ { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
+ LAST_DESC
+};
/*
- * The mapping when the footbridge is in host mode.
+ * The mapping when the footbridge is in host mode. We don't map any of
+ * this when we are in add-in mode.
*/
-#define MAPPING \
- { FLASH_BASE, DC21285_FLASH, FLASH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { PCIIACK_BASE, DC21285_PCI_IACK, PCIIACK_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { WFLUSH_BASE, DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 }
-
-#else
+static struct map_desc ebsa285_host_io_desc[] __initdata = {
+#if defined(CONFIG_ARCH_FOOTBRIDGE) && defined(CONFIG_FOOTBRIDGE_HOST)
+ { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
+ { PCICFG0_BASE, DC21285_PCI_TYPE_0_CONFIG, PCICFG0_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
+ { PCICFG1_BASE, DC21285_PCI_TYPE_1_CONFIG, PCICFG1_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
+ { PCIIACK_BASE, DC21285_PCI_IACK, PCIIACK_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
+ { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
+#endif
+ LAST_DESC
+};
/*
- * The mapping when the footbridge is in add-in mode.
+ * The CO-ebsa285 mapping.
*/
-#define MAPPING \
- { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { XBUS_BASE, 0x40000000, XBUS_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { ARMCSR_BASE, DC21285_ARMCSR_BASE, ARMCSR_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { WFLUSH_BASE, DC21285_OUTBOUND_WRITE_FLUSH, WFLUSH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { FLASH_BASE, DC21285_FLASH, FLASH_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, \
- { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 }
-
+static struct map_desc co285_io_desc[] __initdata = {
+#ifdef CONFIG_ARCH_CO285
+ { PCIO_BASE, DC21285_PCI_IO, PCIO_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
+ { PCIMEM_BASE, DC21285_PCI_MEM, PCIMEM_SIZE, DOMAIN_IO, 0, 1, 0, 0 },
#endif
-
-struct map_desc io_desc[] __initdata = {
- MAPPING
+ LAST_DESC
};
-unsigned int __initdata io_desc_size = SIZE(io_desc);
-
+void __init footbridge_map_io(void)
+{
+ struct map_desc *desc = NULL;
+
+ /*
+ * Set up the common mapping first; we need this to
+ * determine whether we're in host mode or not.
+ */
+ iotable_init(fb_common_io_desc);
+
+ /*
+ * Now, work out what we've got to map in addition on this
+ * platform.
+ */
+ if (machine_is_co285())
+ desc = co285_io_desc;
+ else if (footbridge_cfn_mode())
+ desc = ebsa285_host_io_desc;
+
+ if (desc)
+ iotable_init(desc);
+}
#ifdef CONFIG_FOOTBRIDGE_ADDIN
/*
- * These two functions convert virtual addresses to PCI addresses
- * and PCI addresses to virtual addresses. Note that it is only
- * legal to use these on memory obtained via get_free_page or
- * kmalloc.
+ * These two functions convert virtual addresses to PCI addresses and PCI
+ * addresses to virtual addresses. Note that it is only legal to use these
+ * on memory obtained via get_free_page or kmalloc.
*/
unsigned long __virt_to_bus(unsigned long res)
{
#ifdef CONFIG_DEBUG_ERRORS
if (res < PAGE_OFFSET || res >= (unsigned long)high_memory) {
- printk("__virt_to_phys: invalid virtual address 0x%08lx\n", res);
+ printk("__virt_to_bus: invalid virtual address 0x%08lx\n", res);
__backtrace();
}
#endif
@@ -93,7 +107,7 @@ unsigned long __bus_to_virt(unsigned long res)
#ifdef CONFIG_DEBUG_ERRORS
if (res < PAGE_OFFSET || res >= (unsigned long)high_memory) {
- printk("__phys_to_virt: invalid virtual address 0x%08lx\n", res);
+ printk("__bus_to_virt: invalid virtual address 0x%08lx\n", res);
__backtrace();
}
#endif
diff --git a/arch/arm/mm/mm-l7200.c b/arch/arm/mm/mm-l7200.c
index 8a252d684..bd7c6e2dd 100644
--- a/arch/arm/mm/mm-l7200.c
+++ b/arch/arm/mm/mm-l7200.c
@@ -1,11 +1,10 @@
/*
- * arch/arm/mm/mm-lusl7200.c
+ * linux/arch/arm/mm/mm-lusl7200.c
*
- * Extra MM routines for L7200 architecture
+ * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
*
- * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
+ * Extra MM routines for L7200 architecture
*/
-
#include <linux/init.h>
#include <asm/hardware.h>
@@ -13,13 +12,15 @@
#include <asm/proc/domain.h>
#include <asm/setup.h>
-#include "map.h"
-
-#define SIZE(x) (sizeof(x) / sizeof(x[0]))
+#include <asm/mach/map.h>
-struct map_desc io_desc[] __initdata = {
+static struct map_desc l7200_io_desc[] __initdata = {
{ IO_BASE, IO_START, IO_SIZE, DOMAIN_IO, 0, 1 ,0 ,0},
{ IO_BASE_2, IO_START_2, IO_SIZE_2, DOMAIN_IO, 0, 1 ,0 ,0},
+ LAST_DESC
};
-unsigned int __initdata io_desc_size = SIZE(io_desc);
+void __init l7200_map_io(void)
+{
+ iotable_init(l7200_io_desc);
+}
diff --git a/arch/arm/mm/mm-nexuspci.c b/arch/arm/mm/mm-nexuspci.c
index ccb6c8a5c..31d619433 100644
--- a/arch/arm/mm/mm-nexuspci.c
+++ b/arch/arm/mm/mm-nexuspci.c
@@ -1,13 +1,12 @@
/*
- * arch/arm/mm/mm-nexuspci.c
- * from arch/arm/mm/mm-ebsa110.c
+ * linux/arch/arm/mm/mm-nexuspci.c
+ * from linux/arch/arm/mm/mm-ebsa110.c
*
- * Extra MM routines for the FTV/PCI architecture
+ * Copyright (C) 1998-1999 Phil Blundell
+ * Copyright (C) 1998-1999 Russell King
*
- * Copyright (C) 1998-1999 Phil Blundell
- * Copyright (C) 1998-1999 Russell King
+ * Extra MM routines for the FTV/PCI architecture
*/
-
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/init.h>
@@ -16,16 +15,18 @@
#include <asm/page.h>
#include <asm/io.h>
-#include "map.h"
-
-struct map_desc io_desc[] __initdata = {
+#include <asm/mach/map.h>
+
+static struct map_desc nexuspci_io_desc[] __initdata = {
{ INTCONT_BASE, INTCONT_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
{ PLX_BASE, PLX_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
{ PCIO_BASE, PLX_IO_START, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 },
{ DUART_BASE, DUART_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { STATUS_BASE, STATUS_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }
+ { STATUS_BASE, STATUS_START, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
+ LAST_DESC
};
-#define SIZE(x) (sizeof(x) / sizeof(x[0]))
-
-unsigned int __initdata io_desc_size = SIZE(io_desc);
+void __init nexuspci_map_io(void)
+{
+ iotable_init(nexuspci_io_desc);
+}
diff --git a/arch/arm/mm/mm-rpc.c b/arch/arm/mm/mm-rpc.c
index 494a61988..023fee8e0 100644
--- a/arch/arm/mm/mm-rpc.c
+++ b/arch/arm/mm/mm-rpc.c
@@ -1,9 +1,13 @@
/*
- * arch/arm/mm/mm-rpc.c
+ * linux/arch/arm/mm/mm-rpc.c
*
- * Extra MM routines for RiscPC architecture
+ * Copyright (C) 1998-1999 Russell King
*
- * Copyright (C) 1998-1999 Russell King
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Extra MM routines for RiscPC architecture
*/
#include <linux/init.h>
@@ -12,17 +16,16 @@
#include <asm/proc/domain.h>
#include <asm/setup.h>
-#include "map.h"
-
-#define SIZE(x) (sizeof(x) / sizeof(x[0]))
+#include <asm/mach/map.h>
-struct map_desc io_desc[] __initdata = {
- /* VRAM */
- { SCREEN_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 },
- /* IO space */
- { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
- /* EASI space */
- { EASI_BASE, EASI_START, EASI_SIZE, DOMAIN_IO, 0, 1, 0, 0 }
+static struct map_desc rpc_io_desc[] __initdata = {
+ { SCREEN_BASE, SCREEN_START, 2*1048576, DOMAIN_IO, 0, 1, 0, 0 }, /* VRAM */
+ { IO_BASE, IO_START, IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 }, /* IO space */
+ { EASI_BASE, EASI_START, EASI_SIZE, DOMAIN_IO, 0, 1, 0, 0 }, /* EASI space */
+ LAST_DESC
};
-unsigned int __initdata io_desc_size = SIZE(io_desc);
+void __init rpc_map_io(void)
+{
+ iotable_init(rpc_io_desc);
+}
diff --git a/arch/arm/mm/mm-sa1100.c b/arch/arm/mm/mm-sa1100.c
index aaf28f880..54fe435c6 100644
--- a/arch/arm/mm/mm-sa1100.c
+++ b/arch/arm/mm/mm-sa1100.c
@@ -1,20 +1,19 @@
/*
- * arch/arm/mm/mm-sa1100.c
+ * linux/arch/arm/mm/mm-sa1100.c
*
- * Extra MM routines for the SA1100 architecture
+ * Copyright (C) 1998-1999 Russell King
+ * Copyright (C) 1999 Hugo Fiennes
*
- * Copyright (C) 1998-1999 Russell King
- * Copyright (C) 1999 Hugo Fiennes
+ * Extra MM routines for the SA1100 architecture
*
- * 1999/12/04 Nicolas Pitre <nico@cam.org>
+ * 1999/12/04 Nicolas Pitre <nico@cam.org>
* Converted memory definition for struct meminfo initialisations.
* Memory is listed physically now.
*
- * 2000/04/07 Nicolas Pitre <nico@cam.org>
+ * 2000/04/07 Nicolas Pitre <nico@cam.org>
* Reworked for run-time selection of memory definitions
*
*/
-
#include <linux/config.h>
#include <linux/mm.h>
#include <linux/init.h>
@@ -25,171 +24,158 @@
#include <asm/page.h>
#include <asm/mach-types.h>
-#include "map.h"
+#include <asm/mach/map.h>
-#define SIZE(x) (sizeof(x) / sizeof(x[0]))
-
-
-#define SA1100_STD_IO_MAPPING \
+static struct map_desc standard_io_desc[] __initdata = {
/* virtual physical length domain r w c b */ \
- { 0xe0000000, 0x20000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 IO */ \
- { 0xe4000000, 0x30000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 IO */ \
- { 0xe8000000, 0x28000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 attr */ \
- { 0xec000000, 0x38000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 attr */ \
- { 0xf0000000, 0x2c000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 mem */ \
- { 0xf4000000, 0x3c000000, 0x04000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 mem */ \
- { 0xf8000000, 0x80000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCM */ \
- { 0xfa000000, 0x90000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCM */ \
- { 0xfc000000, 0xa0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* MER */ \
- { 0xfe000000, 0xb0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 } /* LCD + DMA */
+ { 0xf6000000, 0x20000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA0 IO */
+ { 0xf7000000, 0x30000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* PCMCIA1 IO */
+ { 0xf8000000, 0x80000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* PCM */
+ { 0xfa000000, 0x90000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* SCM */
+ { 0xfc000000, 0xa0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* MER */
+ { 0xfe000000, 0xb0000000, 0x02000000, DOMAIN_IO, 0, 1, 0, 0 }, /* LCD + DMA */
+ LAST_DESC
+};
+/*
+ * Typically, static virtual address mappings are as follow:
+ *
+ * 0xe8000000-0xefffffff: flash memory (especially when multiple flash
+ * banks need to be mapped contigously)
+ * 0xf0000000-0xf3ffffff: miscellaneous stuff (CPLDs, etc.)
+ * 0xf4000000-0xf4ffffff: SA-1111
+ * 0xf5000000-0xf5ffffff: reserved (used by cache flushing area)
+ * 0xf6000000-0xffffffff: reserved (internal SA1100 IO defined above)
+ *
+ * Below 0xe8000000 is reserved for vm allocation.
+ */
static struct map_desc assabet_io_desc[] __initdata = {
#ifdef CONFIG_SA1100_ASSABET
- { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
- { 0xd4000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */
- { 0xdc000000, 0x12000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Board Control Register */
- { 0xd8000000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
- SA1100_STD_IO_MAPPING
-#endif
-};
-
-static struct map_desc nanoengine_io_desc[] __initdata = {
-#ifdef CONFIG_SA1100_NANOENGINE
- { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
- { 0xd4000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */
- { 0xdc000000, 0x18A00000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Internal PCI Config Space */
- SA1100_STD_IO_MAPPING
+ { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
+ { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */
+ { 0xf1000000, 0x12000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Board Control Register */
+ { 0xf2800000, 0x4b800000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* MQ200 */
+ { 0xf4000000, 0x40000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
#endif
+ LAST_DESC
};
static struct map_desc bitsy_io_desc[] __initdata = {
#ifdef CONFIG_SA1100_BITSY
- { 0xd0000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
- { 0xdc000000, 0x49000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* EGPIO 0 */
- SA1100_STD_IO_MAPPING
+ { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
+ { 0xf0000000, 0x49000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* EGPIO 0 */
#endif
+ LAST_DESC
};
static struct map_desc cerf_io_desc[] __initdata = {
#ifdef CONFIG_SA1100_CERF
- { 0xd8000000, 0x08000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Crystal Chip */
- { 0xd0000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
- SA1100_STD_IO_MAPPING
+ { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
+ { 0xf0000000, 0x08000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Crystal Chip */
#endif
+ LAST_DESC
};
static struct map_desc empeg_io_desc[] __initdata = {
#ifdef CONFIG_SA1100_EMPEG
{ EMPEG_FLASHBASE, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */
- SA1100_STD_IO_MAPPING
#endif
+ LAST_DESC
};
static struct map_desc graphicsclient_io_desc[] __initdata = {
#ifdef CONFIG_SA1100_GRAPHICSCLIENT
- { 0xd0000000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
- { 0xd0800000, 0x18000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 3 */
- { 0xdc000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
- SA1100_STD_IO_MAPPING
+ { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+ { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
#endif
+ LAST_DESC
};
static struct map_desc lart_io_desc[] __initdata = {
#ifdef CONFIG_SA1100_LART
- { 0xd0000000, 0x00000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash memory */
- { 0xd8000000, 0x08000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash, alternative location */
- SA1100_STD_IO_MAPPING
+ { 0xe8000000, 0x00000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash memory */
+ { 0xec000000, 0x08000000, 0x00400000, DOMAIN_IO, 1, 1, 0, 0 }, /* main flash, alternative location */
#endif
+ LAST_DESC
+};
+
+static struct map_desc nanoengine_io_desc[] __initdata = {
+#ifdef CONFIG_SA1100_NANOENGINE
+ { 0xe8000000, 0x00000000, 0x02000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 */
+ { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* System Registers */
+ { 0xf1000000, 0x18A00000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* Internal PCI Config Space */
+#endif
+ LAST_DESC
};
static struct map_desc thinclient_io_desc[] __initdata = {
#ifdef CONFIG_SA1100_THINCLIENT
#if 0
- { 0xd0000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 when JP1 2-4 */
+ { 0xe8000000, 0x00000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 0 when JP1 2-4 */
#else
- { 0xd0000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 when JP1 3-4 */
+ { 0xe8000000, 0x08000000, 0x01000000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 when JP1 3-4 */
#endif
- { 0xdc000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
- SA1100_STD_IO_MAPPING
+ { 0xf0000000, 0x10000000, 0x00400000, DOMAIN_IO, 0, 1, 0, 0 }, /* CPLD */
#endif
+ LAST_DESC
};
static struct map_desc tifon_io_desc[] __initdata = {
#ifdef CONFIG_SA1100_TIFON
- { 0xd0000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
- { 0xd0800000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 2 */
- SA1100_STD_IO_MAPPING
+ { 0xe8000000, 0x00000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 1 */
+ { 0xe8800000, 0x08000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash bank 2 */
#endif
+ LAST_DESC
};
static struct map_desc victor_io_desc[] __initdata = {
#ifdef CONFIG_SA1100_VICTOR
- { 0xd0000000, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */
- SA1100_STD_IO_MAPPING
+ { 0xe8000000, 0x00000000, 0x00200000, DOMAIN_IO, 1, 1, 0, 0 }, /* Flash */
#endif
+ LAST_DESC
};
static struct map_desc xp860_io_desc[] __initdata = {
#ifdef CONFIG_SA1100_XP860
- { 0xd8000000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
- { 0xda000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SCSI */
- { 0xdc000000, 0x18000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* LAN */
- SA1100_STD_IO_MAPPING
+ { 0xf4000000, 0x40000000, 0x00800000, DOMAIN_IO, 1, 1, 0, 0 }, /* SA-1111 */
+ { 0xf0000000, 0x10000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* SCSI */
+ { 0xf1000000, 0x18000000, 0x00100000, DOMAIN_IO, 1, 1, 0, 0 }, /* LAN */
#endif
+ LAST_DESC
};
-static struct map_desc default_io_desc[] __initdata = {
- SA1100_STD_IO_MAPPING
-};
-
-
-/*
- * Here it would be wiser to simply assign a pointer to the appropriate
- * list, but io_desc is already declared as an array in "map.h".
- */
-struct map_desc io_desc[20] __initdata = {};
-unsigned int io_desc_size;
-
-void __init select_sa1100_io_desc(void)
+void __init sa1100_map_io(void)
{
- if( machine_is_assabet() ) {
- memcpy( io_desc, assabet_io_desc, sizeof(assabet_io_desc) );
- io_desc_size = SIZE(assabet_io_desc);
- } else if( machine_is_nanoengine() ) {
- memcpy( io_desc, nanoengine_io_desc, sizeof(nanoengine_io_desc) );
- io_desc_size = SIZE(nanoengine_io_desc);
- } else if( machine_is_bitsy() ) {
- memcpy( io_desc, bitsy_io_desc, sizeof(bitsy_io_desc) );
- io_desc_size = SIZE(bitsy_io_desc);
- } else if( machine_is_cerf() ) {
- memcpy( io_desc, cerf_io_desc, sizeof(cerf_io_desc) );
- io_desc_size = SIZE(cerf_io_desc);
- } else if( machine_is_empeg() ) {
- memcpy( io_desc, empeg_io_desc, sizeof(empeg_io_desc) );
- io_desc_size = SIZE(empeg_io_desc);
- } else if( machine_is_graphicsclient() ) {
- memcpy( io_desc, graphicsclient_io_desc, sizeof(graphicsclient_io_desc) );
- io_desc_size = SIZE(graphicsclient_io_desc);
- } else if( machine_is_lart() ) {
- memcpy( io_desc, lart_io_desc, sizeof(lart_io_desc) );
- io_desc_size = SIZE(lart_io_desc);
- } else if( machine_is_thinclient() ) {
- memcpy( io_desc, thinclient_io_desc, sizeof(thinclient_io_desc) );
- io_desc_size = SIZE(thinclient_io_desc);
- } else if( machine_is_tifon() ) {
- memcpy( io_desc, tifon_io_desc, sizeof(tifon_io_desc) );
- io_desc_size = SIZE(tifon_io_desc);
- } else if( machine_is_victor() ) {
- memcpy( io_desc, victor_io_desc, sizeof(victor_io_desc) );
- io_desc_size = SIZE(victor_io_desc);
- } else if( machine_is_xp860() ) {
- memcpy( io_desc, xp860_io_desc, sizeof(xp860_io_desc) );
- io_desc_size = SIZE(xp860_io_desc);
- } else {
- memcpy( io_desc, default_io_desc, sizeof(default_io_desc) );
- io_desc_size = SIZE(default_io_desc);
- }
+ struct map_desc *desc = NULL;
+
+ iotable_init(standard_io_desc);
+
+ if (machine_is_assabet())
+ desc = assabet_io_desc;
+ else if (machine_is_nanoengine())
+ desc = nanoengine_io_desc;
+ else if (machine_is_bitsy())
+ desc = bitsy_io_desc;
+ else if (machine_is_cerf())
+ desc = cerf_io_desc;
+ else if (machine_is_empeg())
+ desc = empeg_io_desc;
+ else if (machine_is_graphicsclient())
+ desc = graphicsclient_io_desc;
+ else if (machine_is_lart())
+ desc = lart_io_desc;
+ else if (machine_is_thinclient())
+ desc = thinclient_io_desc;
+ else if (machine_is_tifon())
+ desc = tifon_io_desc;
+ else if (machine_is_victor())
+ desc = victor_io_desc;
+ else if (machine_is_xp860())
+ desc = xp860_io_desc;
+
+ if (desc)
+ iotable_init(desc);
}
diff --git a/arch/arm/mm/mm-shark.c b/arch/arm/mm/mm-shark.c
deleted file mode 100644
index dc8e6e12b..000000000
--- a/arch/arm/mm/mm-shark.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * arch/arm/mm/mm-shark.c
- *
- * by Alexander.Schulz@stud.uni-karlsruhe.de
- */
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/init.h>
-
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/io.h>
-
-#include "map.h"
-
-struct map_desc io_desc[] __initdata = {
- { IO_BASE , IO_START , IO_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
- { FB_BASE , FB_START , FB_SIZE , DOMAIN_IO, 0, 1, 0, 0 },
- { FBREG_BASE , FBREG_START , FBREG_SIZE , DOMAIN_IO, 0, 1, 0, 0 }
-};
-
-
-#define SIZEOFMAP (sizeof(io_desc) / sizeof(io_desc[0]))
-
-unsigned int __initdata io_desc_size = SIZEOFMAP;
diff --git a/arch/arm/mm/mm-tbox.c b/arch/arm/mm/mm-tbox.c
index 78250336e..e927d05d3 100644
--- a/arch/arm/mm/mm-tbox.c
+++ b/arch/arm/mm/mm-tbox.c
@@ -1,13 +1,11 @@
/*
- * arch/arm/mm/mm-tbox.c
- * from arch/arm/mm/mm-ebsa110.c
+ * linux/arch/arm/mm/mm-tbox.c
*
- * Extra MM routines for the Tbox architecture
+ * Copyright (C) 1998, 1999, 2000 Phil Blundell
+ * Copyright (C) 1998-1999 Russell King
*
- * Copyright (C) 1998 Phil Blundell
- * Copyright (C) 1998-1999 Russell King
+ * Extra MM routines for the Tbox architecture
*/
-
#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/init.h>
@@ -16,44 +14,15 @@
#include <asm/pgtable.h>
#include <asm/page.h>
-#include "map.h"
+#include <asm/mach/map.h>
-#define SIZE(x) (sizeof(x) / sizeof(x[0]))
-
-/* Logical Physical
- * 0xffff1000 0x00100000 DMA registers
- * 0xffff2000 0x00200000 MPEG
- * 0xffff3000 0x00300000 FPGA1 local control
- * 0xffff4000 0x00400000 External serial
- * 0xffff5000 0x00500000 Internal serial
- * 0xffff6000 0x00600000 Parallel
- * 0xffff7000 0x00700000 Interrupt control
- * 0xffff8000 0x00800000 Computer video
- * 0xffff9000 0x00900000 Control register 0
- * 0xffffs000 0x00a00000 Control register 1
- * 0xffffb000 0x00b00000 Control register 2
- * 0xffffc000 0x00c00000 FPGA2 local control
- * 0xffffd000 0x00d00000 Interrupt reset
- * 0xffffe000 0x00e00000 MPEG DMA throttle
- */
-
-const struct map_desc io_desc[] __initdata = {
- { 0xffff0000, 0x01000000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffff1000, 0x00100000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffff2000, 0x00200000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffff3000, 0x00300000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffff4000, 0x00400000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xfe000000, 0x00400000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffff5000, 0x00500000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffff6000, 0x00600000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffff7000, 0x00700000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffff8000, 0x00800000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffff9000, 0x00900000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffffa000, 0x00a00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffffb000, 0x00b00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffffc000, 0x00c00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffffd000, 0x00d00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 },
- { 0xffffe000, 0x00e00000, 0x00001000, DOMAIN_IO, 0, 1, 0, 0 }
+static struct map_desc tbox_io_desc[] __initdata = {
+ /* See hardware.h for details */
+ { IO_BASE, IO_START, 0x00100000, DOMAIN_IO, 0, 1, 0, 0 },
+ LAST_DESC
};
-unsigned int __initdata io_desc_size = SIZE(io_desc);
+void __init tbox_map_io(void)
+{
+ iotable_init(tbox_io_desc);
+}
diff --git a/arch/arm/mm/proc-arm2,3.S b/arch/arm/mm/proc-arm2,3.S
index 6dd48c919..76377cf9c 100644
--- a/arch/arm/mm/proc-arm2,3.S
+++ b/arch/arm/mm/proc-arm2,3.S
@@ -1,10 +1,16 @@
/*
- * linux/arch/arm/mm/proc-arm2,3.S: MMU functions for ARM2,3
+ * linux/arch/arm/mm/proc-arm2,3.S
*
- * (C) 1997-1999 Russell King
+ * Copyright (C) 1997-1999 Russell King
*
- * These are the low level assembler for performing cache
- * and memory functions on ARM2, ARM250 and ARM3 processors.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * MMU functions for ARM2,3
+ *
+ * These are the low level assembler for performing cache
+ * and memory functions on ARM2, ARM250 and ARM3 processors.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
diff --git a/arch/arm/mm/proc-arm6,7.S b/arch/arm/mm/proc-arm6,7.S
index b18d69d98..61e135e19 100644
--- a/arch/arm/mm/proc-arm6,7.S
+++ b/arch/arm/mm/proc-arm6,7.S
@@ -1,20 +1,25 @@
/*
- * linux/arch/arm/mm/proc-arm6,7.S: MMU functions for ARM6
+ * linux/arch/arm/mm/proc-arm6,7.S
*
- * (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2000 Russell King
*
- * These are the low level assembler for performing cache and TLB
- * functions on the ARM6 & ARM7.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * MMU functions for ARM6
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the ARM6 & ARM7.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/procinfo.h>
-#include <asm/errno.h>
#include "../lib/constants.h"
/*
- * Function: arm6_7_flush_cache_all (void)
- * : arm6_7_flush_cache_page (unsigned long address, int size, int flags)
+ * Function: arm6_7_cache_clean_invalidate_all (void)
+ * : arm6_7_cache_clean_invalidate_page (unsigned long address, int size, int flags)
*
* Params : address Area start address
* : size size of area
@@ -22,41 +27,41 @@
*
* Purpose : Flush all cache lines
*/
-ENTRY(cpu_arm6_flush_cache_all)
-ENTRY(cpu_arm7_flush_cache_all)
-ENTRY(cpu_arm6_flush_cache_area)
-ENTRY(cpu_arm7_flush_cache_area)
-ENTRY(cpu_arm6_flush_cache_entry)
-ENTRY(cpu_arm7_flush_cache_entry)
-ENTRY(cpu_arm6_flush_icache_area)
-ENTRY(cpu_arm7_flush_icache_area)
-ENTRY(cpu_arm6_flush_icache_page)
-ENTRY(cpu_arm7_flush_icache_page)
-ENTRY(cpu_arm6_cache_wback_area)
-ENTRY(cpu_arm7_cache_wback_area)
-ENTRY(cpu_arm6_cache_purge_area)
-ENTRY(cpu_arm7_cache_purge_area)
+ENTRY(cpu_arm6_cache_clean_invalidate_all)
+ENTRY(cpu_arm7_cache_clean_invalidate_all)
+ENTRY(cpu_arm6_cache_clean_invalidate_range)
+ENTRY(cpu_arm7_cache_clean_invalidate_range)
+ENTRY(cpu_arm6_invalidate_icache_range)
+ENTRY(cpu_arm7_invalidate_icache_range)
+ENTRY(cpu_arm6_invalidate_icache_page)
+ENTRY(cpu_arm7_invalidate_icache_page)
+ENTRY(cpu_arm6_dcache_clean_range)
+ENTRY(cpu_arm7_dcache_clean_range)
+ENTRY(cpu_arm6_dcache_invalidate_range)
+ENTRY(cpu_arm7_dcache_invalidate_range)
mov r0, #0
mcr p15, 0, r0, c7, c0, 0 @ flush cache
-ENTRY(cpu_arm6_clean_cache_area)
-ENTRY(cpu_arm7_clean_cache_area)
+ENTRY(cpu_arm6_dcache_clean_page)
+ENTRY(cpu_arm7_dcache_clean_page)
+ENTRY(cpu_arm6_dcache_clean_entry)
+ENTRY(cpu_arm7_dcache_clean_entry)
ENTRY(cpu_arm6_flush_ram_page)
ENTRY(cpu_arm7_flush_ram_page)
mov pc, lr
/*
- * Function: arm6_7_flush_tlb_all (void)
+ * Function: arm6_7_tlb_invalidate_all (void)
*
* Purpose : flush all TLB entries in all caches
*/
-ENTRY(cpu_arm6_flush_tlb_all)
-ENTRY(cpu_arm7_flush_tlb_all)
+ENTRY(cpu_arm6_tlb_invalidate_all)
+ENTRY(cpu_arm7_tlb_invalidate_all)
mov r0, #0
mcr p15, 0, r0, c5, c0, 0 @ flush TLB
mov pc, lr
/*
- * Function: arm6_7_flush_tlb_page (unsigned long address, int end, int flags)
+ * Function: arm6_7_tlb_invalidate_page (unsigned long address, int end, int flags)
*
* Params : address Area start address
* : end Area end address
@@ -64,8 +69,8 @@ ENTRY(cpu_arm7_flush_tlb_all)
*
* Purpose : flush a TLB entry
*/
-ENTRY(cpu_arm6_flush_tlb_area)
-ENTRY(cpu_arm7_flush_tlb_area)
+ENTRY(cpu_arm6_tlb_invalidate_range)
+ENTRY(cpu_arm7_tlb_invalidate_range)
1: mcr p15, 0, r0, c6, c0, 0 @ flush TLB
add r0, r0, #4096
cmp r0, r1
@@ -73,15 +78,15 @@ ENTRY(cpu_arm7_flush_tlb_area)
mov pc, lr
/*
- * Function: arm6_7_flush_tlb_page (unsigned long address, int flags)
+ * Function: arm6_7_tlb_invalidate_page (unsigned long address, int flags)
*
* Params : address Address
* : flags b0 = I-TLB as well
*
* Purpose : flush a TLB entry
*/
-ENTRY(cpu_arm6_flush_tlb_page)
-ENTRY(cpu_arm7_flush_tlb_page)
+ENTRY(cpu_arm6_tlb_invalidate_page)
+ENTRY(cpu_arm7_tlb_invalidate_page)
mcr p15, 0, r0, c6, c0, 0 @ flush TLB
mov pc, lr
@@ -392,23 +397,33 @@ ENTRY(arm6_processor_functions)
.word cpu_arm6_check_bugs
.word cpu_arm6_proc_init
.word cpu_arm6_proc_fin
- .word cpu_arm6_flush_cache_all
- .word cpu_arm6_flush_cache_area
- .word cpu_arm6_flush_cache_entry
- .word cpu_arm6_clean_cache_area
+ .word cpu_arm6_reset
+ .word cpu_arm6_do_idle
+
+ /* cache */
+ .word cpu_arm6_cache_clean_invalidate_all
+ .word cpu_arm6_cache_clean_invalidate_range
.word cpu_arm6_flush_ram_page
- .word cpu_arm6_flush_tlb_all
- .word cpu_arm6_flush_tlb_area
+
+ /* dcache */
+ .word cpu_arm6_dcache_invalidate_range
+ .word cpu_arm6_dcache_clean_range
+ .word cpu_arm6_dcache_clean_page
+ .word cpu_arm6_dcache_clean_entry
+
+ /* icache */
+ .word cpu_arm6_invalidate_icache_range
+ .word cpu_arm6_invalidate_icache_page
+
+ /* tlb */
+ .word cpu_arm6_tlb_invalidate_all
+ .word cpu_arm6_tlb_invalidate_range
+ .word cpu_arm6_tlb_invalidate_page
+
+ /* pgtable */
.word cpu_arm6_set_pgd
.word cpu_arm6_set_pmd
.word cpu_arm6_set_pte
- .word cpu_arm6_reset
- .word cpu_arm6_flush_icache_area
- .word cpu_arm6_cache_wback_area
- .word cpu_arm6_cache_purge_area
- .word cpu_arm6_flush_tlb_page
- .word cpu_arm6_do_idle
- .word cpu_arm6_flush_icache_page
.size arm6_processor_functions, . - arm6_processor_functions
/*
@@ -421,23 +436,33 @@ ENTRY(arm7_processor_functions)
.word cpu_arm7_check_bugs
.word cpu_arm7_proc_init
.word cpu_arm7_proc_fin
- .word cpu_arm7_flush_cache_all
- .word cpu_arm7_flush_cache_area
- .word cpu_arm7_flush_cache_entry
- .word cpu_arm7_clean_cache_area
+ .word cpu_arm7_reset
+ .word cpu_arm7_do_idle
+
+ /* cache */
+ .word cpu_arm7_cache_clean_invalidate_all
+ .word cpu_arm7_cache_clean_invalidate_range
.word cpu_arm7_flush_ram_page
- .word cpu_arm7_flush_tlb_all
- .word cpu_arm7_flush_tlb_area
+
+ /* dcache */
+ .word cpu_arm7_dcache_invalidate_range
+ .word cpu_arm7_dcache_clean_range
+ .word cpu_arm7_dcache_clean_page
+ .word cpu_arm7_dcache_clean_entry
+
+ /* icache */
+ .word cpu_arm7_invalidate_icache_range
+ .word cpu_arm7_invalidate_icache_page
+
+ /* tlb */
+ .word cpu_arm7_tlb_invalidate_all
+ .word cpu_arm7_tlb_invalidate_range
+ .word cpu_arm7_tlb_invalidate_page
+
+ /* pgtable */
.word cpu_arm7_set_pgd
.word cpu_arm7_set_pmd
.word cpu_arm7_set_pte
- .word cpu_arm7_reset
- .word cpu_arm7_flush_icache_area
- .word cpu_arm7_cache_wback_area
- .word cpu_arm7_cache_purge_area
- .word cpu_arm7_flush_tlb_page
- .word cpu_arm7_do_idle
- .word cpu_arm7_flush_icache_page
.size arm7_processor_functions, . - arm7_processor_functions
.type cpu_arm6_info, #object
@@ -479,7 +504,7 @@ cpu_elf_name: .asciz "v3"
__arm6_proc_info:
.long 0x41560600
.long 0xfffffff0
- .long 0x00000c12
+ .long 0x00000c1e
b __arm6_setup
.long cpu_arch_name
.long cpu_elf_name
@@ -492,7 +517,7 @@ __arm6_proc_info:
__arm610_proc_info:
.long 0x41560610
.long 0xfffffff0
- .long 0x00000c12
+ .long 0x00000c1e
b __arm6_setup
.long cpu_arch_name
.long cpu_elf_name
@@ -505,7 +530,7 @@ __arm610_proc_info:
__arm7_proc_info:
.long 0x41007000
.long 0xffffff00
- .long 0x00000c12
+ .long 0x00000c1e
b __arm7_setup
.long cpu_arch_name
.long cpu_elf_name
@@ -518,7 +543,7 @@ __arm7_proc_info:
__arm710_proc_info:
.long 0x41007100
.long 0xfff8ff00
- .long 0x00000c12
+ .long 0x00000c1e
b __arm7_setup
.long cpu_arch_name
.long cpu_elf_name
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index 262a4fd8b..13620ad5f 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -1,27 +1,44 @@
/*
- * linux/arch/arm/mm/proc-arm720.S: MMU functions for ARM720
+ * linux/arch/arm/mm/proc-arm720.S: MMU functions for ARM720
+ *
+ * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
+ * Rob Scott (rscott@mtrob.fdns.net)
+ * Copyright (C) 2000 ARM Limited, Deep Blue Solutions Ltd.
+ *
+ * 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.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
- * Copyright (C) 2000 Steve Hill (sjhill@cotw.com)
- * Rob Scott (rscott@mtrob.fdns.net)
*
* These are the low level assembler for performing cache and TLB
- * functions on the ARM720T.
+ * functions on the ARM720T. The ARM720T has a writethrough IDC
+ * cache, so we don't need to clean it.
*
- * Changelog:
- * 05-09-2000 SJH Created by moving 720 specific functions
- * out of 'proc-arm6,7.S' per RSK discussion
- * 07-25-2000 SJH Added idle function.
+ * Changelog:
+ * 05-09-2000 SJH Created by moving 720 specific functions
+ * out of 'proc-arm6,7.S' per RMK discussion
+ * 07-25-2000 SJH Added idle function.
+ * 08-25-2000 DBS Updated for integration of ARM Ltd version.
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/procinfo.h>
-#include <asm/errno.h>
#include <asm/hardware.h>
#include "../lib/constants.h"
/*
- * Function: arm720_flush_cache_all (void)
- * : arm720_flush_cache_page (unsigned long address, int size,
+ * Function: arm720_cache_clean_invalidate_all (void)
+ * : arm720_cache_clean_invalidate_page (unsigned long address, int size,
* int flags)
*
* Params : address Area start address
@@ -30,33 +47,37 @@
*
* Purpose : Flush all cache lines
*/
-ENTRY(cpu_arm720_flush_cache_all)
-ENTRY(cpu_arm720_flush_cache_area)
-ENTRY(cpu_arm720_flush_cache_entry)
-ENTRY(cpu_arm720_flush_icache_area)
-ENTRY(cpu_arm720_flush_icache_page)
-ENTRY(cpu_arm720_cache_wback_area)
-ENTRY(cpu_arm720_cache_purge_area)
+ENTRY(cpu_arm720_cache_clean_invalidate_all)
+ENTRY(cpu_arm720_cache_clean_invalidate_range)
+ENTRY(cpu_arm720_icache_invalidate_range)
+ENTRY(cpu_arm720_icache_invalidate_page)
+ENTRY(cpu_arm720_dcache_invalidate_range)
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 @ flush cache
mov pc, lr
-ENTRY(cpu_arm720_clean_cache_area)
+/*
+ * These just expect cache lines to be cleaned. Since we have a writethrough
+ * cache, we never have any dirty cachelines to worry about.
+ */
+ENTRY(cpu_arm720_dcache_clean_range)
+ENTRY(cpu_arm720_dcache_clean_page)
+ENTRY(cpu_arm720_dcache_clean_entry)
ENTRY(cpu_arm720_flush_ram_page)
mov pc, lr
/*
- * Function: arm720_flush_tlb_all (void)
+ * Function: arm720_tlb_invalidate_all (void)
*
* Purpose : flush all TLB entries in all caches
*/
-ENTRY(cpu_arm720_flush_tlb_all)
+ENTRY(cpu_arm720_tlb_invalidate_all)
mov r0, #0
mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)
mov pc, lr
/*
- * Function: arm720_flush_tlb_page (unsigned long address, int end, int flags)
+ * Function: arm720_tlb_invalidate_page (unsigned long address, int end, int flags)
*
* Params : address Area start address
* : end Area end address
@@ -64,7 +85,7 @@ ENTRY(cpu_arm720_flush_tlb_all)
*
* Purpose : flush a TLB entry
*/
-ENTRY(cpu_arm720_flush_tlb_area)
+ENTRY(cpu_arm720_tlb_invalidate_range)
1: mcr p15, 0, r0, c8, c7, 1 @ flush TLB (v4)
add r0, r0, #4096
cmp r0, r1
@@ -72,14 +93,14 @@ ENTRY(cpu_arm720_flush_tlb_area)
mov pc, lr
/*
- * Function: arm720_flush_tlb_page (unsigned long address, int flags)
+ * Function: arm720_tlb_invalidate_page (unsigned long address, int flags)
*
* Params : address Address
* : flags b0 = I-TLB as well
*
* Purpose : flush a TLB entry
*/
-ENTRY(cpu_arm720_flush_tlb_page)
+ENTRY(cpu_arm720_tlb_invalidate_page)
mcr p15, 0, r0, c8, c7, 1 @ flush TLB (v4)
mov pc, lr
@@ -262,12 +283,15 @@ ENTRY(cpu_arm720_proc_init)
mov pc, lr
ENTRY(cpu_arm720_proc_fin)
- mrs r0, cpsr
- orr r0, r0, #F_BIT | I_BIT
- msr cpsr, r0
- mov r0, #0x31 @ ....S..DP...M
+ stmfd sp!, {lr}
+ mov ip, #F_BIT | I_BIT | SVC_MODE
+ msr cpsr_c, ip
+ mrc p15, 0, r0, c1, c0, 0
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
mcr p15, 0, r0, c1, c0, 0 @ disable caches
- mov pc, lr
+ mcr p15, 0, r1, c7, c7, 0 @ invalidate cache
+ ldmfd sp!, {pc}
/*
* Function: arm720_proc_do_idle (void)
@@ -281,10 +305,12 @@ ENTRY(cpu_arm720_proc_fin)
* Purpose : put the processer in proper idle mode
*/
ENTRY(cpu_arm720_do_idle)
+#if 0 /* FIXME: is this part of the processor? */
ldr r2, =IO_BASE @ Virt addr of IO
add r2, r2, #0x00050000 @ Start of PMU regs
mov r1, #0x01 @ Idle mode
- str r1, [r2, #4]
+ str r1, [r2, #4]
+#endif
mov pc, lr
/*
@@ -295,7 +321,7 @@ ENTRY(cpu_arm720_do_idle)
*/
ENTRY(cpu_arm720_set_pgd)
mov r1, #0
- mcr p15, 0, r1, c7, c7, 0 @ flush cache
+ mcr p15, 0, r1, c7, c7, 0 @ invalidate cache
mcr p15, 0, r0, c2, c0, 0 @ update page table ptr
mcr p15, 0, r1, c8, c7, 0 @ flush TLB (v4)
mov pc, lr
@@ -340,9 +366,6 @@ ENTRY(cpu_arm720_set_pte)
movne r2, #0
str r2, [r0] @ hardware version
-
- mcr p15, 0, r0, c7, c7, 0 @ flush cache
- mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)
mov pc, lr
/*
@@ -351,30 +374,37 @@ ENTRY(cpu_arm720_set_pte)
* Notes : This sets up everything for a reset
*/
ENTRY(cpu_arm720_reset)
- mov r0, #0
- mcr p15, 0, r0, c7, c7, 0 @ flush cache
- mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)
- mov pc, lr
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate cache
+ mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4)
+ mrc p15, 0, ip, c1, c0, 0 @ get ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x2100 @ ..v....s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
cpu_armvlsi_name:
.asciz "ARM/VLSI"
cpu_arm720_name:
- .asciz "ARM 720"
+ .asciz "ARM720T"
.align
.section ".text.init", #alloc, #execinstr
__arm720_setup: mov r0, #0
- mcr p15, 0, r0, c7, c7, 0 @ flush caches on v4
+ mcr p15, 0, r0, c7, c7, 0 @ invalidate caches
mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4)
mcr p15, 0, r4, c2, c0 @ load page table pointer
mov r0, #0x1f @ Domains 0, 1 = client
mcr p15, 0, r0, c3, c0 @ load domain access register
-
- /* Set CP15 Control reg bits (RSBLDPWCAM) */
- mov r0, #0x7d @ ...LDPWC.M
- orr r0, r0, #0x100 @ .S.LDPWC.M
+
+ mrc p15, 0, r0, c1, c0 @ get control register
+ bic r0, r0, #0x2e00
+ bic r0, r0, #0x000e
+ orr r0, r0, #0x0031 @ ..V...RSBLDPWCAM
+ orr r0, r0, #0x0100 @ .........111.... (old)
+ orr r0, r0, #0x000c @ ..0...01..111101 (new)
mov pc, lr @ __ret (head-armv.S)
/*
@@ -387,23 +417,33 @@ ENTRY(arm720_processor_functions)
.word cpu_arm720_check_bugs
.word cpu_arm720_proc_init
.word cpu_arm720_proc_fin
- .word cpu_arm720_flush_cache_all
- .word cpu_arm720_flush_cache_area
- .word cpu_arm720_flush_cache_entry
- .word cpu_arm720_clean_cache_area
+ .word cpu_arm720_reset
+ .word cpu_arm720_do_idle
+
+ /* cache */
+ .word cpu_arm720_cache_clean_invalidate_all
+ .word cpu_arm720_cache_clean_invalidate_range
.word cpu_arm720_flush_ram_page
- .word cpu_arm720_flush_tlb_all
- .word cpu_arm720_flush_tlb_area
+
+ /* dcache */
+ .word cpu_arm720_dcache_invalidate_range
+ .word cpu_arm720_dcache_clean_range
+ .word cpu_arm720_dcache_clean_page
+ .word cpu_arm720_dcache_clean_entry
+
+ /* icache */
+ .word cpu_arm720_icache_invalidate_range
+ .word cpu_arm720_icache_invalidate_page
+
+ /* tlb */
+ .word cpu_arm720_tlb_invalidate_all
+ .word cpu_arm720_tlb_invalidate_range
+ .word cpu_arm720_tlb_invalidate_page
+
+ /* pgtable */
.word cpu_arm720_set_pgd
.word cpu_arm720_set_pmd
.word cpu_arm720_set_pte
- .word cpu_arm720_reset
- .word cpu_arm720_flush_icache_area
- .word cpu_arm720_cache_wback_area
- .word cpu_arm720_cache_purge_area
- .word cpu_arm720_flush_tlb_page
- .word cpu_arm720_do_idle
- .word cpu_arm720_flush_icache_page
.size arm720_processor_functions, . - arm720_processor_functions
.type cpu_arm720_info, #object
@@ -431,11 +471,11 @@ cpu_elf_name: .asciz "v4"
__arm720_proc_info:
.long 0x41807200 @ cpu_val
.long 0xffffff00 @ cpu_mask
- .long 0x00000c12 @ __cpu_mmu_flags
+ .long 0x00000c0e @ __cpu_mmu_flags
b __arm720_setup @ --cpu_flush
.long cpu_arch_name @ arch_name
.long cpu_elf_name @ elf_name
- .long HWCAP_SWP | HWCAP_26BIT @ elf_hwcap
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT @ elf_hwcap
.long cpu_arm720_info @ info
.long arm720_processor_functions
.size __arm720_proc_info, . - __arm720_proc_info
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
new file mode 100644
index 000000000..a4306f08a
--- /dev/null
+++ b/arch/arm/mm/proc-arm920.S
@@ -0,0 +1,602 @@
+/*
+ * linux/arch/arm/mm/arm920.S: MMU functions for ARM920
+ *
+ * Copyright (C) 1999,2000 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *
+ * 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.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the arm920.
+ */
+#include <linux/linkage.h>
+#include <linux/config.h>
+#include <asm/assembler.h>
+#include <asm/procinfo.h>
+#include <asm/hardware.h>
+#include "../lib/constants.h"
+
+/*
+ * This is the maximum size of an area which will be invalidated
+ * using the single invalidate entry instructions. Anything larger
+ * than this, and we go for the whole cache.
+ *
+ * This value should be chosen such that we choose the cheapest
+ * alternative.
+ */
+#define MAX_AREA_SIZE 16384
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define DCACHELINESIZE 32
+#define ICACHELINESIZE 32
+
+/*
+ * and the page size
+ */
+#define PAGESIZE 4096
+
+ .text
+
+/*
+ * cpu_arm920_data_abort()
+ *
+ * obtain information about current aborted instruction
+ *
+ * r0 = address of aborted instruction
+ *
+ * Returns:
+ * r0 = address of abort
+ * r1 != 0 if writing
+ * r3 = FSR
+ */
+ .align 5
+ENTRY(cpu_arm920_data_abort)
+ ldr r1, [r0] @ read aborted instruction
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+ mov r1, r1, lsr #19 @ b1 = L
+ mrc p15, 0, r3, c5, c0, 0 @ get FSR
+ and r1, r1, #2
+ and r3, r3, #255
+ mov pc, lr
+
+/*
+ * cpu_arm920_check_bugs()
+ */
+ENTRY(cpu_arm920_check_bugs)
+ mrs ip, cpsr
+ bic ip, ip, #F_BIT
+ msr cpsr, ip
+ mov pc, lr
+
+/*
+ * cpu_arm920_proc_init()
+ */
+ENTRY(cpu_arm920_proc_init)
+ mov pc, lr
+
+/*
+ * cpu_arm920_proc_fin()
+ */
+ENTRY(cpu_arm920_proc_fin)
+ stmfd sp!, {lr}
+ mov ip, #F_BIT | I_BIT | SVC_MODE
+ msr cpsr_c, ip
+ bl cpu_arm920_cache_clean_invalidate_all
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ ldmfd sp!, {pc}
+
+/*
+ * cpu_arm920_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
+ */
+ .align 5
+ENTRY(cpu_arm920_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
+
+/*
+ * cpu_arm920_do_idle()
+ */
+ .align 5
+ENTRY(cpu_arm920_do_idle)
+#if defined(CONFIG_CPU_ARM920_CPU_IDLE)
+ mcr p15, 0, r0, c7, c0, 4 @ Wait for interrupt
+#endif
+ mov pc, lr
+
+/* ================================= CACHE ================================ */
+
+
+/*
+ * cpu_arm920_cache_clean_invalidate_all()
+ *
+ * clean and invalidate all cache lines
+ *
+ * Note:
+ * 1. we should preserve r0 at all times
+ */
+ .align 5
+ENTRY(cpu_arm920_cache_clean_invalidate_all)
+ mov r2, #1
+cpu_arm920_cache_clean_invalidate_all_r2:
+ mov ip, #0
+#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+#else
+/*
+ * 'Clean & Invalidate whole DCache'
+ * Re-written to use Index Ops.
+ * Uses registers r1, r3 and ip
+ */
+ mov r1, #7 << 5 @ 8 segments
+1: orr r3, r1, #63 << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 5
+ bcs 1b @ segments 7 to 0
+#endif
+ teq r2, #0
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * cpu_arm920_cache_clean_invalidate_range(start, end, flags)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * start: Area start address
+ * end: Area end address
+ * flags: nonzero for I cache as well
+ */
+ .align 5
+ENTRY(cpu_arm920_cache_clean_invalidate_range)
+ bic r0, r0, #DCACHELINESIZE - 1 @ && added by PGM
+ sub r3, r1, r0
+ cmp r3, #MAX_AREA_SIZE
+ bgt cpu_arm920_cache_clean_invalidate_all_r2
+1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ add r0, r0, #DCACHELINESIZE
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ add r0, r0, #DCACHELINESIZE
+ cmp r0, r1
+ blt 1b
+ teq r2, #0
+ movne r0, #0
+ mcrne p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+
+/*
+ * cpu_arm920_flush_ram_page(page)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * page: page to clean and invalidate
+ */
+ .align 5
+ENTRY(cpu_arm920_flush_ram_page)
+ mov r1, #PAGESIZE
+1: mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ add r0, r0, #DCACHELINESIZE
+ mcr p15, 0, r0, c7, c14, 1 @ clean and invalidate D entry
+ add r0, r0, #DCACHELINESIZE
+ subs r1, r1, #2 * DCACHELINESIZE
+ bne 1b
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/* ================================ D-CACHE =============================== */
+
+/*
+ * cpu_arm920_dcache_invalidate_range(start, end)
+ *
+ * throw away all D-cached data in specified region without an obligation
+ * to write them back. Note however that we must clean the D-cached entries
+ * around the boundaries if the start and/or end address are not cache
+ * aligned.
+ *
+ * start: virtual start address
+ * end: virtual end address
+ */
+ .align 5
+ENTRY(cpu_arm920_dcache_invalidate_range)
+ tst r0, #DCACHELINESIZE - 1
+ bic r0, r0, #DCACHELINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #DCACHELINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #DCACHELINESIZE
+ cmp r0, r1
+ blt 1b
+ mov pc, lr
+
+/*
+ * cpu_arm920_dcache_clean_range(start, end)
+ *
+ * For the specified virtual address range, ensure that all caches contain
+ * clean data, such that peripheral accesses to the physical RAM fetch
+ * correct data.
+ *
+ * start: virtual start address
+ * end: virtual end address
+ */
+ .align 5
+ENTRY(cpu_arm920_dcache_clean_range)
+ bic r0, r0, #DCACHELINESIZE - 1
+ sub r1, r1, r0
+ cmp r1, #MAX_AREA_SIZE
+ mov r2, #0
+ bgt cpu_arm920_cache_clean_invalidate_all_r2
+
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #DCACHELINESIZE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #DCACHELINESIZE
+ subs r1, r1, #2 * DCACHELINESIZE
+ bpl 1b
+ mcr p15, 0, r2, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * cpu_arm920_dcache_clean_page(page)
+ *
+ * Cleans a single page of dcache so that if we have any future aliased
+ * mappings, they will be consistent at the time that they are created.
+ *
+ * page: virtual address of page to clean from dcache
+ *
+ * Note:
+ * 1. we don't need to flush the write buffer in this case.
+ * 2. we don't invalidate the entries since when we write the page
+ * out to disk, the entries may get reloaded into the cache.
+ */
+ .align 5
+ENTRY(cpu_arm920_dcache_clean_page)
+#ifndef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH
+ mov r1, #PAGESIZE
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #DCACHELINESIZE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #DCACHELINESIZE
+ subs r1, r1, #2 * DCACHELINESIZE
+ bne 1b
+#endif
+ mov pc, lr
+
+/*
+ * cpu_arm920_dcache_clean_entry(addr)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
+ */
+ .align 5
+ENTRY(cpu_arm920_dcache_clean_entry)
+#ifndef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+#endif
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/* ================================ I-CACHE =============================== */
+
+/*
+ * cpu_arm920_icache_invalidate_range(start, end)
+ *
+ * invalidate a range of virtual addresses from the Icache
+ *
+ * start: virtual start address
+ * end: virtual end address
+ */
+ .align 5
+ENTRY(cpu_arm920_icache_invalidate_range)
+1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry
+ add r0, r0, #DCACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ENTRY(cpu_arm920_icache_invalidate_page)
+ /* why no invalidate I cache --rmk */
+ mov pc, lr
+
+
+/* ================================== TLB ================================= */
+
+/*
+ * cpu_arm920_tlb_invalidate_all()
+ *
+ * Invalidate all TLB entries
+ */
+ .align 5
+ENTRY(cpu_arm920_tlb_invalidate_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D TLBs
+ mov pc, lr
+
+/*
+ * cpu_arm920_tlb_invalidate_range(start, end)
+ *
+ * invalidate TLB entries covering the specified range
+ *
+ * start: range start address
+ * end: range end address
+ */
+ .align 5
+ENTRY(cpu_arm920_tlb_invalidate_range)
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
+ mcr p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
+ add r0, r0, #PAGESIZE
+ cmp r0, r1
+ blt 1b
+ mov pc, lr
+
+/*
+ * cpu_arm920_tlb_invalidate_page(page, flags)
+ *
+ * invalidate the TLB entries for the specified page.
+ *
+ * page: page to invalidate
+ * flags: non-zero if we include the I TLB
+ */
+ .align 5
+ENTRY(cpu_arm920_tlb_invalidate_page)
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ teq r1, #0
+ mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
+ mcrne p15, 0, r0, c8, c5, 1 @ invalidate I TLB entry
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
+
+/*
+ * cpu_arm920_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_arm920_set_pgd)
+ mov ip, #0
+#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH
+ /* Any reason why we don't use mcr p15, 0, r0, c7, c7, 0 here? --rmk */
+ mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache
+#else
+@ && 'Clean & Invalidate whole DCache'
+@ && Re-written to use Index Ops.
+@ && Uses registers r1, r3 and ip
+
+ mov r1, #7 << 5 @ 8 segments
+1: orr r3, r1, #63 << 26 @ 64 entries
+2: mcr p15, 0, r3, c7, c14, 2 @ clean & invalidate D index
+ subs r3, r3, #1 << 26
+ bcs 2b @ entries 63 to 0
+ subs r1, r1, #1 << 5
+ bcs 1b @ segments 7 to 0
+#endif
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mov pc, lr
+
+/*
+ * cpu_arm920_set_pmd(pmdp, pmd)
+ *
+ * Set a level 1 translation table entry, and clean it out of
+ * any caches such that the MMUs can load it correctly.
+ *
+ * pmdp: pointer to PMD entry
+ * pmd: PMD value to store
+ */
+ .align 5
+ENTRY(cpu_arm920_set_pmd)
+#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH
+ eor r2, r1, #0x0a @ C & Section
+ tst r2, #0x0b
+ biceq r1, r1, #4 @ clear bufferable bit
+#endif
+ str r1, [r0]
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/*
+ * cpu_arm920_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_arm920_set_pte)
+ str r1, [r0], #-1024 @ linux version
+
+ eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+
+ bic r2, r1, #0xff0
+ bic r2, r2, #3
+ orr r2, r2, #HPTE_TYPE_SMALL
+
+ tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
+ orrne r2, r2, #HPTE_AP_READ
+
+ tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
+ orreq r2, r2, #HPTE_AP_WRITE
+
+ tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young?
+ movne r2, #0
+
+#ifdef CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH
+ eor r3, r1, #0x0a @ C & small page?
+ tst r3, #0x0b
+ biceq r2, r2, #4
+#endif
+ str r2, [r0] @ hardware version
+ mov r0, r0
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+
+cpu_manu_name:
+ .asciz "ARM/VLSI"
+ENTRY(cpu_arm920_name)
+ .ascii "Arm920"
+#if defined(CONFIG_CPU_ARM920_CPU_IDLE)
+ .ascii "s"
+#endif
+#if defined(CONFIG_CPU_ARM920_I_CACHE_ON)
+ .ascii "i"
+#endif
+#if defined(CONFIG_CPU_ARM920_D_CACHE_ON)
+ .ascii "d"
+#if defined(CONFIG_CPU_ARM920_FORCE_WRITE_THROUGH)
+ .ascii "(wt)"
+#else
+ .ascii "(wb)"
+#endif
+#endif
+ .ascii "\0"
+ .align
+
+ .section ".text.init", #alloc, #execinstr
+
+__arm920_setup:
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+ mcr p15, 0, r4, c2, c0 @ load page table pointer
+ mov r0, #0x1f @ Domains 0, 1 = client
+ mcr p15, 0, r0, c3, c0 @ load domain access register
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+/*
+ * Clear out 'unwanted' bits (then put them in if we need them)
+ */
+ bic r0, r0, #0x0e00 @ ....??r.........
+ bic r0, r0, #0x0002 @ ..............a.
+ bic r0, r0, #0x000c @ W,D
+ bic r0, r0, #0x1000 @ I
+/*
+ * Turn on what we want
+ */
+ orr r0, r0, #0x0031 @ ..........DP...M
+ orr r0, r0, #0x0100 @ .......S........
+
+#ifdef CONFIG_CPU_ARM920_D_CACHE_ON
+ orr r0, r0, #0x0004 @ Enable D cache
+#endif
+#ifdef CONFIG_CPU_ARM920_I_CACHE_ON
+ orr r0, r0, #0x1000 @ I Cache on
+#endif
+ mov pc, lr
+
+ .text
+
+/*
+ * Purpose : Function pointers used to access above functions - all calls
+ * come through these
+ */
+ .type arm920_processor_functions, #object
+arm920_processor_functions:
+ .word cpu_arm920_data_abort
+ .word cpu_arm920_check_bugs
+ .word cpu_arm920_proc_init
+ .word cpu_arm920_proc_fin
+ .word cpu_arm920_reset
+ .word cpu_arm920_do_idle
+
+ /* cache */
+ .word cpu_arm920_cache_clean_invalidate_all
+ .word cpu_arm920_cache_clean_invalidate_range
+ .word cpu_arm920_flush_ram_page
+
+ /* dcache */
+ .word cpu_arm920_dcache_invalidate_range
+ .word cpu_arm920_dcache_clean_range
+ .word cpu_arm920_dcache_clean_page
+ .word cpu_arm920_dcache_clean_entry
+
+ /* icache */
+ .word cpu_arm920_icache_invalidate_range
+ .word cpu_arm920_icache_invalidate_page
+
+ /* tlb */
+ .word cpu_arm920_tlb_invalidate_all
+ .word cpu_arm920_tlb_invalidate_range
+ .word cpu_arm920_tlb_invalidate_page
+
+ /* pgtable */
+ .word cpu_arm920_set_pgd
+ .word cpu_arm920_set_pmd
+ .word cpu_arm920_set_pte
+ .size arm920_processor_functions, . - arm920_processor_functions
+
+ .type cpu_arm920_info, #object
+cpu_arm920_info:
+ .long cpu_manu_name
+ .long cpu_arm920_name
+ .size cpu_arm920_info, . - cpu_arm920_info
+
+ .type cpu_arch_name, #object
+cpu_arch_name:
+ .asciz "armv4"
+ .size cpu_arch_name, . - cpu_arch_name
+
+ .type cpu_elf_name, #object
+cpu_elf_name:
+ .asciz "v4"
+ .size cpu_elf_name, . - cpu_elf_name
+ .align
+
+ .section ".proc.info", #alloc, #execinstr
+
+ .type __arm920_proc_info,#object
+__arm920_proc_info:
+ .long 0x41009200
+ .long 0xff00fff0
+ .long 0x00000c1e @ mmuflags
+ b __arm920_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+ .long cpu_arm920_info
+ .long arm920_processor_functions
+ .size __arm920_proc_info, . - __arm920_proc_info
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index bf75c97a2..031ba648a 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -1,15 +1,21 @@
/*
- * linux/arch/arm/mm/proc-sa110.S: MMU functions for SA110
+ * linux/arch/arm/mm/proc-sa110.S
*
- * (C) 1997-2000 Russell King
+ * Copyright (C) 1997-2000 Russell King
*
- * These are the low level assembler for performing cache and TLB
- * functions on the StrongARM-110, StrongARM-1100 and StrongARM-1110.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * MMU functions for SA110
+ *
+ * These are the low level assembler for performing cache and TLB
+ * functions on the StrongARM-110, StrongARM-1100 and StrongARM-1110.
*
- * Note that SA1100 and SA1110 share everything but their name and CPU ID.
+ * Note that SA1100 and SA1110 share everything but their name and CPU ID.
*
- * 12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
- * Flush the read buffer at context switches
+ * 12-jun-2000, Erik Mouw (J.A.K.Mouw@its.tudelft.nl):
+ * Flush the read buffer at context switches
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
@@ -21,24 +27,35 @@
* is larger than this, then we flush the whole cache
*/
#define MAX_AREA_SIZE 32768
+
+/*
+ * the cache line size of the I and D cache
+ */
+#define DCACHELINESIZE 32
+
+/*
+ * and the page size
+ */
+#define PAGESIZE 4096
+
#define FLUSH_OFFSET 32768
.macro flush_110_dcache rd, ra, re
add \re, \ra, #16384 @ only necessary for 16k
-1001: ldr \rd, [\ra], #32
+1001: ldr \rd, [\ra], #DCACHELINESIZE
teq \re, \ra
bne 1001b
.endm
.macro flush_1100_dcache rd, ra, re
add \re, \ra, #8192 @ only necessary for 8k
-1001: ldr \rd, [\ra], #32
+1001: ldr \rd, [\ra], #DCACHELINESIZE
teq \re, \ra
bne 1001b
#ifdef FLUSH_BASE_MINICACHE
add \ra, \ra, #FLUSH_BASE_MINICACHE - FLUSH_BASE
add \re, \ra, #512 @ only 512 bytes
-1002: ldr \rd, [\ra], #32
+1002: ldr \rd, [\ra], #DCACHELINESIZE
teq \re, \ra
bne 1002b
#endif
@@ -48,610 +65,705 @@
Lclean_switch: .long 0
.text
+
/*
- * Function: sa110_flush_cache_all (void)
- * Purpose : Flush all cache lines
+ * cpu_sa110_data_abort()
+ *
+ * obtain information about current aborted instruction
+ *
+ * r0 = address of aborted instruction
+ *
+ * Returns:
+ * r0 = address of abort
+ * r1 != 0 if writing
+ * r3 = FSR
*/
- .align 5
-ENTRY(cpu_sa110_flush_cache_all) @ preserves r0
- mov r2, #1
-cpu_sa110_flush_cache_all_r2:
- ldr r3, =Lclean_switch
- ldr ip, =FLUSH_BASE
- ldr r1, [r3]
- ands r1, r1, #1
- eor r1, r1, #1
- str r1, [r3]
- addne ip, ip, #FLUSH_OFFSET
- flush_110_dcache r3, ip, r1
- mov ip, #0
- teq r2, #0
- mcrne p15, 0, ip, c7, c5, 0 @ flush I cache
- mcr p15, 0, ip, c7, c10, 4 @ drain WB
- mov pc, lr
-
- .align 5
-ENTRY(cpu_sa1100_flush_cache_all) @ preserves r0
- mov r2, #1
-cpu_sa1100_flush_cache_all_r2:
- ldr r3, =Lclean_switch
- ldr ip, =FLUSH_BASE
- ldr r1, [r3]
- ands r1, r1, #1
- eor r1, r1, #1
- str r1, [r3]
- addne ip, ip, #FLUSH_OFFSET
- flush_1100_dcache r3, ip, r1
- mov ip, #0
- teq r2, #0
- mcrne p15, 0, ip, c7, c5, 0 @ flush I cache
- mcr p15, 0, r1, c9, c0, 0 @ flush RB
- mcr p15, 0, ip, c7, c10, 4 @ drain WB
- mov pc, lr
+ .align 5
+ENTRY(cpu_sa110_data_abort)
+ENTRY(cpu_sa1100_data_abort)
+ ldr r1, [r0] @ read aborted instruction
+ mrc p15, 0, r0, c6, c0, 0 @ get FAR
+ mov r1, r1, lsr #19 @ b1 = L
+ mrc p15, 0, r3, c5, c0, 0 @ get FSR
+ and r1, r1, #2
+ and r3, r3, #255
+ mov pc, lr
/*
- * Function: sa110_flush_cache_area (unsigned long address, int end, int flags)
- * Params : address Area start address
- * : end Area end address
- * : flags b0 = I cache as well
- * Purpose : clean & flush all cache lines associated with this area of memory
+ * cpu_sa110_check_bugs()
*/
- .align 5
-ENTRY(cpu_sa110_flush_cache_area)
- sub r3, r1, r0
- cmp r3, #MAX_AREA_SIZE
- bgt cpu_sa110_flush_cache_all_r2
-1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- mcr p15, 0, r0, c7, c6, 1 @ flush D entry
- add r0, r0, #32
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- mcr p15, 0, r0, c7, c6, 1 @ flush D entry
- add r0, r0, #32
- cmp r0, r1
- blt 1b
- teq r2, #0
- movne r0, #0
- mcrne p15, 0, r0, c7, c5, 0 @ flush I cache
- mov pc, lr
-
-ENTRY(cpu_sa1100_flush_cache_area)
- sub r3, r1, r0
- cmp r3, #MAX_AREA_SIZE
- bgt cpu_sa1100_flush_cache_all_r2
- b 1b
+ENTRY(cpu_sa110_check_bugs)
+ENTRY(cpu_sa1100_check_bugs)
+ mrs ip, cpsr
+ bic ip, ip, #F_BIT
+ msr cpsr, ip
+ mov pc, lr
/*
- * Function: sa110_cache_wback_area(unsigned long address, unsigned long end)
- * Params : address Area start address
- * : end Area end address
- * Purpose : ensure all dirty cachelines in the specified area have been
- * written out to memory (for DMA)
+ * cpu_sa110_proc_init()
*/
- .align 5
-ENTRY(cpu_sa110_cache_wback_area)
- sub r3, r1, r0
- cmp r3, #MAX_AREA_SIZE
- mov r2, #0
- bgt cpu_sa110_flush_cache_all_r2
- bic r0, r0, #31
-1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- add r0, r0, #32
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- add r0, r0, #32
- cmp r0, r1
- blt 1b
- mcr p15, 0, r2, c7, c10, 4 @ drain WB
- mov pc, lr
-
-ENTRY(cpu_sa1100_cache_wback_area)
- sub r3, r1, r0
- cmp r3, #MAX_AREA_SIZE
- mov r2, #0
- bgt cpu_sa1100_flush_cache_all_r2
- bic r0, r0, #31
- b 1b
+ENTRY(cpu_sa110_proc_init)
+ENTRY(cpu_sa1100_proc_init)
+ mov r0, #0
+ mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching
+ mov pc, lr
+
/*
- * Function: sa110_cache_purge_area(unsigned long address, unsigned long end)
- * Params : address Area start address
- * : end Area end address
- * Purpose : throw away all D-cached data in specified region without
- * an obligation to write it back.
- * Note : Must clean the D-cached entries around the boundaries if the
- * start and/or end address are not cache aligned.
+ * cpu_sa110_proc_fin()
*/
- .align 5
-ENTRY(cpu_sa110_cache_purge_area)
-ENTRY(cpu_sa1100_cache_purge_area)
- tst r0, #31
- bic r0, r0, #31
- mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
- tst r1, #31
- mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
-1: mcr p15, 0, r0, c7, c6, 1 @ flush D entry
- add r0, r0, #32
- cmp r0, r1
- blt 1b
- mov pc, lr
+ENTRY(cpu_sa110_proc_fin)
+ stmfd sp!, {lr}
+ mov ip, #F_BIT | I_BIT | SVC_MODE
+ msr cpsr_c, ip
+ bl cpu_sa110_cache_clean_invalidate_all @ clean caches
+1: mov r0, #0
+ mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
+ mrc p15, 0, r0, c1, c0, 0 @ ctrl register
+ bic r0, r0, #0x1000 @ ...i............
+ bic r0, r0, #0x000e @ ............wca.
+ mcr p15, 0, r0, c1, c0, 0 @ disable caches
+ ldmfd sp!, {pc}
+
+ENTRY(cpu_sa1100_proc_fin)
+ stmfd sp!, {lr}
+ mov ip, #F_BIT | I_BIT | SVC_MODE
+ msr cpsr_c, ip
+ bl cpu_sa1100_cache_clean_invalidate_all @ clean caches
+ b 1b
/*
- * Function: sa110_flush_cache_entry (unsigned long address)
- * Params : address Address of cache line to flush
- * Purpose : clean & flush an entry
+ * cpu_sa110_reset(loc)
+ *
+ * Perform a soft reset of the system. Put the CPU into the
+ * same state as it would be if it had been reset, and branch
+ * to what would be the reset vector.
+ *
+ * loc: location to jump to for soft reset
*/
- .align 5
-ENTRY(cpu_sa110_flush_cache_entry)
-ENTRY(cpu_sa1100_flush_cache_entry)
- mov r1, #0
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- mcr p15, 0, r1, c7, c10, 4 @ drain WB
- mcr p15, 0, r1, c7, c5, 0 @ flush I cache
- mov pc, lr
+ .align 5
+ENTRY(cpu_sa110_reset)
+ENTRY(cpu_sa1100_reset)
+ mov ip, #0
+ mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x000f @ ............wcam
+ bic ip, ip, #0x1100 @ ...i...s........
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
+ mov pc, r0
/*
- * Function: sa110_clean_cache_area(unsigned long start, unsigned long size)
- * Params : address Address of cache line to clean
- * Purpose : Ensure that physical memory reflects cache at this location
- * for page table purposes.
+ * cpu_sa110_do_idle(type)
+ *
+ * Cause the processor to idle
+ *
+ * type: call type:
+ * 0 = slow idle
+ * 1 = fast idle
+ * 2 = switch to slow processor clock
+ * 3 = switch to fast processor clock
*/
-ENTRY(cpu_sa110_clean_cache_area)
-ENTRY(cpu_sa1100_clean_cache_area)
-1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry (drain is done by TLB fns)
- add r0, r0, #32
- subs r1, r1, #32
- bhi 1b
- mov pc, lr
+ .align 5
+idle: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned
+ mov r0, r0 @ safety
+ mov pc, lr
+
+ENTRY(cpu_sa110_do_idle)
+ mov ip, #0
+ cmp r0, #4
+ addcc pc, pc, r0, lsl #2
+ mov pc, lr
+
+ b idle
+ b idle
+ b slow_clock
+ b fast_clock
+
+fast_clock:
+ mcr p15, 0, ip, c15, c1, 2 @ enable clock switching
+ mov pc, lr
+
+slow_clock:
+ mcr p15, 0, ip, c15, c2, 2 @ disable clock switching
+ ldr r1, =UNCACHEABLE_ADDR @ load from uncacheable loc
+ ldr r1, [r1, #0] @ force switch to MCLK
+ mov pc, lr
+
+ .align 5
+ENTRY(cpu_sa1100_do_idle)
+ mov r0, r0 @ 4 nop padding
+ mov r0, r0
+ mov r0, r0
+ mov r0, #0
+ ldr r1, =UNCACHEABLE_ADDR @ ptr to uncacheable address
+ mrs r2, cpsr
+ orr r3, r2, #192 @ disallow interrupts
+ msr cpsr_c, r3
+ @ --- aligned to a cache line
+ mcr p15, 0, r0, c15, c2, 2 @ disable clock switching
+ ldr r1, [r1, #0] @ force switch to MCLK
+ mcr p15, 0, r0, c15, c8, 2 @ wait for interrupt
+ mov r0, r0 @ safety
+ mcr p15, 0, r0, c15, c1, 2 @ enable clock switching
+ msr cpsr_c, r2 @ allow interrupts
+ mov pc, lr
+
+/* ================================= CACHE ================================ */
+
/*
- * Function: sa110_flush_ram_page (unsigned long page)
- * Params : page Area start address
- * Purpose : clean all cache lines associated with this area of memory
+ * cpu_sa110_cache_clean_invalidate_all (void)
+ *
+ * clean and invalidate all cache lines
+ *
+ * Note:
+ * 1. we should preserve r0 at all times
*/
- .align 5
-ENTRY(cpu_sa110_flush_ram_page)
-ENTRY(cpu_sa1100_flush_ram_page)
- mov r1, #4096
-1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- add r0, r0, #32
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- add r0, r0, #32
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- add r0, r0, #32
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- add r0, r0, #32
- subs r1, r1, #128
- bne 1b
- mov r0, #0
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
- mov pc, lr
+ .align 5
+ENTRY(cpu_sa110_cache_clean_invalidate_all)
+ mov r2, #1
+cpu_sa110_cache_clean_invalidate_all_r2:
+ ldr r3, =Lclean_switch
+ ldr ip, =FLUSH_BASE
+ ldr r1, [r3]
+ ands r1, r1, #1
+ eor r1, r1, #1
+ str r1, [r3]
+ addne ip, ip, #FLUSH_OFFSET
+ flush_110_dcache r3, ip, r1
+ mov ip, #0
+ teq r2, #0
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+ .align 5
+ENTRY(cpu_sa1100_cache_clean_invalidate_all)
+ mov r2, #1
+cpu_sa1100_cache_clean_invalidate_all_r2:
+ ldr r3, =Lclean_switch
+ ldr ip, =FLUSH_BASE
+ ldr r1, [r3]
+ ands r1, r1, #1
+ eor r1, r1, #1
+ str r1, [r3]
+ addne ip, ip, #FLUSH_OFFSET
+ flush_1100_dcache r3, ip, r1
+ mov ip, #0
+ teq r2, #0
+ mcrne p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r1, c9, c0, 0 @ invalidate RB
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mov pc, lr
/*
- * Function: sa110_flush_tlb_all (void)
- * Purpose : flush all TLB entries in all caches
+ * cpu_sa110_cache_clean_invalidate_range(start, end, flags)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * start: Area start address
+ * end: Area end address
+ * flags: nonzero for I cache as well
*/
- .align 5
-ENTRY(cpu_sa110_flush_tlb_all)
-ENTRY(cpu_sa1100_flush_tlb_all)
- mov ip, #0
- mcr p15, 0, ip, c7, c10, 4 @ drain WB
- mcr p15, 0, ip, c8, c7, 0 @ flush I & D tlbs
- mov pc, lr
+ .align 5
+ENTRY(cpu_sa110_cache_clean_invalidate_range)
+ bic r0, r0, #DCACHELINESIZE - 1
+ sub r3, r1, r0
+ cmp r3, #MAX_AREA_SIZE
+ bgt cpu_sa110_cache_clean_invalidate_all_r2
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #DCACHELINESIZE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #DCACHELINESIZE
+ cmp r0, r1
+ blt 1b
+ teq r2, #0
+ movne r0, #0
+ mcrne p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+
+ENTRY(cpu_sa1100_cache_clean_invalidate_range)
+ sub r3, r1, r0
+ cmp r3, #MAX_AREA_SIZE
+ bgt cpu_sa1100_cache_clean_invalidate_all_r2
+ b 1b
/*
- * Function: sa110_flush_tlb_area (unsigned long address, unsigned long end, int flags)
- * Params : address Area start address
- * : end Area end address
- * : flags b0 = I-TLB as well
- * Purpose : flush a TLB entry
+ * cpu_sa110_flush_ram_page(page)
+ *
+ * clean and invalidate all cache lines associated with this area of memory
+ *
+ * page: page to clean and invalidate
*/
- .align 5
-ENTRY(cpu_sa110_flush_tlb_area)
-ENTRY(cpu_sa1100_flush_tlb_area)
- mov r3, #0
- mcr p15, 0, r3, c7, c10, 4 @ drain WB
-1: cmp r0, r1
- mcrlt p15, 0, r0, c8, c6, 1 @ flush D TLB entry
- addlt r0, r0, #4096
- cmp r0, r1
- mcrlt p15, 0, r0, c8, c6, 1 @ flush D TLB entry
- addlt r0, r0, #4096
- blt 1b
- teq r2, #0
- mcrne p15, 0, r3, c8, c5, 0 @ flush I TLB
- mov pc, lr
+ .align 5
+ENTRY(cpu_sa110_flush_ram_page)
+ENTRY(cpu_sa1100_flush_ram_page)
+ mov r1, #PAGESIZE
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #DCACHELINESIZE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #DCACHELINESIZE
+ subs r1, r1, #2 * DCACHELINESIZE
+ bne 1b
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/* ================================ D-CACHE =============================== */
/*
- * Function: sa110_flush_tlb_page (unsigned long address, int flags)
- * Params : address Address to flush
- * : flags b0 = I-TLB as well
- * Purpose : flush a TLB entry
+ * cpu_sa110_dcache_invalidate_range(start, end)
+ *
+ * throw away all D-cached data in specified region without an obligation
+ * to write them back. Note however that we must clean the D-cached entries
+ * around the boundaries if the start and/or end address are not cache
+ * aligned.
+ *
+ * start: virtual start address
+ * end: virtual end address
*/
- .align 5
-ENTRY(cpu_sa110_flush_tlb_page)
-ENTRY(cpu_sa1100_flush_tlb_page)
- mov r3, #0
- mcr p15, 0, r3, c7, c10, 4 @ drain WB
- mcr p15, 0, r0, c8, c6, 1 @ flush D TLB entry
- teq r1, #0
- mcrne p15, 0, r3, c8, c5, 0 @ flush I TLB
- mov pc, lr
+ .align 5
+ENTRY(cpu_sa110_dcache_invalidate_range)
+ENTRY(cpu_sa1100_dcache_invalidate_range)
+ tst r0, #DCACHELINESIZE - 1
+ bic r0, r0, #DCACHELINESIZE - 1
+ mcrne p15, 0, r0, c7, c10, 1 @ clean D entry
+ tst r1, #DCACHELINESIZE - 1
+ mcrne p15, 0, r1, c7, c10, 1 @ clean D entry
+1: mcr p15, 0, r0, c7, c6, 1 @ invalidate D entry
+ add r0, r0, #DCACHELINESIZE
+ cmp r0, r1
+ blt 1b
+ mov pc, lr
/*
- * Function: sa110_flush_icache_area (unsigned long address, unsigned long size)
- * Params : address Address of area to flush
- * : size Size of area to flush
- * Purpose : flush an area from the Icache
+ * cpu_sa110_dcache_clean_range(start, end)
+ *
+ * For the specified virtual address range, ensure that all caches contain
+ * clean data, such that peripheral accesses to the physical RAM fetch
+ * correct data.
+ *
+ * start: virtual start address
+ * end: virtual end address
*/
- .align 5
-ENTRY(cpu_sa110_flush_icache_area)
-ENTRY(cpu_sa1100_flush_icache_area)
-1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry
- add r0, r0, #32
- subs r1, r1, #32
- bhi 1b
- mov r0, #0
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
- mcr p15, 0, r0, c7, c5, 0 @ flush I cache
- mov pc, lr
-
- .align 5
-ENTRY(cpu_sa110_flush_icache_page)
-ENTRY(cpu_sa1100_flush_icache_page)
- mcr p15, 0, r0, c7, c5, 0 @ flush I cache
- mov pc, lr
+ .align 5
+ENTRY(cpu_sa110_dcache_clean_range)
+ bic r0, r0, #DCACHELINESIZE - 1
+ sub r1, r1, r0
+ cmp r1, #MAX_AREA_SIZE
+ mov r2, #0
+ bgt cpu_sa110_cache_clean_invalidate_all_r2
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #DCACHELINESIZE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #DCACHELINESIZE
+ subs r1, r1, #2 * DCACHELINESIZE
+ bpl 1b
+ mcr p15, 0, r2, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+ENTRY(cpu_sa1100_dcache_clean_range)
+ bic r0, r0, #DCACHELINESIZE - 1
+ sub r1, r1, r0
+ cmp r1, #MAX_AREA_SIZE
+ mov r2, #0
+ bgt cpu_sa1100_cache_clean_invalidate_all_r2
+ b 1b
/*
- * Function: sa110_data_abort ()
- * Params : r0 = address of aborted instruction
- * Purpose : obtain information about current aborted instruction
- * Returns : r0 = address of abort
- * : r1 != 0 if writing
- * : r3 = FSR
+ * cpu_sa110_clean_dcache_page(page)
+ *
+ * Cleans a single page of dcache so that if we have any future aliased
+ * mappings, they will be consistent at the time that they are created.
+ *
+ * Note:
+ * 1. we don't need to flush the write buffer in this case.
+ * 2. we don't invalidate the entries since when we write the page
+ * out to disk, the entries may get reloaded into the cache.
*/
- .align 5
-ENTRY(cpu_sa110_data_abort)
-ENTRY(cpu_sa1100_data_abort)
- ldr r1, [r0] @ read instruction causing problem
- mrc p15, 0, r0, c6, c0, 0 @ get FAR
- mov r1, r1, lsr #19 @ b1 = L
- mrc p15, 0, r3, c5, c0, 0 @ get FSR
- and r1, r1, #2
- and r3, r3, #255
- mov pc, lr
-
- .align 5
+ .align 5
+ENTRY(cpu_sa110_dcache_clean_page)
+ENTRY(cpu_sa1100_dcache_clean_page)
+ mov r1, #PAGESIZE
+1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #DCACHELINESIZE
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ add r0, r0, #DCACHELINESIZE
+ subs r1, r1, #2 * DCACHELINESIZE
+ bne 1b
+ mov pc, lr
+
/*
- * Function: sa110_set_pgd(unsigned long pgd_phys)
- * Params : pgd_phys Physical address of page table
- * Purpose : Perform a task switch, saving the old processes state, and restoring
- * the new.
+ * cpu_sa110_dcache_clean_entry(addr)
+ *
+ * Clean the specified entry of any caches such that the MMU
+ * translation fetches will obtain correct data.
+ *
+ * addr: cache-unaligned virtual address
*/
- .align 5
-ENTRY(cpu_sa110_set_pgd)
- ldr r3, =Lclean_switch
- ldr ip, =FLUSH_BASE
- ldr r2, [r3]
- ands r2, r2, #1
- eor r2, r2, #1
- str r2, [r3]
- addne ip, ip, #FLUSH_OFFSET
- flush_110_dcache r3, ip, r1
- mov r1, #0
- mcr p15, 0, r1, c7, c5, 0 @ flush I cache
- mcr p15, 0, r1, c7, c10, 4 @ drain WB
- mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
- mcr p15, 0, r1, c8, c7, 0 @ flush TLBs
- mov pc, lr
-
- .align 5
-ENTRY(cpu_sa1100_set_pgd)
- ldr r3, =Lclean_switch
- ldr ip, =FLUSH_BASE
- ldr r2, [r3]
- ands r2, r2, #1
- eor r2, r2, #1
- str r2, [r3]
- addne ip, ip, #FLUSH_OFFSET
- flush_1100_dcache r3, ip, r1
- mov r1, #0
- mcr p15, 0, r1, c7, c5, 0 @ flush I cache
- mcr p15, 0, r1, c9, c0, 0 @ flush RB
- mcr p15, 0, r1, c7, c10, 4 @ drain WB
- mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
- mcr p15, 0, r1, c8, c7, 0 @ flush TLBs
- mov pc, lr
+ .align 5
+ENTRY(cpu_sa110_dcache_clean_entry)
+ENTRY(cpu_sa1100_dcache_clean_entry)
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
+
+/* ================================ I-CACHE =============================== */
/*
- * Function: sa110_set_pmd(pmd_t *pmdp, pmd_t pmd)
- * Params : r0 = Address to set
- * : r1 = value to set
- * Purpose : Set a PMD and flush it out
+ * cpu_sa110_icache_invalidate_range(start, end)
+ *
+ * invalidate a range of virtual addresses from the Icache
+ *
+ * start: virtual start address
+ * end: virtual end address
*/
- .align 5
-ENTRY(cpu_sa110_set_pmd)
-ENTRY(cpu_sa1100_set_pmd)
- str r1, [r0]
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
- mov pc, lr
+ .align 5
+ENTRY(cpu_sa110_icache_invalidate_range)
+ENTRY(cpu_sa1100_icache_invalidate_range)
+1: mcr p15, 0, r0, c7, c10, 1 @ Clean D entry
+ add r0, r0, #DCACHELINESIZE
+ cmp r0, r1
+ blo 1b
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ENTRY(cpu_sa110_icache_invalidate_page)
+ENTRY(cpu_sa1100_icache_invalidate_page)
+ mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache
+ mov pc, lr
+
+/* ================================== TLB ================================= */
/*
- * Function: sa110_set_pte(pte_t *ptep, pte_t pte)
- * Params : r0 = Address to set
- * : r1 = value to set
- * Purpose : Set a PTE and flush it out
+ * cpu_sa110_tlb_invalidate_all()
+ *
+ * Invalidate all TLB entries
*/
- .align 5
-ENTRY(cpu_sa110_set_pte)
-ENTRY(cpu_sa1100_set_pte)
- str r1, [r0], #-1024 @ linux version
-
- eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
+ .align 5
+ENTRY(cpu_sa110_tlb_invalidate_all)
+ENTRY(cpu_sa1100_tlb_invalidate_all)
+ mov r0, #0
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c8, c7, 0 @ invalidate I & D TLBs
+ mov pc, lr
- bic r2, r1, #0xff0
- bic r2, r2, #3
- orr r2, r2, #HPTE_TYPE_SMALL
-
- tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
- orrne r2, r2, #HPTE_AP_READ
+/*
+ * cpu_sa110_tlb_invalidate_range(start, end)
+ *
+ * invalidate TLB entries covering the specified range
+ *
+ * start: range start address
+ * end: range end address
+ */
+ .align 5
+ENTRY(cpu_sa110_tlb_invalidate_range)
+ENTRY(cpu_sa1100_tlb_invalidate_range)
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+1: mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
+ add r0, r0, #PAGESIZE
+ cmp r0, r1
+ blt 1b
+ mcr p15, 0, r3, c8, c5, 0 @ invalidate I TLB
+ mov pc, lr
- tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
- orreq r2, r2, #HPTE_AP_WRITE
+/*
+ * cpu_sa110_tlb_invalidate_page(page, flags)
+ *
+ * invalidate the TLB entries for the specified page.
+ *
+ * page: page to invalidate
+ * flags: non-zero if we include the I TLB
+ */
+ .align 5
+ENTRY(cpu_sa110_tlb_invalidate_page)
+ENTRY(cpu_sa1100_tlb_invalidate_page)
+ mov r3, #0
+ mcr p15, 0, r3, c7, c10, 4 @ drain WB
+ teq r1, #0
+ mcr p15, 0, r0, c8, c6, 1 @ invalidate D TLB entry
+ mcrne p15, 0, r3, c8, c5, 0 @ invalidate I TLB
+ mov pc, lr
+
+/* =============================== PageTable ============================== */
- tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young?
- movne r2, #0
+/*
+ * cpu_sa110_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_sa110_set_pgd)
+ ldr r3, =Lclean_switch
+ ldr ip, =FLUSH_BASE
+ ldr r2, [r3]
+ ands r2, r2, #1
+ eor r2, r2, #1
+ str r2, [r3]
+ addne ip, ip, #FLUSH_OFFSET
+ flush_110_dcache r3, ip, r1
+ mov r1, #0
+ mcr p15, 0, r1, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, r1, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs
+ mov pc, lr
- str r2, [r0] @ hardware version
- mov r0, r0
- mcr p15, 0, r0, c7, c10, 1 @ clean D entry
- mcr p15, 0, r0, c7, c10, 4 @ drain WB
- mov pc, lr
+/*
+ * cpu_sa1100_set_pgd(pgd)
+ *
+ * Set the translation base pointer to be as described by pgd.
+ *
+ * pgd: new page tables
+ */
+ .align 5
+ENTRY(cpu_sa1100_set_pgd)
+ ldr r3, =Lclean_switch
+ ldr ip, =FLUSH_BASE
+ ldr r2, [r3]
+ ands r2, r2, #1
+ eor r2, r2, #1
+ str r2, [r3]
+ addne ip, ip, #FLUSH_OFFSET
+ flush_1100_dcache r3, ip, r1
+ mov ip, #0
+ mcr p15, 0, ip, c7, c5, 0 @ invalidate I cache
+ mcr p15, 0, ip, c9, c0, 0 @ invalidate RB
+ mcr p15, 0, ip, c7, c10, 4 @ drain WB
+ mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
+ mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs
+ mov pc, lr
/*
- * Function: sa110_check_bugs (void)
- * : sa110_proc_init (void)
- * : sa110_proc_fin (void)
- * Notes : This processor does not require these
+ * cpu_sa110_set_pmd(pmdp, pmd)
+ *
+ * Set a level 1 translation table entry, and clean it out of
+ * any caches such that the MMUs can load it correctly.
+ *
+ * pmdp: pointer to PMD entry
+ * pmd: PMD value to store
*/
-ENTRY(cpu_sa110_check_bugs)
-ENTRY(cpu_sa1100_check_bugs)
- mrs ip, cpsr
- bic ip, ip, #F_BIT
- msr cpsr, ip
- mov pc, lr
+ .align 5
+ENTRY(cpu_sa110_set_pmd)
+ENTRY(cpu_sa1100_set_pmd)
+ str r1, [r0]
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
-ENTRY(cpu_sa110_proc_init)
-ENTRY(cpu_sa1100_proc_init)
- mov r0, #0
- mcr p15, 0, r0, c15, c1, 2 @ Enable clock switching
- mov pc, lr
+/*
+ * cpu_sa110_arm920_set_pte(ptep, pte)
+ *
+ * Set a PTE and flush it out
+ */
+ .align 5
+ENTRY(cpu_sa110_set_pte)
+ENTRY(cpu_sa1100_set_pte)
+ str r1, [r0], #-1024 @ linux version
-ENTRY(cpu_sa110_proc_fin)
- stmfd sp!, {r1, lr}
- mov ip, #F_BIT | I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl cpu_sa110_flush_cache_all @ clean caches
-1: mov r0, #0
- mcr p15, 0, r0, c15, c2, 2 @ Disable clock switching
- mrc p15, 0, r0, c1, c0, 0
- bic r0, r0, #0x1000 @ ...i............
- bic r0, r0, #0x000e @ ............wca.
- mcr p15, 0, r0, c1, c0, 0 @ disable caches
- ldmfd sp!, {r1, pc}
+ eor r1, r1, #LPTE_PRESENT | LPTE_YOUNG | LPTE_WRITE | LPTE_DIRTY
-ENTRY(cpu_sa1100_proc_fin)
- stmfd sp!, {r1, lr}
- mov ip, #F_BIT | I_BIT | SVC_MODE
- msr cpsr_c, ip
- bl cpu_sa1100_flush_cache_all @ clean caches
- b 1b
+ bic r2, r1, #0xff0
+ bic r2, r2, #3
+ orr r2, r2, #HPTE_TYPE_SMALL
+ tst r1, #LPTE_USER | LPTE_EXEC @ User or Exec?
+ orrne r2, r2, #HPTE_AP_READ
- .align 5
-idle: mcr p15, 0, r0, c15, c8, 2 @ Wait for interrupt, cache aligned
- mov r0, r0 @ safety
- mov pc, lr
-/*
- * Function: *_do_idle
- * Params : r0 = call type:
- * 0 = slow idle
- * 1 = fast idle
- * 2 = switch to slow processor clock
- * 3 = switch to fast processor clock
- */
-ENTRY(cpu_sa110_do_idle)
-ENTRY(cpu_sa1100_do_idle)
- mov ip, #0
- cmp r0, #4
- addcc pc, pc, r0, lsl #2
- mov pc, lr
+ tst r1, #LPTE_WRITE | LPTE_DIRTY @ Write and Dirty?
+ orreq r2, r2, #HPTE_AP_WRITE
- b idle
- b idle
- b slow_clock
- b fast_clock
+ tst r1, #LPTE_PRESENT | LPTE_YOUNG @ Present and Young?
+ movne r2, #0
-fast_clock: mcr p15, 0, ip, c15, c1, 2 @ enable clock switching
- mov pc, lr
+ str r2, [r0] @ hardware version
+ mov r0, r0
+ mcr p15, 0, r0, c7, c10, 1 @ clean D entry
+ mcr p15, 0, r0, c7, c10, 4 @ drain WB
+ mov pc, lr
-slow_clock: mcr p15, 0, ip, c15, c2, 2 @ disable clock switching
- ldr r1, =UNCACHEABLE_ADDR @ load from uncacheable loc
- ldr r1, [r1, #0] @ force switch to MCLK
- mov pc, lr
-/*
- * Function: sa110_reset
- * Params : r0 = address to jump to
- * Notes : This sets up everything for a reset
- */
- .align 5
-ENTRY(cpu_sa110_reset)
-ENTRY(cpu_sa1100_reset)
- mov ip, #0
- mcr p15, 0, ip, c7, c7, 0 @ flush I,D caches
- mcr p15, 0, ip, c7, c10, 4 @ drain WB
- mcr p15, 0, ip, c8, c7, 0 @ flush I & D tlbs
- mrc p15, 0, ip, c1, c0, 0 @ ctrl register
- bic ip, ip, #0x000f @ ............wcam
- bic ip, ip, #0x1100 @ ...i...s........
- mcr p15, 0, ip, c1, c0, 0 @ ctrl register
- mov pc, r0
-
-
-cpu_manu_name: .asciz "Intel"
-cpu_sa110_name: .asciz "StrongARM-110"
+cpu_manu_name:
+ .asciz "Intel"
+cpu_sa110_name:
+ .asciz "StrongARM-110"
cpu_sa1100_name:
- .asciz "StrongARM-1100"
+ .asciz "StrongARM-1100"
cpu_sa1110_name:
- .asciz "StrongARM-1110"
- .align
+ .asciz "StrongARM-1110"
+ .align
- .section ".text.init", #alloc, #execinstr
+ .section ".text.init", #alloc, #execinstr
__sa1100_setup: @ Allow read-buffer operations from userland
- mcr p15, 0, r0, c9, c0, 5
-
-__sa110_setup: mov r0, #F_BIT | I_BIT | SVC_MODE
- msr cpsr_c, r0
- mov r0, #0
- mcr p15, 0, r0, c7, c7 @ flush I,D caches on v4
- mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
- mcr p15, 0, r0, c8, c7 @ flush I,D TLBs on v4
- mcr p15, 0, r4, c2, c0 @ load page table pointer
- mov r0, #0x1f @ Domains 0, 1 = client
- mcr p15, 0, r0, c3, c0 @ load domain access register
- mrc p15, 0, r0, c1, c0 @ get control register v4
- bic r0, r0, #0x0e00 @ ....??r.........
- bic r0, r0, #0x0002 @ ..............a.
- orr r0, r0, #0x003d @ ..........DPWC.M
- orr r0, r0, #0x1100 @ ...I...S........
- mov pc, lr
-
- .text
+ mcr p15, 0, r0, c9, c0, 5
+
+__sa110_setup:
+ mov r0, #F_BIT | I_BIT | SVC_MODE
+ msr cpsr_c, r0
+ mov r0, #0
+ mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4
+ mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4
+ mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4
+ mcr p15, 0, r4, c2, c0 @ load page table pointer
+ mov r0, #0x1f @ Domains 0, 1 = client
+ mcr p15, 0, r0, c3, c0 @ load domain access register
+ mrc p15, 0, r0, c1, c0 @ get control register v4
+ bic r0, r0, #0x0e00 @ ....??r.........
+ bic r0, r0, #0x0002 @ ..............a.
+ orr r0, r0, #0x003d @ ..........DPWC.M
+ orr r0, r0, #0x1100 @ ...I...S........
+ mov pc, lr
+
+ .text
/*
* Purpose : Function pointers used to access above functions - all calls
* come through these
*/
- .type sa110_processor_functions, #object
+ .type sa110_processor_functions, #object
ENTRY(sa110_processor_functions)
- .word cpu_sa110_data_abort
- .word cpu_sa110_check_bugs
- .word cpu_sa110_proc_init
- .word cpu_sa110_proc_fin
- .word cpu_sa110_flush_cache_all
- .word cpu_sa110_flush_cache_area
- .word cpu_sa110_flush_cache_entry
- .word cpu_sa110_clean_cache_area
- .word cpu_sa110_flush_ram_page
- .word cpu_sa110_flush_tlb_all
- .word cpu_sa110_flush_tlb_area
- .word cpu_sa110_set_pgd
- .word cpu_sa110_set_pmd
- .word cpu_sa110_set_pte
- .word cpu_sa110_reset
- .word cpu_sa110_flush_icache_area
- .word cpu_sa110_cache_wback_area
- .word cpu_sa110_cache_purge_area
- .word cpu_sa110_flush_tlb_page
- .word cpu_sa110_do_idle
- .word cpu_sa110_flush_icache_page
- .size sa110_processor_functions, . - sa110_processor_functions
-
- .type cpu_sa110_info, #object
+ .word cpu_sa110_data_abort
+ .word cpu_sa110_check_bugs
+ .word cpu_sa110_proc_init
+ .word cpu_sa110_proc_fin
+ .word cpu_sa110_reset
+ .word cpu_sa110_do_idle
+
+ /* cache */
+ .word cpu_sa110_cache_clean_invalidate_all
+ .word cpu_sa110_cache_clean_invalidate_range
+ .word cpu_sa110_flush_ram_page
+
+ /* dcache */
+ .word cpu_sa110_dcache_invalidate_range
+ .word cpu_sa110_dcache_clean_range
+ .word cpu_sa110_dcache_clean_page
+ .word cpu_sa110_dcache_clean_entry
+
+ /* icache */
+ .word cpu_sa110_icache_invalidate_range
+ .word cpu_sa110_icache_invalidate_page
+
+ /* tlb */
+ .word cpu_sa110_tlb_invalidate_all
+ .word cpu_sa110_tlb_invalidate_range
+ .word cpu_sa110_tlb_invalidate_page
+
+ /* pgtable */
+ .word cpu_sa110_set_pgd
+ .word cpu_sa110_set_pmd
+ .word cpu_sa110_set_pte
+ .size sa110_processor_functions, . - sa110_processor_functions
+
+ .type cpu_sa110_info, #object
cpu_sa110_info:
- .long cpu_manu_name
- .long cpu_sa110_name
- .size cpu_sa110_info, . - cpu_sa110_info
+ .long cpu_manu_name
+ .long cpu_sa110_name
+ .size cpu_sa110_info, . - cpu_sa110_info
/*
* SA1100 and SA1110 share the same function calls
*/
- .type sa1100_processor_functions, #object
+ .type sa1100_processor_functions, #object
ENTRY(sa1100_processor_functions)
- .word cpu_sa1100_data_abort
- .word cpu_sa1100_check_bugs
- .word cpu_sa1100_proc_init
- .word cpu_sa1100_proc_fin
- .word cpu_sa1100_flush_cache_all
- .word cpu_sa1100_flush_cache_area
- .word cpu_sa1100_flush_cache_entry
- .word cpu_sa1100_clean_cache_area
- .word cpu_sa1100_flush_ram_page
- .word cpu_sa1100_flush_tlb_all
- .word cpu_sa1100_flush_tlb_area
- .word cpu_sa1100_set_pgd
- .word cpu_sa1100_set_pmd
- .word cpu_sa1100_set_pte
- .word cpu_sa1100_reset
- .word cpu_sa1100_flush_icache_area
- .word cpu_sa1100_cache_wback_area
- .word cpu_sa1100_cache_purge_area
- .word cpu_sa1100_flush_tlb_page
- .word cpu_sa1100_do_idle
- .word cpu_sa1100_flush_icache_page
- .size sa1100_processor_functions, . - sa1100_processor_functions
+ .word cpu_sa1100_data_abort
+ .word cpu_sa1100_check_bugs
+ .word cpu_sa1100_proc_init
+ .word cpu_sa1100_proc_fin
+ .word cpu_sa1100_reset
+ .word cpu_sa1100_do_idle
+
+ /* cache */
+ .word cpu_sa1100_cache_clean_invalidate_all
+ .word cpu_sa1100_cache_clean_invalidate_range
+ .word cpu_sa1100_flush_ram_page
+
+ /* dcache */
+ .word cpu_sa1100_dcache_invalidate_range
+ .word cpu_sa1100_dcache_clean_range
+ .word cpu_sa1100_dcache_clean_page
+ .word cpu_sa1100_dcache_clean_entry
+
+ /* icache */
+ .word cpu_sa1100_icache_invalidate_range
+ .word cpu_sa1100_icache_invalidate_page
+
+ /* tlb */
+ .word cpu_sa1100_tlb_invalidate_all
+ .word cpu_sa1100_tlb_invalidate_range
+ .word cpu_sa1100_tlb_invalidate_page
+
+ /* pgtable */
+ .word cpu_sa1100_set_pgd
+ .word cpu_sa1100_set_pmd
+ .word cpu_sa1100_set_pte
+ .size sa1100_processor_functions, . - sa1100_processor_functions
cpu_sa1100_info:
- .long cpu_manu_name
- .long cpu_sa1100_name
- .size cpu_sa1100_info, . - cpu_sa1100_info
+ .long cpu_manu_name
+ .long cpu_sa1100_name
+ .size cpu_sa1100_info, . - cpu_sa1100_info
cpu_sa1110_info:
- .long cpu_manu_name
- .long cpu_sa1110_name
- .size cpu_sa1110_info, . - cpu_sa1110_info
+ .long cpu_manu_name
+ .long cpu_sa1110_name
+ .size cpu_sa1110_info, . - cpu_sa1110_info
+ .type cpu_arch_name, #object
+cpu_arch_name:
+ .asciz "armv4"
+ .size cpu_arch_name, . - cpu_arch_name
- .type cpu_arch_name, #object
-cpu_arch_name: .asciz "armv4"
- .size cpu_arch_name, . - cpu_arch_name
+ .type cpu_elf_name, #object
+cpu_elf_name:
+ .asciz "v4"
+ .size cpu_elf_name, . - cpu_elf_name
+ .align
- .type cpu_elf_name, #object
-cpu_elf_name: .asciz "v4"
- .size cpu_elf_name, . - cpu_elf_name
- .align
+ .section ".proc.info", #alloc, #execinstr
- .section ".proc.info", #alloc, #execinstr
-
- .type __sa110_proc_info,#object
+ .type __sa110_proc_info,#object
__sa110_proc_info:
- .long 0x4401a100
- .long 0xfffffff0
- .long 0x00000c02
- b __sa110_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
- .long cpu_sa110_info
- .long sa110_processor_functions
- .size __sa110_proc_info, . - __sa110_proc_info
-
- .type __sa1100_proc_info,#object
+ .long 0x4401a100
+ .long 0xfffffff0
+ .long 0x00000c0e
+ b __sa110_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+ .long cpu_sa110_info
+ .long sa110_processor_functions
+ .size __sa110_proc_info, . - __sa110_proc_info
+
+ .type __sa1100_proc_info,#object
__sa1100_proc_info:
- .long 0x4401a110
- .long 0xfffffff0
- .long 0x00000c02
- b __sa1100_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
- .long cpu_sa1100_info
- .long sa1100_processor_functions
- .size __sa1100_proc_info, . - __sa1100_proc_info
-
- .type __sa1110_proc_info,#object
+ .long 0x4401a110
+ .long 0xfffffff0
+ .long 0x00000c0e
+ b __sa1100_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+ .long cpu_sa1100_info
+ .long sa1100_processor_functions
+ .size __sa1100_proc_info, . - __sa1100_proc_info
+
+ .type __sa1110_proc_info,#object
__sa1110_proc_info:
- .long 0x6901b110
- .long 0xfffffff0
- .long 0x00000c02
- b __sa1100_setup
- .long cpu_arch_name
- .long cpu_elf_name
- .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
- .long cpu_sa1110_info
- .long sa1100_processor_functions
- .size __sa1110_proc_info, . - __sa1110_proc_info
-
-
+ .long 0x6901b110
+ .long 0xfffffff0
+ .long 0x00000c0e
+ b __sa1100_setup
+ .long cpu_arch_name
+ .long cpu_elf_name
+ .long HWCAP_SWP | HWCAP_HALF | HWCAP_26BIT
+ .long cpu_sa1110_info
+ .long sa1100_processor_functions
+ .size __sa1110_proc_info, . - __sa1110_proc_info
diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c
new file mode 100644
index 000000000..07ceac0f9
--- /dev/null
+++ b/arch/arm/mm/proc-syms.c
@@ -0,0 +1,31 @@
+/*
+ * linux/arch/arm/mm/proc-syms.c
+ *
+ * Copyright (C) 2000 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <asm/proc-fns.h>
+
+#ifndef MULTI_CPU
+EXPORT_SYMBOL(cpu_cache_clean_invalidate_all);
+EXPORT_SYMBOL(cpu_cache_clean_invalidate_range);
+EXPORT_SYMBOL(cpu_flush_ram_page);
+EXPORT_SYMBOL(cpu_dcache_clean_page);
+EXPORT_SYMBOL(cpu_dcache_clean_entry);
+EXPORT_SYMBOL(cpu_dcache_clean_range);
+EXPORT_SYMBOL(cpu_dcache_invalidate_range);
+EXPORT_SYMBOL(cpu_icache_invalidate_range);
+EXPORT_SYMBOL(cpu_icache_invalidate_page);
+EXPORT_SYMBOL(cpu_tlb_invalidate_all);
+EXPORT_SYMBOL(cpu_tlb_invalidate_range);
+EXPORT_SYMBOL(cpu_tlb_invalidate_page);
+EXPORT_SYMBOL(cpu_set_pgd);
+EXPORT_SYMBOL(cpu_set_pmd);
+EXPORT_SYMBOL(cpu_set_pte);
+#else
+EXPORT_SYMBOL(processor);
+#endif
diff --git a/arch/arm/mm/small_page.c b/arch/arm/mm/small_page.c
index 27fb0f663..634cc1ead 100644
--- a/arch/arm/mm/small_page.c
+++ b/arch/arm/mm/small_page.c
@@ -3,12 +3,15 @@
*
* Copyright (C) 1996 Russell King
*
- * Changelog:
- * 26/01/1996 RMK Cleaned up various areas to make little more generic
- * 07/02/1999 RMK Support added for 16K and 32K page sizes
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Changelog:
+ * 26/01/1996 RMK Cleaned up various areas to make little more generic
+ * 07/02/1999 RMK Support added for 16K and 32K page sizes
* containing 8K blocks
*/
-
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -70,6 +73,8 @@ static struct order orders[] = {
#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 spinlock_t small_page_lock = SPIN_LOCK_UNLOCKED;
+
static void add_page_to_queue(struct page *page, struct page **p)
{
#ifdef PEDANTIC
@@ -99,11 +104,10 @@ static unsigned long __get_small_page(int priority, struct order *order)
struct page *page;
int offset;
- save_flags(flags);
if (!order->queue)
goto need_new_page;
- cli();
+ spin_lock_irqsave(&small_page_lock, flags);
page = order->queue;
again:
#ifdef PEDANTIC
@@ -114,12 +118,14 @@ again:
SET_USED(page, offset);
if (USED_MAP(page) == order->all_used)
remove_page_from_queue(page);
- restore_flags(flags);
+ spin_unlock_irqrestore(&small_page_lock, flags);
return (unsigned long) page_address(page) + (offset << order->shift);
need_new_page:
page = alloc_page(priority);
+
+ spin_lock_irqsave(&small_page_lock, flags);
if (!order->queue) {
if (!page)
goto no_page;
@@ -135,7 +141,7 @@ need_new_page:
goto again;
no_page:
- restore_flags(flags);
+ spin_unlock_irqrestore(&small_page_lock, flags);
return 0;
}
@@ -164,7 +170,7 @@ static void __free_small_page(unsigned long spage, struct order *order)
/*
* the following must be atomic wrt get_page
*/
- save_flags_cli(flags);
+ spin_lock_irqsave(&small_page_lock, flags);
if (USED_MAP(page) == order->all_used)
add_page_to_queue(page, &order->queue);
@@ -175,7 +181,7 @@ static void __free_small_page(unsigned long spage, struct order *order)
if (USED_MAP(page) == 0)
goto free_page;
- restore_flags(flags);
+ spin_unlock_irqrestore(&small_page_lock, flags);
}
return;
@@ -184,7 +190,7 @@ free_page:
* unlink the page from the small page queue and free it
*/
remove_page_from_queue(page);
- restore_flags(flags);
+ spin_unlock_irqrestore(&small_page_lock, flags);
ClearPageReserved(page);
__free_page(page);
return;
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index b922786e3..f3d1fb0b1 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -37,6 +37,11 @@ graphicsclient SA1100_GRAPHICSCLIENT GRAPHICSCLIENT 29
xp860 SA1100_XP860 XP860 30
cerf SA1100_CERF CERF 31
nanoengine SA1100_NANOENGINE NANOENGINE 32
+fpic SA1100_FPIC FPIC 33
+extenex1 SA1100_EXTENEX1 EXTENEX1 34
+sherman SA1100_SHERMAN SHERMAN 35
+accelent_sa SA1100_ACCELENT ACCELENT_SA 36
+accelent_l7200 ARCH_L7200_ACCELENT ACCELENT_L7200 37
# The following are unallocated
empeg SA1100_EMPEG EMPEG
diff --git a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in
index 656779195..5353e7f8f 100644
--- a/arch/arm/vmlinux-armo.lds.in
+++ b/arch/arm/vmlinux-armo.lds.in
@@ -79,9 +79,10 @@ SECTIONS
.bss : {
- __bss_start = .; /* BSS */
+ __bss_start = .; /* BSS */
*(.bss)
- _end = . ;
+ *(COMMON)
+ _end = . ;
}
/* Stabs debugging sections. */
diff --git a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in
index 4ef7377bb..b54f2bd92 100644
--- a/arch/arm/vmlinux-armv.lds.in
+++ b/arch/arm/vmlinux-armv.lds.in
@@ -42,8 +42,8 @@ SECTIONS
*(.text.lock) /* out-of-line lock text */
*(.rodata)
*(.kstrtab)
- . = ALIGN(16); /* Exception table */
- __start___ex_table = .;
+ . = ALIGN(16);
+ __start___ex_table = .; /* Exception table */
*(__ex_table)
__stop___ex_table = .;
diff --git a/arch/i386/config.in b/arch/i386/config.in
index 4f41a46f7..6d1279ed7 100644
--- a/arch/i386/config.in
+++ b/arch/i386/config.in
@@ -128,6 +128,7 @@ if [ "$CONFIG_MWINCHIP3D" = "y" ]; then
define_bool CONFIG_X86_USE_PPRO_CHECKSUM y
define_bool CONFIG_X86_USE_3DNOW y
fi
+tristate 'Toshiba Laptop support' CONFIG_TOSHIBA
tristate '/dev/cpu/microcode - Intel P6 CPU microcode support' CONFIG_MICROCODE
tristate '/dev/cpu/*/msr - Model-specific register support' CONFIG_X86_MSR
@@ -248,6 +249,8 @@ source drivers/pnp/Config.in
source drivers/block/Config.in
+source drivers/md/Config.in
+
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
fi
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index ce51570da..7dddf3057 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -26,8 +26,8 @@ CONFIG_KMOD=y
# CONFIG_M586 is not set
# CONFIG_M586TSC is not set
# CONFIG_M586MMX is not set
-CONFIG_M686=y
-# CONFIG_M686FXSR is not set
+# CONFIG_M686 is not set
+CONFIG_M686FXSR=y
# CONFIG_MK6 is not set
# CONFIG_MK7 is not set
# CONFIG_MCRUSOE is not set
@@ -44,13 +44,15 @@ CONFIG_X86_TSC=y
CONFIG_X86_GOOD_APIC=y
CONFIG_X86_PGE=y
CONFIG_X86_USE_PPRO_CHECKSUM=y
+CONFIG_X86_FXSR=y
+CONFIG_X86_XMM=y
+# CONFIG_TOSHIBA is not set
# CONFIG_MICROCODE is not set
# CONFIG_X86_MSR is not set
# CONFIG_X86_CPUID is not set
CONFIG_NOHIGHMEM=y
# CONFIG_HIGHMEM4G is not set
# CONFIG_HIGHMEM64G is not set
-# CONFIG_MATH_EMULATION is not set
# CONFIG_MTRR is not set
CONFIG_SMP=y
CONFIG_HAVE_DEC_LOCK=y
@@ -112,17 +114,24 @@ CONFIG_BLK_DEV_FD=y
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_LVM_PROC_FS is not set
#
# Networking options
@@ -224,7 +233,6 @@ CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
-# CONFIG_VIA82CXXX_TUNING is not set
# CONFIG_IDE_CHIPSETS is not set
# CONFIG_IDEDMA_AUTO is not set
# CONFIG_DMA_NONPCI is not set
@@ -262,12 +270,12 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
@@ -276,11 +284,10 @@ 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_IPS 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
@@ -299,6 +306,8 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
# CONFIG_SCSI_SEAGATE is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
@@ -357,14 +366,18 @@ CONFIG_EEPRO100=y
# CONFIG_NE2K_PCI is not set
# CONFIG_8139TOO is not set
# CONFIG_SIS900 is not set
+# CONFIG_EPIC100 is not set
+# CONFIG_SUNDANCE is not set
# CONFIG_TLAN is not set
# CONFIG_VIA_RHINE is not set
+# CONFIG_WINBOND_840 is not set
# CONFIG_NET_POCKET is not set
#
# Ethernet (1000 Mbit)
#
# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_PPP is not set
@@ -501,10 +514,6 @@ CONFIG_PCMCIA_SERIAL=y
#
# Multimedia devices
#
-
-#
-# Video For Linux
-#
# CONFIG_VIDEO_DEV is not set
#
@@ -588,12 +597,64 @@ CONFIG_VGA_CONSOLE=y
#
# Sound
#
-# CONFIG_SOUND is not set
+CONFIG_SOUND=y
+# CONFIG_SOUND_CMPCI is not set
+# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
+# CONFIG_SOUND_CS4281 is not set
+# CONFIG_SOUND_ES1370 is not set
+CONFIG_SOUND_ES1371=y
+# CONFIG_SOUND_ESSSOLO1 is not set
+# CONFIG_SOUND_MAESTRO is not set
+# CONFIG_SOUND_SONICVIBES is not set
+# CONFIG_SOUND_TRIDENT is not set
+# CONFIG_SOUND_MSNDCLAS is not set
+# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
+# CONFIG_SOUND_OSS is not set
+# CONFIG_SOUND_TVMIXER is not set
#
# USB support
#
-# CONFIG_USB is not set
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+# CONFIG_USB_BANDWIDTH is not set
+
+#
+# USB Controllers
+#
+CONFIG_USB_UHCI_ALT=y
+# CONFIG_USB_OHCI is not set
+
+#
+# USB Devices
+#
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_AUDIO is not set
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_SERIAL is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_DC2XX is not set
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_USS720 is not set
+# CONFIG_USB_DABUSB is not set
+
+#
+# USB Human Interface Devices (HID)
+#
+
+#
+# Input core support is needed for USB HID
+#
#
# Kernel hacking
diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile
index d1388eec3..a8ea61306 100644
--- a/arch/i386/kernel/Makefile
+++ b/arch/i386/kernel/Makefile
@@ -18,7 +18,7 @@ export-objs := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o
obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \
ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \
- pci-dma.o i386_ksyms.o i387.o
+ pci-dma.o i386_ksyms.o i387.o bluesmoke.o
ifdef CONFIG_PCI
diff --git a/arch/i386/kernel/acpi.c b/arch/i386/kernel/acpi.c
index 9993d8331..211a6ce50 100644
--- a/arch/i386/kernel/acpi.c
+++ b/arch/i386/kernel/acpi.c
@@ -21,6 +21,12 @@
/*
* See http://www.geocities.com/SiliconValley/Hardware/3165/
* for the user-level ACPI stuff
+ *
+ * Changes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 2000/08/31
+ * - check copy*user return
+ * - get rid of check_region
+ * - get rid of verify_area
*/
#include <linux/config.h>
@@ -135,8 +141,7 @@ static int acpi_do_stat(ctl_table *ctl,
*len = 0;
return 0;
}
- copy_to_user(buffer, str, size);
- return 0;
+ return copy_to_user(buffer, str, size) ? -EFAULT : 0;
}
static void cx_statistics(unsigned int x, unsigned long time)
@@ -1283,11 +1288,9 @@ static void acpi_power_off(void)
*/
static int acpi_claim(unsigned long start, unsigned long size)
{
- if (start && size) {
- if (check_region(start, size))
+ if (start && size)
+ if (!request_region(start, size, "acpi"))
return -EBUSY;
- request_region(start, size, "acpi");
- }
return 0;
}
@@ -1391,7 +1394,8 @@ static int acpi_do_ulong(ctl_table *ctl,
val = *(unsigned long*) ctl->data;
size = sprintf(str, "0x%08lx\n", val);
if (*len >= size) {
- copy_to_user(buffer, str, size);
+ if (copy_to_user(buffer, str, size))
+ return -EFAULT;
*len = size;
}
else
@@ -1404,7 +1408,8 @@ static int acpi_do_ulong(ctl_table *ctl,
size = sizeof(str) - 1;
if (size > *len)
size = *len;
- copy_from_user(str, buffer, size);
+ if (copy_from_user(str, buffer, size))
+ return -EFAULT;
str[size] = '\0';
val = simple_strtoul(str, &strend, 0);
if (strend == str)
@@ -1423,22 +1428,22 @@ static int acpi_verify_table(void *buffer,
size_t size,
struct acpi_table_info *info)
{
+ struct acpi_table hdr;
+ size_t table_size;
+
if (size < sizeof(struct acpi_table))
return -EINVAL;
- else if (verify_area(VERIFY_READ, buffer, size))
+
+ if (copy_from_user(&hdr, buffer, sizeof(hdr)))
return -EFAULT;
- else {
- struct acpi_table hdr;
- size_t table_size;
- copy_from_user(&hdr, buffer, sizeof(hdr));
- table_size = (size_t) hdr.length;
- if (hdr.signature != info->expected_signature
- || table_size < size
- || (info->expected_size
- && table_size != info->expected_size))
- return -EINVAL;
- }
+ table_size = (size_t) hdr.length;
+ if (hdr.signature != info->expected_signature
+ || table_size < size
+ || (info->expected_size
+ && table_size != info->expected_size))
+ return -EINVAL;
+
return 0;
}
@@ -1496,7 +1501,8 @@ static int acpi_do_table(ctl_table *ctl,
error = acpi_verify_table(buffer, *len, info);
if (error)
return error;
- copy_from_user(&hdr, buffer, sizeof(hdr));
+ if (copy_from_user(&hdr, buffer, sizeof(hdr)))
+ return -EFAULT;
table_size = (size_t) hdr.length;
write_lock(&acpi_do_table_lock);
@@ -1517,7 +1523,8 @@ static int acpi_do_table(ctl_table *ctl,
error = -ENOMEM;
}
if (data)
- copy_from_user(data, buffer, size);
+ if (copy_from_user(data, buffer, size))
+ error = -EFAULT;
write_unlock(&acpi_do_table_lock);
}
@@ -1565,7 +1572,8 @@ static int acpi_do_event_reg(ctl_table *ctl,
size = sprintf(str, "0x%08x\n", val);
if (*len >= size) {
- copy_to_user(buffer, str, size);
+ if (copy_to_user(buffer, str, size))
+ return -EFAULT;
*len = size;
}
else
@@ -1580,7 +1588,8 @@ static int acpi_do_event_reg(ctl_table *ctl,
size = sizeof(str) - 1;
if (size > *len)
size = *len;
- copy_from_user(str, buffer, size);
+ if (copy_from_user(str, buffer, size))
+ return -EFAULT;
str[size] = '\0';
val = (u32) simple_strtoul(str, &strend, 0);
if (strend == str)
@@ -1682,7 +1691,8 @@ static int acpi_do_event(ctl_table *ctl,
pm1_status,
gpe_status,
event_state);
- copy_to_user(buffer, str, size);
+ if (copy_to_user(buffer, str, size))
+ return -EFAULT;
*len = size;
file->f_pos += size;
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index 1626761fb..4e5df4681 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -695,7 +695,7 @@ inline void smp_local_timer_interrupt(struct pt_regs * regs)
* [ if a single-CPU system runs an SMP kernel then we call the local
* interrupt as well. Thus we cannot inline the local irq ... ]
*/
-unsigned int apic_timer_irqs [NR_CPUS] = { 0, };
+unsigned int apic_timer_irqs [NR_CPUS];
void smp_apic_timer_interrupt(struct pt_regs * regs)
{
diff --git a/arch/i386/kernel/bluesmoke.c b/arch/i386/kernel/bluesmoke.c
new file mode 100644
index 000000000..0fecf5851
--- /dev/null
+++ b/arch/i386/kernel/bluesmoke.c
@@ -0,0 +1,109 @@
+/*
+ * Machine Check Handler For PII/PIII
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/processor.h>
+#include <asm/msr.h>
+
+static int banks = 0;
+
+void mcheck_fault(void)
+{
+ int recover=1;
+ u32 alow, ahigh, high, low;
+ u32 mcgstl, mcgsth;
+ int i;
+
+ rdmsr(0x17a, mcgstl, mcgsth);
+ if(mcgstl&(1<<0)) /* Recoverable ? */
+ recover=0;
+
+ printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", smp_processor_id(), mcgsth, mcgstl);
+
+ for(i=0;i<banks;i++)
+ {
+ rdmsr(0x401+i*4,low, high);
+ if(high&(1<<31))
+ {
+ if(high&(1<<29))
+ recover|=1;
+ if(high&(1<<25))
+ recover|=2;
+ printk(KERN_EMERG "Bank %d: %08x%08x", i, high, low);
+ high&=~(1<<31);
+ if(high&(1<<27))
+ {
+ rdmsr(0x402+i*4, alow, ahigh);
+ printk("[%08x%08x]", alow, ahigh);
+ }
+ if(high&(1<<26))
+ {
+ rdmsr(0x402+i*4, alow, ahigh);
+ printk(" at %08x%08x",
+ high, low);
+ }
+ /* Clear it */
+ wrmsr(0x401+i*4, 0UL, 0UL);
+ /* Serialize */
+ wmb();
+ }
+ }
+
+ if(recover&2)
+ panic("CPU context corrupt");
+ if(recover&1)
+ panic("Unable to continue");
+ printk(KERN_EMERG "Attempting to continue.\n");
+ mcgstl&=~(1<<2);
+ wrmsr(0x17a,mcgstl, mcgsth);
+}
+
+
+/*
+ * This has to be run for each processor
+ */
+
+void mcheck_init(void)
+{
+ u32 l, h;
+ int i;
+ struct cpuinfo_x86 *c;
+ static int done=0;
+
+ c=cpu_data+smp_processor_id();
+
+ if(c->x86_vendor!=X86_VENDOR_INTEL)
+ return;
+
+ if(!(c->x86_capability&X86_FEATURE_MCE))
+ return;
+
+ if(!(c->x86_capability&X86_FEATURE_MCA))
+ return;
+
+ /* Ok machine check is available */
+
+ if(done==0)
+ printk(KERN_INFO "Intel machine check architecture supported.\n");
+ rdmsr(0x179, l, h);
+ if(l&(1<<8))
+ wrmsr(0x17b, 0xffffffff, 0xffffffff);
+ banks = l&0xff;
+ for(i=1;i<banks;i++)
+ {
+ wrmsr(0x400+4*i, 0xffffffff, 0xffffffff);
+ }
+ for(i=0;i<banks;i++)
+ {
+ wrmsr(0x401+4*i, 0x0, 0x0);
+ }
+ __asm__ __volatile__ (
+ "movl %%cr4, %%eax\n\t"
+ "orl $0x40, %%eax\n\t"
+ "movl %%eax, %%cr4\n\t" : : : "eax");
+ printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", smp_processor_id());
+ done=1;
+}
diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S
index fb9b7b2ea..57aada831 100644
--- a/arch/i386/kernel/entry.S
+++ b/arch/i386/kernel/entry.S
@@ -414,6 +414,11 @@ ENTRY(page_fault)
pushl $ SYMBOL_NAME(do_page_fault)
jmp error_code
+ENTRY(machine_check)
+ pushl $0
+ pushl $ SYMBOL_NAME(mcheck_fault)
+ jmp error_code
+
ENTRY(spurious_interrupt_bug)
pushl $0
pushl $ SYMBOL_NAME(do_spurious_interrupt_bug)
@@ -643,6 +648,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_madvise)
.long SYMBOL_NAME(sys_getdents64) /* 220 */
.long SYMBOL_NAME(sys_fcntl64)
+ .long SYMBOL_NAME(sys_ni_syscall) /* reserved for TUX */
/*
* NOTE!! This doesn't have to be exact - we just have
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index e1b00a702..c5aece040 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -38,7 +38,7 @@ static spinlock_t ioapic_lock = SPIN_LOCK_UNLOCKED;
/*
* # of IO-APICs and # of IRQ routing registers
*/
-int nr_ioapics = 0;
+int nr_ioapics;
int nr_ioapic_registers[MAX_IO_APICS];
/* I/O APIC entries */
@@ -48,7 +48,7 @@ struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
/* MP IRQ source entries */
-int mp_irq_entries = 0;
+int mp_irq_entries;
#if CONFIG_SMP
# define TARGET_CPUS cpu_online_map
@@ -172,8 +172,8 @@ static void clear_IO_APIC (void)
#define MAX_PIRQS 8
int pirq_entries [MAX_PIRQS];
-int pirqs_enabled = 0;
-int skip_ioapic_setup = 0;
+int pirqs_enabled;
+int skip_ioapic_setup;
static int __init ioapic_setup(char *str)
{
@@ -219,10 +219,10 @@ static int __init find_irq_entry(int apic, int pin, int type)
int i;
for (i = 0; i < mp_irq_entries; i++)
- if ( (mp_irqs[i].mpc_irqtype == type) &&
- (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid) &&
- (mp_irqs[i].mpc_dstirq == pin))
-
+ if (mp_irqs[i].mpc_irqtype == type &&
+ (mp_irqs[i].mpc_dstapic == mp_ioapics[apic].mpc_apicid ||
+ mp_irqs[i].mpc_dstapic == MP_APIC_ALL) &&
+ mp_irqs[i].mpc_dstirq == pin)
return i;
return -1;
@@ -262,7 +262,8 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pci_pin)
int lbus = mp_irqs[i].mpc_srcbus;
for (apic = 0; apic < nr_ioapics; apic++)
- if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic)
+ if (mp_ioapics[apic].mpc_apicid == mp_irqs[i].mpc_dstapic ||
+ mp_irqs[i].mpc_dstapic == MP_APIC_ALL)
break;
if ((mp_bus_id_to_type[lbus] == MP_BUS_PCI) &&
@@ -982,7 +983,10 @@ void disable_IO_APIC(void)
static void __init setup_ioapic_ids_from_mpc (void)
{
struct IO_APIC_reg_00 reg_00;
+ unsigned long phys_id_present_map = phys_cpu_present_map;
int apic;
+ int i;
+ unsigned char old_id;
/*
* Set the IOAPIC ID to the value stored in the MPC table.
@@ -992,6 +996,8 @@ static void __init setup_ioapic_ids_from_mpc (void)
/* Read the register 0 value */
*(int *)&reg_00 = io_apic_read(apic, 0);
+ old_id = mp_ioapics[apic].mpc_apicid;
+
if (mp_ioapics[apic].mpc_apicid >= 0xf) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
apic, mp_ioapics[apic].mpc_apicid);
@@ -1001,21 +1007,41 @@ static void __init setup_ioapic_ids_from_mpc (void)
}
/*
+ * Sanity check, is the ID really free? Every APIC in a
+ * system must have a unique ID or we get lots of nice
+ * 'stuck on smp_invalidate_needed IPI wait' messages.
+ */
+ if (phys_id_present_map & (1 << mp_ioapics[apic].mpc_apicid)) {
+ printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
+ apic, mp_ioapics[apic].mpc_apicid);
+ for (i = 0; i < 0xf; i++)
+ if (!(phys_id_present_map & (1 << i)))
+ break;
+ if (i >= 0xf)
+ panic("Max APIC ID exceeded!\n");
+ printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
+ i);
+ phys_id_present_map |= 1 << i;
+ mp_ioapics[apic].mpc_apicid = i;
+ }
+
+ /*
+ * We need to adjust the IRQ routing table
+ * if the ID changed.
+ */
+ if (old_id != mp_ioapics[apic].mpc_apicid)
+ for (i = 0; i < mp_irq_entries; i++)
+ if (mp_irqs[i].mpc_dstapic == old_id)
+ mp_irqs[i].mpc_dstapic
+ = mp_ioapics[apic].mpc_apicid;
+
+ /*
* Read the right value from the MPC table and
* write it into the ID register.
*/
printk(KERN_INFO "...changing IO-APIC physical APIC ID to %d ...",
mp_ioapics[apic].mpc_apicid);
- /*
- * Sanity check, is the ID really free? Every APIC in the
- * system must have a unique ID or we get lots of nice
- * 'stuck on smp_invalidate_needed IPI wait' messages.
- */
- if (phys_cpu_present_map & (1<<mp_ioapics[apic].mpc_apicid))
- panic("APIC ID %d already used",
- mp_ioapics[apic].mpc_apicid);
-
reg_00.ID = mp_ioapics[apic].mpc_apicid;
io_apic_write(apic, 0, *(int *)&reg_00);
diff --git a/arch/i386/kernel/microcode.c b/arch/i386/kernel/microcode.c
index 1d5b7b3c8..80536a1c4 100644
--- a/arch/i386/kernel/microcode.c
+++ b/arch/i386/kernel/microcode.c
@@ -37,6 +37,13 @@
* Removed ->release(). Removed exclusive open and status bitmap.
* Added microcode_rwsem to serialize read()/write()/ioctl().
* Removed global kernel lock usage.
+ * 1.07 07 Sep 2000, Tigran Aivazian <tigran@veritas.com>
+ * Write 0 to 0x8B msr and then cpuid before reading revision,
+ * so that it works even if there were no update done by the
+ * BIOS. Otherwise, reading from 0x8B gives junk (which happened
+ * to be 0 on my machine which is why it worked even when I
+ * disabled update by the BIOS)
+ * Thanks to Eric W. Biederman <ebiederman@lnxi.com> for the fix.
*/
#include <linux/init.h>
@@ -51,7 +58,7 @@
#include <asm/uaccess.h>
#include <asm/processor.h>
-#define MICROCODE_VERSION "1.06"
+#define MICROCODE_VERSION "1.07"
MODULE_DESCRIPTION("Intel CPU (P6) microcode update driver");
MODULE_AUTHOR("Tigran Aivazian <tigran@veritas.com>");
@@ -188,7 +195,8 @@ static void do_update_one(void *unused)
microcode[i].ldrver == 1 && microcode[i].hdrver == 1) {
found=1;
-
+ wrmsr(0x8B, 0, 0);
+ __asm__ __volatile__ ("cpuid" : : : "ax", "bx", "cx", "dx");
rdmsr(0x8B, val[0], rev);
if (microcode[i].rev <= rev) {
printk(KERN_ERR
diff --git a/arch/i386/kernel/mpparse.c b/arch/i386/kernel/mpparse.c
index 746bea030..b17c30041 100644
--- a/arch/i386/kernel/mpparse.c
+++ b/arch/i386/kernel/mpparse.c
@@ -28,26 +28,26 @@
#include <asm/pgalloc.h>
/* Have we found an MP table */
-int smp_found_config = 0;
+int smp_found_config;
/*
* Various Linux-internal data structures created from the
* MP-table.
*/
int apic_version [MAX_APICS];
-int mp_bus_id_to_type [MAX_MP_BUSSES] = { -1, };
+int mp_bus_id_to_type [MAX_MP_BUSSES];
int mp_bus_id_to_pci_bus [MAX_MP_BUSSES] = { -1, };
-int mp_current_pci_id = 0;
+int mp_current_pci_id;
int pic_mode;
-unsigned long mp_lapic_addr = 0;
+unsigned long mp_lapic_addr;
/* Processor that is doing the boot up */
unsigned int boot_cpu_id = -1U;
/* Internal processor count */
-static unsigned int num_processors = 0;
+static unsigned int num_processors;
/* Bitmask of physically existing CPUs */
-unsigned long phys_cpu_present_map = 0;
+unsigned long phys_cpu_present_map;
/*
* Intel MP BIOS table parsing routines:
@@ -158,19 +158,18 @@ static void __init MP_bus_info (struct mpc_config_bus *m)
str[6] = 0;
Dprintk("Bus #%d is %s\n", m->mpc_busid, str);
- if (strncmp(str, "ISA", 3) == 0) {
+ if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) {
mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA;
- } else if (strncmp(str, "EISA", 4) == 0) {
+ } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) {
mp_bus_id_to_type[m->mpc_busid] = MP_BUS_EISA;
- } else if (strncmp(str, "PCI", 3) == 0) {
+ } else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI)-1) == 0) {
mp_bus_id_to_type[m->mpc_busid] = MP_BUS_PCI;
mp_bus_id_to_pci_bus[m->mpc_busid] = mp_current_pci_id;
mp_current_pci_id++;
- } else if (strncmp(str, "MCA", 3) == 0) {
+ } else if (strncmp(str, BUSTYPE_MCA, sizeof(BUSTYPE_MCA)-1) == 0) {
mp_bus_id_to_type[m->mpc_busid] = MP_BUS_MCA;
} else {
- printk("Unknown bustype %s\n", str);
- panic("cannot handle bus - mail to linux-smp@vger.kernel.org");
+ printk("Unknown bustype %s - ignoring\n", str);
}
}
diff --git a/arch/i386/kernel/mtrr.c b/arch/i386/kernel/mtrr.c
index 05b57c93a..abe198315 100644
--- a/arch/i386/kernel/mtrr.c
+++ b/arch/i386/kernel/mtrr.c
@@ -319,10 +319,10 @@ typedef u8 mtrr_type;
#endif
#ifdef USERSPACE_INTERFACE
-static char *ascii_buffer = NULL;
-static unsigned int ascii_buf_bytes = 0;
+static char *ascii_buffer;
+static unsigned int ascii_buf_bytes;
#endif
-static unsigned int *usage_table = NULL;
+static unsigned int *usage_table;
static DECLARE_MUTEX(main_lock);
/* Private functions */
@@ -356,7 +356,8 @@ static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
if (boot_cpu_data.x86 >= 6) break; /* Athlon and post-Athlon CPUs */
/* else fall through */
case X86_VENDOR_CENTAUR:
- return;
+ if(boot_cpu_data.x86 != 6)
+ return;
/*break;*/
}
/* Save value of CR4 and clear Page Global Enable (bit 7) */
@@ -380,6 +381,7 @@ static void set_mtrr_prepare (struct set_mtrr_context *ctxt)
{
case X86_VENDOR_AMD:
case X86_VENDOR_INTEL:
+ case X86_VENDOR_CENTAUR:
/* Disable MTRRs, and set the default type to uncached */
rdmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
wrmsr (MTRRdefType_MSR, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi);
@@ -403,8 +405,11 @@ static void set_mtrr_done (struct set_mtrr_context *ctxt)
if (boot_cpu_data.x86 >= 6) break; /* Athlon and post-Athlon CPUs */
/* else fall through */
case X86_VENDOR_CENTAUR:
- __restore_flags (ctxt->flags);
- return;
+ if(boot_cpu_data.x86 != 6)
+ {
+ __restore_flags (ctxt->flags);
+ return;
+ }
/*break;*/
}
/* Flush caches and TLBs */
@@ -415,6 +420,7 @@ static void set_mtrr_done (struct set_mtrr_context *ctxt)
{
case X86_VENDOR_AMD:
case X86_VENDOR_INTEL:
+ case X86_VENDOR_CENTAUR:
wrmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
break;
case X86_VENDOR_CYRIX:
@@ -453,9 +459,17 @@ static unsigned int get_num_var_ranges (void)
/*break;*/
case X86_VENDOR_CYRIX:
/* Cyrix have 8 ARRs */
+ return 8;
case X86_VENDOR_CENTAUR:
/* and Centaur has 8 MCR's */
- return 8;
+ if(boot_cpu_data.x86==5)
+ return 8;
+ /* the cyrix III has intel compatible MTRR */
+ if(boot_cpu_data.x86==6)
+ {
+ rdmsr (MTRRcap_MSR, config, dummy);
+ return (config & 0xff);
+ }
/*break;*/
}
return 0;
@@ -471,12 +485,15 @@ static int have_wrcomb (void)
case X86_VENDOR_AMD:
if (boot_cpu_data.x86 < 6) return 1; /* pre-Athlon CPUs */
/* else fall through */
+ case X86_VENDOR_CENTAUR:
+ if (boot_cpu_data.x86 == 5)
+ return 1; /* C6 */
+ /* CyrixIII is Intel like */
case X86_VENDOR_INTEL:
rdmsr (MTRRcap_MSR, config, dummy);
return (config & (1<<10));
/*break;*/
case X86_VENDOR_CYRIX:
- case X86_VENDOR_CENTAUR:
return 1;
/*break;*/
}
@@ -623,7 +640,7 @@ static void centaur_get_mcr (unsigned int reg, unsigned long *base,
} /* End Function centaur_get_mcr */
static void (*get_mtrr) (unsigned int reg, unsigned long *base,
- unsigned long *size, mtrr_type *type) = NULL;
+ unsigned long *size, mtrr_type *type);
static void intel_set_mtrr_up (unsigned int reg, unsigned long base,
unsigned long size, mtrr_type type, int do_safe)
@@ -766,7 +783,7 @@ static void centaur_set_mcr_up (unsigned int reg, unsigned long base,
static void (*set_mtrr_up) (unsigned int reg, unsigned long base,
unsigned long size, mtrr_type type,
- int do_safe) = NULL;
+ int do_safe);
#ifdef CONFIG_SMP
@@ -1194,7 +1211,7 @@ int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char inc
printk ("mtrr: size: %lx base: %lx\n", size, base);
return -EINVAL;
}
- if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR)
+ if (boot_cpu_data.x86_vendor == X86_VENDOR_CENTAUR && boot_cpu_data.x86 == 5)
{
if (type != MTRR_TYPE_WRCOMB)
{
@@ -1779,8 +1796,16 @@ static void __init mtrr_setup(void)
get_free_region = cyrix_get_free_region;
break;
case X86_VENDOR_CENTAUR:
- get_mtrr = centaur_get_mcr;
- set_mtrr_up = centaur_set_mcr_up;
+ if(boot_cpu_data.x86 == 5)
+ {
+ get_mtrr = centaur_get_mcr;
+ set_mtrr_up = centaur_set_mcr_up;
+ }
+ if(boot_cpu_data.x86 == 6)
+ {
+ get_mtrr = intel_get_mtrr;
+ set_mtrr_up = intel_set_mtrr_up;
+ }
break;
}
} /* End Function mtrr_setup */
@@ -1804,8 +1829,11 @@ void __init mtrr_init_boot_cpu(void)
case X86_VENDOR_CYRIX:
cyrix_arr_init ();
break;
- case X86_VENDOR_CENTAUR:
- centaur_mcr_init ();
+ case X86_VENDOR_CENTAUR: /* C6 and Cyrix III have different ones */
+ if(boot_cpu_data.x86 == 5)
+ centaur_mcr_init ();
+ if(boot_cpu_data.x86 == 6)
+ get_mtrr_state(&smp_mtrr_state);
break;
}
} /* End Function mtrr_init_boot_cpu */
@@ -1877,7 +1905,8 @@ int __init mtrr_init(void)
cyrix_arr_init ();
break;
case X86_VENDOR_CENTAUR:
- centaur_mcr_init ();
+ if(boot_cpu_data.x86 == 5)
+ centaur_mcr_init ();
break;
}
#endif /* !CONFIG_SMP */
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c
index 83ec9d192..6d3cf4d9a 100644
--- a/arch/i386/kernel/process.c
+++ b/arch/i386/kernel/process.c
@@ -50,17 +50,17 @@
asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
-int hlt_counter=0;
+int hlt_counter;
/*
* Powermanagement idle function, if any..
*/
-void (*pm_idle)(void) = NULL;
+void (*pm_idle)(void);
/*
* Power off function, if any
*/
-void (*pm_power_off)(void) = NULL;
+void (*pm_power_off)(void);
void disable_hlt(void)
{
@@ -149,9 +149,9 @@ static int __init idle_setup (char *str)
__setup("idle=", idle_setup);
-static long no_idt[2] = {0, 0};
-static int reboot_mode = 0;
-static int reboot_thru_bios = 0;
+static long no_idt[2];
+static int reboot_mode;
+static int reboot_thru_bios;
static int __init reboot_setup(char *str)
{
@@ -525,6 +525,7 @@ void copy_segments(struct task_struct *p, struct mm_struct *new_mm)
asm volatile("movl %%" #seg ",%0":"=m" (*(int *)&(value)))
int copy_thread(int nr, unsigned long clone_flags, unsigned long esp,
+ unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
@@ -686,7 +687,7 @@ void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
asmlinkage int sys_fork(struct pt_regs regs)
{
- return do_fork(SIGCHLD, regs.esp, &regs);
+ return do_fork(SIGCHLD, regs.esp, &regs, 0);
}
asmlinkage int sys_clone(struct pt_regs regs)
@@ -698,7 +699,7 @@ asmlinkage int sys_clone(struct pt_regs regs)
newsp = regs.ecx;
if (!newsp)
newsp = regs.esp;
- return do_fork(clone_flags, newsp, &regs);
+ return do_fork(clone_flags, newsp, &regs, 0);
}
/*
@@ -713,7 +714,7 @@ asmlinkage int sys_clone(struct pt_regs regs)
*/
asmlinkage int sys_vfork(struct pt_regs regs)
{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs);
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, &regs, 0);
}
/*
diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c
index 0bafdc7e2..a9b11561d 100644
--- a/arch/i386/kernel/ptrace.c
+++ b/arch/i386/kernel/ptrace.c
@@ -99,6 +99,7 @@ static int putreg(struct task_struct *child,
case EFL:
value &= FLAG_MASK;
value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK;
+ break;
}
if (regno > GS*4)
regno -= 2*4;
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
index e79572f90..e765a0e94 100644
--- a/arch/i386/kernel/setup.c
+++ b/arch/i386/kernel/setup.c
@@ -95,22 +95,22 @@
* Machine setup..
*/
-char ignore_irq13 = 0; /* set if exception 16 works */
+char ignore_irq13; /* set if exception 16 works */
struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
-unsigned long mmu_cr4_features = 0;
+unsigned long mmu_cr4_features;
/*
* Bus types ..
*/
-int EISA_bus = 0;
-int MCA_bus = 0;
+int EISA_bus;
+int MCA_bus;
/* for MCA, but anyone else can use it if they want */
-unsigned int machine_id = 0;
-unsigned int machine_submodel_id = 0;
-unsigned int BIOS_revision = 0;
-unsigned int mca_pentium_flag = 0;
+unsigned int machine_id;
+unsigned int machine_submodel_id;
+unsigned int BIOS_revision;
+unsigned int mca_pentium_flag;
/*
* Setup options
@@ -123,7 +123,7 @@ struct sys_desc_table_struct {
unsigned char table[0];
};
-struct e820map e820 = { 0 };
+struct e820map e820;
unsigned char aux_device_present;
@@ -135,7 +135,7 @@ extern int rd_image_start; /* starting block # of image */
extern int root_mountflags;
extern char _text, _etext, _edata, _end;
-extern unsigned long cpu_hz;
+extern unsigned long cpu_khz;
/*
* This is set up by the setup-routine at boot-time
@@ -291,7 +291,7 @@ visws_get_board_type_and_rev(void)
#endif
-static char command_line[COMMAND_LINE_SIZE] = { 0, };
+static char command_line[COMMAND_LINE_SIZE];
char saved_command_line[COMMAND_LINE_SIZE];
struct resource standard_io_resources[] = {
@@ -875,7 +875,8 @@ static int __init amd_model(struct cpuinfo_x86 *c)
* Set MTRR capability flag if appropriate
*/
if(boot_cpu_data.x86 == 5) {
- if((boot_cpu_data.x86_model == 9) ||
+ if((boot_cpu_data.x86_model == 13) ||
+ (boot_cpu_data.x86_model == 9) ||
((boot_cpu_data.x86_model == 8) &&
(boot_cpu_data.x86_mask >= 8)))
c->x86_capability |= X86_FEATURE_MTRR;
@@ -916,7 +917,7 @@ static int __init amd_model(struct cpuinfo_x86 *c)
}
break;
}
- if (c->x86_model == 8 || c->x86_model == 9)
+ if (c->x86_model == 8 || c->x86_model == 9 || c->x86_model == 13)
{
/* The more serious chips .. */
@@ -1650,6 +1651,7 @@ int get_cpuinfo(char * buffer)
int i, n;
for (n = 0; n < NR_CPUS; n++, c++) {
+ int fpu_exception;
#ifdef CONFIG_SMP
if (!(cpu_online_map & (1<<n)))
continue;
@@ -1672,7 +1674,7 @@ int get_cpuinfo(char * buffer)
if (c->x86_capability & X86_FEATURE_TSC) {
p += sprintf(p, "cpu MHz\t\t: %lu.%06lu\n",
- cpu_hz / 1000000, (cpu_hz % 1000000));
+ cpu_khz / 1000, (cpu_khz % 1000));
}
/* Cache size */
@@ -1722,7 +1724,9 @@ int get_cpuinfo(char * buffer)
(c->x86_capability & X86_FEATURE_SEP) &&
c->x86_model < 3 &&
c->x86_mask < 3;
-
+
+ /* We use exception 16 if we have hardware math and we've either seen it or the CPU claims it is internal */
+ fpu_exception = c->hard_math && (ignore_irq13 | (c->x86_capability & X86_FEATURE_FPU));
p += sprintf(p, "fdiv_bug\t: %s\n"
"hlt_bug\t\t: %s\n"
"sep_bug\t\t: %s\n"
@@ -1739,7 +1743,7 @@ int get_cpuinfo(char * buffer)
c->f00f_bug ? "yes" : "no",
c->coma_bug ? "yes" : "no",
c->hard_math ? "yes" : "no",
- (c->hard_math && ignore_irq13) ? "yes" : "no",
+ fpu_exception ? "yes" : "no",
c->cpuid_level,
c->wp_works_ok ? "yes" : "no");
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c
index 116816f1f..2423a8b06 100644
--- a/arch/i386/kernel/signal.c
+++ b/arch/i386/kernel/signal.c
@@ -682,7 +682,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
/* FALLTHRU */
default:
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
@@ -690,6 +690,13 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
}
}
+ /* Reenable any watchpoints before delivering the
+ * signal to user space. The processor register will
+ * have been cleared if the watchpoint triggered
+ * inside the kernel.
+ */
+ __asm__("movl %0,%%db7" : : "r" (current->thread.debugreg[7]));
+
/* Whee! Actually deliver the signal. */
handle_signal(signr, ka, &info, oldset, regs);
return 1;
diff --git a/arch/i386/kernel/smp.c b/arch/i386/kernel/smp.c
index 4a118ab17..6ce9eb61e 100644
--- a/arch/i386/kernel/smp.c
+++ b/arch/i386/kernel/smp.c
@@ -414,13 +414,15 @@ void smp_send_reschedule(int cpu)
*/
static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
-static volatile struct call_data_struct {
+struct call_data_struct {
void (*func) (void *info);
void *info;
atomic_t started;
atomic_t finished;
int wait;
-} *call_data = NULL;
+};
+
+static struct call_data_struct * call_data = NULL;
/*
* this function sends a 'generic call function' IPI to all other CPUs
@@ -443,7 +445,7 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
*/
{
struct call_data_struct data;
- int ret, cpus = smp_num_cpus-1;
+ int cpus = smp_num_cpus-1;
if (!cpus)
return 0;
@@ -464,7 +466,6 @@ int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
while (atomic_read(&data.started) != cpus)
barrier();
- ret = 0;
if (wait)
while (atomic_read(&data.finished) != cpus)
barrier();
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c
index 7629bb3d2..6092aec3b 100644
--- a/arch/i386/kernel/smpboot.c
+++ b/arch/i386/kernel/smpboot.c
@@ -46,7 +46,7 @@
#include <asm/pgalloc.h>
/* Set if we find a B stepping CPU */
-static int smp_b_stepping = 0;
+static int smp_b_stepping;
/* Setup configured maximum number of CPUs to activate */
static int max_cpus = -1;
@@ -55,21 +55,21 @@ static int max_cpus = -1;
int smp_num_cpus = 1;
/* Bitmask of currently online CPUs */
-unsigned long cpu_online_map = 0;
+unsigned long cpu_online_map;
/* which CPU (physical APIC ID) maps to which logical CPU number */
volatile int x86_apicid_to_cpu[NR_CPUS];
/* which logical CPU number maps to which CPU (physical APIC ID) */
volatile int x86_cpu_to_apicid[NR_CPUS];
-static volatile unsigned long cpu_callin_map = 0;
-static volatile unsigned long cpu_callout_map = 0;
+static volatile unsigned long cpu_callin_map;
+static volatile unsigned long cpu_callout_map;
/* Per CPU bogomips and other parameters */
struct cpuinfo_x86 cpu_data[NR_CPUS];
/* Set when the idlers are all forked */
-int smp_threads_ready = 0;
+int smp_threads_ready;
/*
* Setup routine for controlling SMP activation
@@ -194,7 +194,7 @@ void __init smp_commence(void)
static atomic_t tsc_start_flag = ATOMIC_INIT(0);
static atomic_t tsc_count_start = ATOMIC_INIT(0);
static atomic_t tsc_count_stop = ATOMIC_INIT(0);
-static unsigned long long tsc_values[NR_CPUS] = { 0, };
+static unsigned long long tsc_values[NR_CPUS];
#define NR_LOOPS 5
@@ -438,7 +438,7 @@ void __init smp_callin(void)
synchronize_tsc_ap();
}
-int cpucount = 0;
+int cpucount;
extern int cpu_idle(void);
@@ -497,7 +497,7 @@ static int __init fork_by_hand(void)
* don't care about the eip and regs settings since
* we'll never reschedule the forked task.
*/
- return do_fork(CLONE_VM|CLONE_PID, 0, &regs);
+ return do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0);
}
#if APIC_DEBUG
@@ -774,7 +774,7 @@ static void __init do_boot_cpu (int apicid)
}
cycles_t cacheflush_time;
-extern unsigned long cpu_hz;
+extern unsigned long cpu_khz;
static void smp_tune_scheduling (void)
{
@@ -791,7 +791,7 @@ static void smp_tune_scheduling (void)
* the cache size)
*/
- if (!cpu_hz) {
+ if (!cpu_khz) {
/*
* this basically disables processor-affinity
* scheduling on SMP without a TSC.
@@ -805,12 +805,12 @@ static void smp_tune_scheduling (void)
bandwidth = 100;
}
- cacheflush_time = (cpu_hz>>20) * (cachesize<<10) / bandwidth;
+ cacheflush_time = (cpu_khz>>10) * (cachesize<<10) / bandwidth;
}
printk("per-CPU timeslice cutoff: %ld.%02ld usecs.\n",
- (long)cacheflush_time/(cpu_hz/1000000),
- ((long)cacheflush_time*100/(cpu_hz/1000000)) % 100);
+ (long)cacheflush_time/(cpu_khz/1000),
+ ((long)cacheflush_time*100/(cpu_khz/1000)) % 100);
}
/*
diff --git a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
index 4bb184112..3a9df08e7 100644
--- a/arch/i386/kernel/time.c
+++ b/arch/i386/kernel/time.c
@@ -64,7 +64,7 @@
#include <linux/irq.h>
-unsigned long cpu_hz; /* Detected as we calibrate the TSC */
+unsigned long cpu_khz; /* Detected as we calibrate the TSC */
/* Number of usecs that the last interrupt was delayed */
static int delay_at_last_interrupt;
@@ -504,37 +504,6 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
}
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static inline unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
/* not static: needed by APM */
unsigned long get_cmos_time(void)
{
@@ -707,12 +676,12 @@ void __init time_init(void)
* The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
* clock/second. Our precision is about 100 ppm.
*/
- { unsigned long eax=0, edx=1000000;
+ { unsigned long eax=0, edx=1000;
__asm__("divl %2"
- :"=a" (cpu_hz), "=d" (edx)
+ :"=a" (cpu_khz), "=d" (edx)
:"r" (tsc_quotient),
"0" (eax), "1" (edx));
- printk("Detected %ld Hz processor.\n", cpu_hz);
+ printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000);
}
}
}
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c
index 7bd8a04d0..953c23d55 100644
--- a/arch/i386/kernel/traps.c
+++ b/arch/i386/kernel/traps.c
@@ -95,6 +95,7 @@ asmlinkage void simd_coprocessor_error(void);
asmlinkage void reserved(void);
asmlinkage void alignment_check(void);
asmlinkage void spurious_interrupt_bug(void);
+asmlinkage void machine_check(void);
int kstack_depth_to_print = 24;
@@ -415,8 +416,8 @@ inline void nmi_watchdog_tick(struct pt_regs * regs)
* here too!]
*/
- static unsigned int last_irq_sums [NR_CPUS] = { 0, },
- alert_counter [NR_CPUS] = { 0, };
+ static unsigned int last_irq_sums [NR_CPUS],
+ alert_counter [NR_CPUS];
/*
* Since current-> is always on the stack, and we always switch
@@ -491,17 +492,26 @@ asmlinkage void do_nmi(struct pt_regs * regs, long error_code)
}
/*
- * Careful - we must not do a lock-kernel until we have checked that the
- * debug fault happened in user mode. Getting debug exceptions while
- * in the kernel has to be handled without locking, to avoid deadlocks..
+ * Our handling of the processor debug registers is non-trivial.
+ * We do not clear them on entry and exit from the kernel. Therefore
+ * it is possible to get a watchpoint trap here from inside the kernel.
+ * However, the code in ./ptrace.c has ensured that the user can
+ * only set watchpoints on userspace addresses. Therefore the in-kernel
+ * watchpoint trap can only occur in code which is reading/writing
+ * from user space. Such code must not hold kernel locks (since it
+ * can equally take a page fault), therefore it is safe to call
+ * force_sig_info even though that claims and releases locks.
+ *
+ * Code in ./signal.c ensures that the debug control register
+ * is restored before we deliver any signal, and therefore that
+ * user code runs with the correct debug control register even though
+ * we clear it here.
*
* Being careful here means that we don't have to be as careful in a
* lot of more complicated places (task switching can be a bit lazy
* about restoring all the debug state, and ptrace doesn't have to
* find every occurrence of the TF bit that could be saved away even
- * by user code - and we don't have to be careful about what values
- * can be written to the debug registers because there are no really
- * bad cases).
+ * by user code)
*/
asmlinkage void do_debug(struct pt_regs * regs, long error_code)
{
@@ -520,6 +530,9 @@ asmlinkage void do_debug(struct pt_regs * regs, long error_code)
if (regs->eflags & VM_MASK)
goto debug_vm86;
+ /* Save debug status register where ptrace can see it */
+ tsk->thread.debugreg[6] = condition;
+
/* Mask out spurious TF errors due to lazy TF clearing */
if (condition & DR_STEP) {
/*
@@ -535,30 +548,33 @@ asmlinkage void do_debug(struct pt_regs * regs, long error_code)
goto clear_TF;
}
- /* If this is a kernel mode trap, we need to reset db7 to allow us to continue sanely */
- if ((regs->xcs & 3) == 0)
- goto clear_dr7;
-
/* Ok, finally something we can handle */
tsk->thread.trap_no = 1;
tsk->thread.error_code = error_code;
info.si_signo = SIGTRAP;
info.si_errno = 0;
info.si_code = TRAP_BRKPT;
- info.si_addr = (void *)regs->eip;
+
+ /* If this is a kernel mode trap, save the user PC on entry to
+ * the kernel, that's what the debugger can make sense of.
+ */
+ info.si_addr = ((regs->xcs & 3) == 0) ? (void *)tsk->thread.eip :
+ (void *)regs->eip;
force_sig_info(SIGTRAP, &info, tsk);
- return;
-
-debug_vm86:
- handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
- return;
+ /* Disable additional traps. They'll be re-enabled when
+ * the signal is delivered.
+ */
clear_dr7:
__asm__("movl %0,%%db7"
: /* no output */
: "r" (0));
return;
+debug_vm86:
+ handle_vm86_trap((struct kernel_vm86_regs *) regs, error_code, 1);
+ return;
+
clear_TF:
regs->eflags &= ~TF_MASK;
return;
@@ -641,7 +657,6 @@ void simd_math_error(void *eip)
*/
task = current;
save_init_fpu(task);
- load_mxcsr(0x1f80);
task->thread.trap_no = 19;
task->thread.error_code = 0;
info.si_signo = SIGFPE;
@@ -964,6 +979,7 @@ void __init trap_init(void)
set_trap_gate(15,&spurious_interrupt_bug);
set_trap_gate(16,&coprocessor_error);
set_trap_gate(17,&alignment_check);
+ set_trap_gate(18,&machine_check);
set_trap_gate(19,&simd_coprocessor_error);
set_system_gate(SYSCALL_VECTOR,&system_call);
diff --git a/arch/i386/kernel/vm86.c b/arch/i386/kernel/vm86.c
index 9875a3bdb..15b20d695 100644
--- a/arch/i386/kernel/vm86.c
+++ b/arch/i386/kernel/vm86.c
@@ -565,8 +565,8 @@ void handle_vm86_fault(struct kernel_vm86_regs * regs, long error_code)
static struct vm86_irqs {
struct task_struct *tsk;
int sig;
-} vm86_irqs[16] = {{0},};
-static int irqbits=0;
+} vm86_irqs[16];
+static int irqbits;
#define ALLOWED_SIGS ( 1 /* 0 = don't send a signal */ \
| (1 << SIGUSR1) | (1 << SIGUSR2) | (1 << SIGIO) | (1 << SIGURG) \
diff --git a/arch/i386/lib/checksum.S b/arch/i386/lib/checksum.S
index 0d66abee0..bfc638953 100644
--- a/arch/i386/lib/checksum.S
+++ b/arch/i386/lib/checksum.S
@@ -394,26 +394,32 @@ csum_partial_copy_generic:
movl ARGBASE+8(%esp),%edi #dst
movl ARGBASE+12(%esp),%ecx #len
movl ARGBASE+16(%esp),%eax #sum
- movl %ecx, %edx
+# movl %ecx, %edx
movl %ecx, %ebx
+ movl %esi, %edx
shrl $6, %ecx
andl $0x3c, %ebx
negl %ebx
subl %ebx, %esi
subl %ebx, %edi
+ lea -1(%esi),%edx
+ andl $-32,%edx
lea 3f(%ebx,%ebx), %ebx
testl %esi, %esi
- jmp *%ebx
+ jmp *%ebx
1: addl $64,%esi
addl $64,%edi
+ SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl)
ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52)
ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36)
ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20)
ROUND (-16) ROUND(-12) ROUND(-8) ROUND(-4)
3: adcl $0,%eax
+ addl $64, %edx
dec %ecx
jge 1b
-4: andl $3, %edx
+4: movl ARGBASE+12(%esp),%edx #len
+ andl $3, %edx
jz 7f
cmpl $2, %edx
jb 5f
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c
index ba5c2e7ba..66f846925 100644
--- a/arch/i386/mm/ioremap.c
+++ b/arch/i386/mm/ioremap.c
@@ -126,7 +126,7 @@ void * __ioremap(unsigned long phys_addr, unsigned long size, unsigned long flag
t_addr = __va(phys_addr);
t_end = t_addr + (size - 1);
- for(page = virt_to_page(t_addr); page < virt_to_page(t_end); page++)
+ for(page = virt_to_page(t_addr); page <= virt_to_page(t_end); page++)
if(!PageReserved(page))
return NULL;
}
diff --git a/arch/ia64/config.in b/arch/ia64/config.in
index 0fdf86c19..97d622276 100644
--- a/arch/ia64/config.in
+++ b/arch/ia64/config.in
@@ -99,6 +99,7 @@ source drivers/mtd/Config.in
source drivers/pnp/Config.in
source drivers/block/Config.in
source drivers/i2o/Config.in
+source drivers/md/Config.in
mainmenu_option next_comment
comment 'ATA/IDE/MFM/RLL support'
diff --git a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
index ad963b92f..5fb064a3b 100644
--- a/arch/ia64/ia32/ia32_entry.S
+++ b/arch/ia64/ia32/ia32_entry.S
@@ -91,8 +91,8 @@ GLOBAL_ENTRY(sys32_fork)
UNW(.body)
mov out1=0
- mov out2=0
- adds out3=IA64_SWITCH_STACK_SIZE+16,sp
+ mov out3=0
+ adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = &regs
br.call.sptk.few rp=do_fork
.ret3: mov ar.pfs=loc1
UNW(.restore sp)
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index d55835df6..32d83ae75 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -98,37 +98,6 @@ phys_reset_system (int reset_type, efi_status_t status,
efi_call_phys(__va(runtime->reset_system), status, data_size, __pa(data));
}
-/*
- * Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static inline unsigned long
-mktime (unsigned int year, unsigned int mon, unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return ((((unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day)
- + year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
void
efi_gettimeofday (struct timeval *tv)
{
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
index e37bd0df8..eba75378e 100644
--- a/arch/ia64/kernel/entry.S
+++ b/arch/ia64/kernel/entry.S
@@ -68,8 +68,8 @@ GLOBAL_ENTRY(sys_clone2)
mov loc1=r16 // save ar.pfs across do_fork
UNW(.body)
mov out1=in1
- mov out2=in2
- adds out3=IA64_SWITCH_STACK_SIZE+16,sp // out3 = &regs
+ mov out3=in2
+ adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = &regs
mov out0=in0 // out0 = clone_flags
br.call.sptk.few rp=do_fork
.ret1: UNW(.restore sp)
@@ -87,8 +87,8 @@ GLOBAL_ENTRY(sys_clone)
mov loc1=r16 // save ar.pfs across do_fork
UNW(.body)
mov out1=in1
- mov out2=0
- adds out3=IA64_SWITCH_STACK_SIZE+16,sp // out3 = &regs
+ mov out3=0
+ adds out2=IA64_SWITCH_STACK_SIZE+16,sp // out2 = &regs
mov out0=in0 // out0 = clone_flags
br.call.sptk.few rp=do_fork
.ret2: UNW(.restore sp)
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
index ca0f7a981..12f312672 100644
--- a/arch/ia64/kernel/signal.c
+++ b/arch/ia64/kernel/signal.c
@@ -570,7 +570,7 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
/* FALLTHRU */
default:
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
diff --git a/arch/m68k/config.in b/arch/m68k/config.in
index 076d9107c..83381857f 100644
--- a/arch/m68k/config.in
+++ b/arch/m68k/config.in
@@ -149,6 +149,8 @@ source drivers/mtd/Config.in
source drivers/block/Config.in
+source drivers/md/Config.in
+
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
fi
diff --git a/arch/m68k/kernel/process.c b/arch/m68k/kernel/process.c
index ef4a49339..6934e4168 100644
--- a/arch/m68k/kernel/process.c
+++ b/arch/m68k/kernel/process.c
@@ -181,12 +181,12 @@ void flush_thread(void)
asmlinkage int m68k_fork(struct pt_regs *regs)
{
- return do_fork(SIGCHLD, rdusp(), regs);
+ return do_fork(SIGCHLD, rdusp(), regs, 0);
}
asmlinkage int m68k_vfork(struct pt_regs *regs)
{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs);
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, rdusp(), regs, 0);
}
asmlinkage int m68k_clone(struct pt_regs *regs)
@@ -199,10 +199,11 @@ asmlinkage int m68k_clone(struct pt_regs *regs)
newsp = regs->d2;
if (!newsp)
newsp = rdusp();
- return do_fork(clone_flags, newsp, regs);
+ return do_fork(clone_flags, newsp, regs, 0);
}
int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index d67617bea..fa13dc390 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -1137,7 +1137,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */
default:
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
diff --git a/arch/m68k/kernel/time.c b/arch/m68k/kernel/time.c
index 9b98fdb75..c58f4eeeb 100644
--- a/arch/m68k/kernel/time.c
+++ b/arch/m68k/kernel/time.c
@@ -102,37 +102,6 @@ static void timer_interrupt(int irq, void *dummy, struct pt_regs * regs)
#endif /* CONFIG_HEARTBEAT */
}
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static inline unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
void time_init(void)
{
unsigned int year, mon, day, hour, min, sec;
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index a14f25c56..d6065716a 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -11,6 +11,7 @@
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/malloc.h>
+#include <linux/time.h>
#include <linux/kd.h>
#include <linux/mm.h>
@@ -499,37 +500,6 @@ void mac_reset(void)
while(1);
}
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
/*
* This function translates seconds since 1970 into a proper date.
*
diff --git a/arch/mips/baget/vacserial.c b/arch/mips/baget/vacserial.c
index cd56c6dd3..1c2918e5b 100644
--- a/arch/mips/baget/vacserial.c
+++ b/arch/mips/baget/vacserial.c
@@ -2843,7 +2843,7 @@ long __init serial_console_init(long kmem_start, long kmem_end)
* device more directly.
*/
-static int initialized = 0;
+static int initialized;
static int rs_debug_init(struct async_struct *info)
{
diff --git a/arch/mips/config.in b/arch/mips/config.in
index 8515a7900..5a0a0642c 100644
--- a/arch/mips/config.in
+++ b/arch/mips/config.in
@@ -197,6 +197,8 @@ source drivers/mtd/Config.in
source drivers/block/Config.in
+source drivers/md/Config.in
+
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
fi
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index a71ad234a..4e1ec7ba1 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -423,37 +423,6 @@ static void ioasic_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
timer_interrupt(irq, dev_id, regs);
}
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static inline unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long) (year / 4 - year / 100 + year / 400 + 367 * mon / 12 + day) +
- year * 365 - 719499
- ) * 24 + hour /* now have hours */
- ) * 60 + min /* now have minutes */
- ) * 60 + sec; /* finally seconds */
-}
-
char cyclecounter_available;
static inline void init_cycle_counter(void)
diff --git a/arch/mips/defconfig b/arch/mips/defconfig
index c1538c663..9b3379fb5 100644
--- a/arch/mips/defconfig
+++ b/arch/mips/defconfig
@@ -87,17 +87,24 @@ CONFIG_SYSCTL=y
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_LVM_PROC_FS is not set
#
# Networking options
@@ -169,7 +176,7 @@ CONFIG_SCSI_CONSTANTS=y
#
# SCSI low-level drivers
#
-CONFIG_SCSI_SGIWD93=y
+CONFIG_SGIWD93_SCSI=y
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
@@ -192,14 +199,14 @@ CONFIG_SCSI_SGIWD93=y
# 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_PAS16 is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_DEBUG is not set
diff --git a/arch/mips/defconfig-cobalt b/arch/mips/defconfig-cobalt
index 627cc710b..57dd72f33 100644
--- a/arch/mips/defconfig-cobalt
+++ b/arch/mips/defconfig-cobalt
@@ -86,22 +86,27 @@ CONFIG_SYSCTL=y
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
CONFIG_BLK_DEV_LOOP=m
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-# CONFIG_MD_RAID0 is not set
-# CONFIG_MD_RAID1 is not set
-# CONFIG_MD_RAID5 is not set
-# CONFIG_MD_BOOT is not set
-# CONFIG_AUTODETECT_RAID is not set
CONFIG_BLK_DEV_RAM=m
CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_INITRD is not set
#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
+# CONFIG_BLK_DEV_MD is not set
+# CONFIG_MD_LINEAR is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_LVM_PROC_FS is not set
+
+#
# Networking options
#
# CONFIG_PACKET is not set
@@ -202,6 +207,7 @@ CONFIG_AIC7XXX_RESET_DELAY=5
# CONFIG_SCSI_AM53C974 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
@@ -213,8 +219,6 @@ CONFIG_AIC7XXX_RESET_DELAY=5
# 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=y
# CONFIG_SCSI_SYM53C8XX is not set
@@ -232,6 +236,8 @@ CONFIG_SCSI_NCR53C8XX_IOMAPPED=y
# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
@@ -284,8 +290,9 @@ CONFIG_NET_ETHERNET=y
#
# Ethernet (1000 Mbit)
#
-# CONFIG_YELLOWFIN is not set
# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -509,7 +516,7 @@ CONFIG_NFS_FS=y
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_SMB_FS=m
-CONFIG_SMB_NLS_REMOTE=""
+# CONFIG_SMB_NLS_DEFAULT is not set
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
# CONFIG_NCPFS_IOCTL_LOCKING is not set
diff --git a/arch/mips/defconfig-decstation b/arch/mips/defconfig-decstation
index b79e4bcb3..882182fff 100644
--- a/arch/mips/defconfig-decstation
+++ b/arch/mips/defconfig-decstation
@@ -81,17 +81,24 @@ CONFIG_TC=y
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_LVM_PROC_FS is not set
#
# Networking options
@@ -173,14 +180,14 @@ CONFIG_SCSI_DECNCR=y
# 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_PAS16 is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_DEBUG is not set
diff --git a/arch/mips/defconfig-ip22 b/arch/mips/defconfig-ip22
index 5ceb991b4..9b3379fb5 100644
--- a/arch/mips/defconfig-ip22
+++ b/arch/mips/defconfig-ip22
@@ -87,17 +87,24 @@ CONFIG_SYSCTL=y
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_LVM_PROC_FS is not set
#
# Networking options
@@ -169,7 +176,7 @@ CONFIG_SCSI_CONSTANTS=y
#
# SCSI low-level drivers
#
-CONFIG_SCSI_SGIWD93=y
+CONFIG_SGIWD93_SCSI=y
# CONFIG_SCSI_7000FASST is not set
# CONFIG_SCSI_ACARD is not set
# CONFIG_SCSI_AHA152X is not set
@@ -192,14 +199,14 @@ CONFIG_SCSI_SGIWD93=y
# 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_PAS16 is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
# CONFIG_SCSI_DEBUG is not set
@@ -220,8 +227,7 @@ CONFIG_VT=y
CONFIG_VT_CONSOLE=y
CONFIG_SGI_NEWPORT_CONSOLE=y
CONFIG_FONT_8x16=y
-CONFIG_PSMOUSE=y
-CONFIG_MOUSE=y
+# CONFIG_PSMOUSE is not set
# CONFIG_UNIX98_PTYS is not set
#
diff --git a/arch/mips/defconfig-orion b/arch/mips/defconfig-orion
index 928d48c73..01dc2b78b 100644
--- a/arch/mips/defconfig-orion
+++ b/arch/mips/defconfig-orion
@@ -82,18 +82,25 @@ CONFIG_NET=y
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
+CONFIG_BLK_DEV_INITRD=y
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=4096
-CONFIG_BLK_DEV_INITRD=y
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_LVM_PROC_FS is not set
#
# Networking options
diff --git a/arch/mips/defconfig-rm200 b/arch/mips/defconfig-rm200
index a418643e2..88c3ab1d5 100644
--- a/arch/mips/defconfig-rm200
+++ b/arch/mips/defconfig-rm200
@@ -90,17 +90,24 @@ CONFIG_BLK_DEV_FD=y
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_LVM_PROC_FS is not set
#
# Networking options
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c
index 2aff468fa..e0986a61a 100644
--- a/arch/mips/kernel/gdb-stub.c
+++ b/arch/mips/kernel/gdb-stub.c
@@ -115,7 +115,7 @@ void handle_exception(struct gdb_regs *regs);
static char input_buffer[BUFMAX];
static char output_buffer[BUFMAX];
-static int initialized = 0; /* !0 means we've been initialized */
+static int initialized; /* !0 means we've been initialized */
static const char hexchars[]="0123456789abcdef";
diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c
index 3329e5e84..5f63b0910 100644
--- a/arch/mips/kernel/irixelf.c
+++ b/arch/mips/kernel/irixelf.c
@@ -1127,7 +1127,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file)
notes[0].datasz = sizeof(prstatus);
notes[0].data = &prstatus;
prstatus.pr_info.si_signo = prstatus.pr_cursig = signr;
- prstatus.pr_sigpend = current->signal.sig[0];
+ prstatus.pr_sigpend = current->pending.signal.sig[0];
prstatus.pr_sighold = current->blocked.sig[0];
psinfo.pr_pid = prstatus.pr_pid = current->pid;
psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid;
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c
index 7254ee95d..6f6556da4 100644
--- a/arch/mips/kernel/irixsig.c
+++ b/arch/mips/kernel/irixsig.c
@@ -264,7 +264,7 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */
default:
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
@@ -429,24 +429,7 @@ irix_sigaction(int sig, const struct sigaction *act,
asmlinkage int irix_sigpending(irix_sigset_t *set)
{
- int err;
-
- if (verify_area(VERIFY_WRITE, set, sizeof(*set)) < 0)
- return -EFAULT;
-
- /* fill in "set" with signals pending but blocked. */
- spin_lock_irq(&current->sigmask_lock);
- err = __put_user(current->blocked.sig[0] & current->signal.sig[0],
- &set->sig[0]);
- err |= __put_user(current->blocked.sig[1] & current->signal.sig[1],
- &set->sig[1]);
- err |= __put_user(current->blocked.sig[2] & current->signal.sig[2],
- &set->sig[2]);
- err |= __put_user(current->blocked.sig[3] & current->signal.sig[3],
- &set->sig[3]);
- spin_unlock_irq(&current->sigmask_lock);
-
- return err;
+ return do_sigpending(set, sizeof(*set));
}
asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old)
@@ -605,7 +588,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
expire = schedule_timeout(expire);
for (i=0; i<=4; i++)
- tmp |= (current->signal.sig[i] & kset.sig[i]);
+ tmp |= (current->pending.signal.sig[i] & kset.sig[i]);
if (tmp)
break;
@@ -622,7 +605,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info,
for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) {
if (sigismember (&kset, sig))
continue;
- if (sigismember (&current->signal, sig)) {
+ if (sigismember (&current->pending.signal, sig)) {
/* XXX need more than this... */
if (info)
info->sig = sig;
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
index a5a630769..6a1a6c326 100644
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -72,6 +72,7 @@ void flush_thread(void)
}
int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 5a9992141..ad66fcb6c 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -662,7 +662,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */
default:
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 2afb00e0a..a7887b6d0 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -97,7 +97,7 @@ asmlinkage int sys_fork(struct pt_regs regs)
int res;
save_static(&regs);
- res = do_fork(SIGCHLD, regs.regs[29], &regs);
+ res = do_fork(SIGCHLD, regs.regs[29], &regs, 0);
return res;
}
@@ -112,7 +112,7 @@ asmlinkage int sys_clone(struct pt_regs regs)
newsp = regs.regs[5];
if (!newsp)
newsp = regs.regs[29];
- res = do_fork(clone_flags, newsp, &regs);
+ res = do_fork(clone_flags, newsp, &regs, 0);
return res;
}
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index 3551fd683..62739e4a6 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -445,37 +445,6 @@ void indy_r4k_timer_interrupt (struct pt_regs *regs)
r4k_timer_interrupt (INDY_R4K_TIMER_IRQ, NULL, regs);
}
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static inline unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
char cyclecounter_available;
static inline void init_cycle_counter(void)
diff --git a/arch/mips/orion/initrd.c b/arch/mips/orion/initrd.c
new file mode 100644
index 000000000..06e05d71f
--- /dev/null
+++ b/arch/mips/orion/initrd.c
@@ -0,0 +1,9 @@
+/*
+* Miscellaneous data structures:
+* WARNING - this file is automatically generated!
+*/
+
+unsigned long orion_initrd_start[] = {
+ 0x1F8B0800,0x7109D539,0x02030300,0x00000000, /* 0 */
+ 0x00000000,0 };
+unsigned long orion_initrd_size = 0x14;
diff --git a/arch/mips64/config.in b/arch/mips64/config.in
index 7bfc0b3a3..129c24913 100644
--- a/arch/mips64/config.in
+++ b/arch/mips64/config.in
@@ -21,7 +21,7 @@ if [ "$CONFIG_SGI_IP27" = "y" ]; then
bool ' Mapped kernel support' CONFIG_MAPPED_KERNEL
bool ' Kernel text replication support' CONFIG_REPLICATE_KTEXT
bool ' Exception handler replication support' CONFIG_REPLICATE_EXHANDLERS
- bool ' Multi-Processing support (Experimental)' CONFIG_SMP
+ bool ' Multi-Processing support' CONFIG_SMP
#bool ' IP27 XXL' CONFIG_SGI_SN0_XXL
fi
endmenu
@@ -129,6 +129,8 @@ source drivers/mtd/Config.in
source drivers/block/Config.in
+source drivers/md/Config.in
+
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
fi
diff --git a/arch/mips64/defconfig b/arch/mips64/defconfig
index 9817d35f3..51d2d3c06 100644
--- a/arch/mips64/defconfig
+++ b/arch/mips64/defconfig
@@ -18,7 +18,7 @@ CONFIG_DISCONTIGMEM=y
# CONFIG_MAPPED_KERNEL is not set
# CONFIG_REPLICATE_KTEXT is not set
# CONFIG_REPLICATE_EXHANDLERS is not set
-# CONFIG_SMP is not set
+CONFIG_SMP=y
CONFIG_BOOT_ELF64=y
CONFIG_ARC64=y
CONFIG_COHERENT_IO=y
@@ -30,7 +30,6 @@ CONFIG_QL_ISP_A64=y
#
# CPU selection
#
-# CONFIG_CPU_GENERIC is not set
# CONFIG_CPU_R4300 is not set
# CONFIG_CPU_R4X00 is not set
# CONFIG_CPU_R5000 is not set
@@ -73,17 +72,24 @@ CONFIG_PCI_NAMES=y
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_LVM_PROC_FS is not set
#
# Networking options
@@ -162,6 +168,7 @@ CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_AM53C974 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
@@ -175,8 +182,6 @@ CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_NCR53C8XX is not set
# CONFIG_SCSI_SYM53C8XX is not set
@@ -188,6 +193,8 @@ CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_QLOGIC_ISP=y
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
@@ -235,6 +242,7 @@ CONFIG_SGI_IOC3_ETH=y
# Ethernet (1000 Mbit)
#
# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_PLIP is not set
diff --git a/arch/mips64/defconfig-ip22 b/arch/mips64/defconfig-ip22
index 64471af14..1e1e020eb 100644
--- a/arch/mips64/defconfig-ip22
+++ b/arch/mips64/defconfig-ip22
@@ -62,17 +62,24 @@ CONFIG_BINFMT_ELF=y
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_LVM_PROC_FS is not set
#
# Networking options
@@ -152,6 +159,7 @@ CONFIG_NETDEVICES=y
# Ethernet (1000 Mbit)
#
# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_PLIP is not set
diff --git a/arch/mips64/defconfig-ip27 b/arch/mips64/defconfig-ip27
index 9817d35f3..51d2d3c06 100644
--- a/arch/mips64/defconfig-ip27
+++ b/arch/mips64/defconfig-ip27
@@ -18,7 +18,7 @@ CONFIG_DISCONTIGMEM=y
# CONFIG_MAPPED_KERNEL is not set
# CONFIG_REPLICATE_KTEXT is not set
# CONFIG_REPLICATE_EXHANDLERS is not set
-# CONFIG_SMP is not set
+CONFIG_SMP=y
CONFIG_BOOT_ELF64=y
CONFIG_ARC64=y
CONFIG_COHERENT_IO=y
@@ -30,7 +30,6 @@ CONFIG_QL_ISP_A64=y
#
# CPU selection
#
-# CONFIG_CPU_GENERIC is not set
# CONFIG_CPU_R4300 is not set
# CONFIG_CPU_R4X00 is not set
# CONFIG_CPU_R5000 is not set
@@ -73,17 +72,24 @@ CONFIG_PCI_NAMES=y
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
+# CONFIG_BLK_CPQ_CISS_DA is not set
# CONFIG_BLK_DEV_DAC960 is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_INITRD is not set
+
+#
+# Multi-device support (RAID and LVM)
+#
+# CONFIG_MD is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
# CONFIG_MD_RAID1 is not set
# CONFIG_MD_RAID5 is not set
-# CONFIG_BLK_DEV_RAM is not set
-# CONFIG_BLK_DEV_INITRD is not set
+# CONFIG_BLK_DEV_LVM is not set
+# CONFIG_LVM_PROC_FS is not set
#
# Networking options
@@ -162,6 +168,7 @@ CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_AM53C974 is not set
# CONFIG_SCSI_MEGARAID is not set
# CONFIG_SCSI_BUSLOGIC is not set
+# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
@@ -175,8 +182,6 @@ CONFIG_SCSI_LOGGING=y
# CONFIG_SCSI_PPA is not set
# CONFIG_SCSI_IMM is not set
# CONFIG_SCSI_NCR53C406A is not set
-# CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_SIM710 is not set
# CONFIG_SCSI_NCR53C7xx is not set
# CONFIG_SCSI_NCR53C8XX is not set
# CONFIG_SCSI_SYM53C8XX is not set
@@ -188,6 +193,8 @@ CONFIG_SCSI_LOGGING=y
CONFIG_SCSI_QLOGIC_ISP=y
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
+# CONFIG_SCSI_SIM710 is not set
+# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
@@ -235,6 +242,7 @@ CONFIG_SGI_IOC3_ETH=y
# Ethernet (1000 Mbit)
#
# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
# CONFIG_SK98LIN is not set
# CONFIG_FDDI is not set
# CONFIG_PLIP is not set
diff --git a/arch/mips64/kernel/ioctl32.c b/arch/mips64/kernel/ioctl32.c
index f177ea94d..a284357a1 100644
--- a/arch/mips64/kernel/ioctl32.c
+++ b/arch/mips64/kernel/ioctl32.c
@@ -24,6 +24,7 @@
#include <linux/blkdev.h>
#include <linux/elevator.h>
#include <linux/auto_fs.h>
+#include <linux/ext2_fs.h>
#include <asm/types.h>
#include <asm/uaccess.h>
diff --git a/arch/mips64/kernel/process.c b/arch/mips64/kernel/process.c
index 924140719..df03ef081 100644
--- a/arch/mips64/kernel/process.c
+++ b/arch/mips64/kernel/process.c
@@ -69,6 +69,7 @@ void flush_thread(void)
}
int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
struct pt_regs * childregs;
diff --git a/arch/mips64/kernel/signal.c b/arch/mips64/kernel/signal.c
index 81daadab8..15b2fc60b 100644
--- a/arch/mips64/kernel/signal.c
+++ b/arch/mips64/kernel/signal.c
@@ -695,7 +695,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */
default:
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
diff --git a/arch/mips64/kernel/signal32.c b/arch/mips64/kernel/signal32.c
index 1988b681c..b3de6d4c9 100644
--- a/arch/mips64/kernel/signal32.c
+++ b/arch/mips64/kernel/signal32.c
@@ -773,7 +773,7 @@ printk("%s: delivering signal.\n", current->comm);
/* FALLTHRU */
default:
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
@@ -879,12 +879,12 @@ asmlinkage int sys32_rt_sigaction(int sig, const struct sigaction32 *act,
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
return -EFAULT;
- err |= __put_user((u32)(u64)new_sa.sa.sa_handler,
+ err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
&oact->sa_handler);
- err |= __put_user(new_sa.sa.sa_flags, &oact->sa_flags);
- err |= __put_user((u32)(u64)new_sa.sa.sa_restorer,
+ err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
+ err |= __put_user((u32)(u64)old_sa.sa.sa_restorer,
&oact->sa_restorer);
- err |= put_sigset(&new_sa.sa.sa_mask, &oact->sa_mask);
+ err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
if (err)
return -EFAULT;
}
diff --git a/arch/mips64/kernel/syscall.c b/arch/mips64/kernel/syscall.c
index daea69e6c..a69558792 100644
--- a/arch/mips64/kernel/syscall.c
+++ b/arch/mips64/kernel/syscall.c
@@ -77,7 +77,7 @@ asmlinkage int sys_fork(abi64_no_regargs, struct pt_regs regs)
int res;
save_static(&regs);
- res = do_fork(SIGCHLD, regs.regs[29], &regs);
+ res = do_fork(SIGCHLD, regs.regs[29], &regs, 0);
return res;
}
@@ -92,7 +92,7 @@ asmlinkage int sys_clone(abi64_no_regargs, struct pt_regs regs)
newsp = regs.regs[5];
if (!newsp)
newsp = regs.regs[29];
- res = do_fork(clone_flags, newsp, &regs);
+ res = do_fork(clone_flags, newsp, &regs, 0);
return res;
}
diff --git a/arch/mips64/sgi-ip22/ip22-timer.c b/arch/mips64/sgi-ip22/ip22-timer.c
index 5b8ea05f7..76ed0c214 100644
--- a/arch/mips64/sgi-ip22/ip22-timer.c
+++ b/arch/mips64/sgi-ip22/ip22-timer.c
@@ -151,37 +151,6 @@ static unsigned long dosample(volatile unsigned char *tcwp,
return ct1 - ct0;
}
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static inline unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
static unsigned long __init get_indy_time(void)
{
struct indy_clock *clock = (struct indy_clock *)INDY_CLOCK_REGS;
diff --git a/arch/mips64/sgi-ip27/ip27-memory.c b/arch/mips64/sgi-ip27/ip27-memory.c
index fd47e0103..f858d098f 100644
--- a/arch/mips64/sgi-ip27/ip27-memory.c
+++ b/arch/mips64/sgi-ip27/ip27-memory.c
@@ -242,7 +242,7 @@ void __init paging_init(void)
pfn_t end_pfn = node_getmaxclick(node);
zones_size[ZONE_DMA] = end_pfn + 1 - start_pfn;
- free_area_init_node(node, NODE_DATA(node), zones_size,
+ free_area_init_node(node, NODE_DATA(node), 0, zones_size,
start_pfn << PAGE_SHIFT, 0);
if ((PLAT_NODE_DATA_STARTNR(node) +
PLAT_NODE_DATA_SIZE(node)) > pagenr)
diff --git a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c
index 7b4b8ef78..8cbb943c8 100644
--- a/arch/mips64/sgi-ip27/ip27-timer.c
+++ b/arch/mips64/sgi-ip27/ip27-timer.c
@@ -205,38 +205,6 @@ void do_settimeofday(struct timeval *tv)
#include <asm/sn/sn0/hubio.h>
#include <asm/pci/bridge.h>
-/*
- * Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static inline unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
static __init unsigned long get_m48t35_time(void)
{
unsigned int year, month, date, hour, min, sec;
diff --git a/arch/ppc/8260_io/Config.in b/arch/ppc/8260_io/Config.in
index 8cdd8c615..4db16a068 100644
--- a/arch/ppc/8260_io/Config.in
+++ b/arch/ppc/8260_io/Config.in
@@ -11,12 +11,15 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
bool 'Ethernet on SCC2' CONFIG_SCC2_ENET
fi
fi
- bool 'FCC Ethernet' CONFIG_FCC_ENET
- if [ "$CONFIG_FCC_ENET" = "y" ]; then
- bool 'Ethernet on FCC1' CONFIG_FCC1_ENET
- if [ "$CONFIG_FCC1_ENET" != "y" ]; then
- bool 'Ethernet on FCC2' CONFIG_FCC2_ENET
- fi
+#
+# CONFIG_FEC_ENET is only used to get netdevices to call our init
+# function. Any combination of FCC1,2,3 are supported.
+#
+ bool 'FCC Ethernet' CONFIG_FEC_ENET
+ if [ "$CONFIG_FEC_ENET" = "y" ]; then
+ bool 'Ethernet on FCC1' CONFIG_FCC1_ENET
+ bool 'Ethernet on FCC2' CONFIG_FCC2_ENET
+ bool 'Ethernet on FCC3' CONFIG_FCC3_ENET
fi
endmenu
fi
diff --git a/arch/ppc/8260_io/Makefile b/arch/ppc/8260_io/Makefile
index 240a85628..8de47b144 100644
--- a/arch/ppc/8260_io/Makefile
+++ b/arch/ppc/8260_io/Makefile
@@ -10,8 +10,8 @@
O_TARGET := 8260_io.a
O_OBJS = commproc.o uart.o
-ifdef CONFIG_FCC_ENET
-O_OBJS += fcc.o
+ifdef CONFIG_FEC_ENET
+O_OBJS += fcc_enet.o
endif
ifdef CONFIG_SCC_ENET
O_OBJS += enet.o
diff --git a/arch/ppc/8260_io/commproc.c b/arch/ppc/8260_io/commproc.c
index 8642fa420..b7c13b167 100644
--- a/arch/ppc/8260_io/commproc.c
+++ b/arch/ppc/8260_io/commproc.c
@@ -69,17 +69,27 @@ m8260_cpm_reset(void)
cpmp = (cpm8260_t *)commproc;
}
-/* Allocate some memory from the dual ported ram. We may want to
- * enforce alignment restrictions, but right now everyone is a good
- * citizen.
+/* Allocate some memory from the dual ported ram.
+ * To help protocols with object alignment restrictions, we do that
+ * if they ask.
*/
uint
-m8260_cpm_dpalloc(uint size)
+m8260_cpm_dpalloc(uint size, uint align)
{
uint retloc;
+ uint align_mask, off;
+ uint savebase;
- if ((dp_alloc_base + size) >= dp_alloc_top)
+ align_mask = align - 1;
+ savebase = dp_alloc_base;
+
+ if ((off = (dp_alloc_base & align_mask)) != 0)
+ dp_alloc_base += (align - off);
+
+ if ((dp_alloc_base + size) >= dp_alloc_top) {
+ dp_alloc_base = savebase;
return(CPM_DP_NOSPACE);
+ }
retloc = dp_alloc_base;
dp_alloc_base += size;
@@ -91,12 +101,22 @@ m8260_cpm_dpalloc(uint size)
* UART "fifos" and the like.
*/
uint
-m8260_cpm_hostalloc(uint size)
+m8260_cpm_hostalloc(uint size, uint align)
{
uint retloc;
+ uint align_mask, off;
+ uint savebase;
- if ((host_buffer + size) >= host_end)
+ align_mask = align - 1;
+ savebase = host_buffer;
+
+ if ((off = (host_buffer & align_mask)) != 0)
+ host_buffer += (align - off);
+
+ if ((host_buffer + size) >= host_end) {
+ host_buffer = savebase;
return(0);
+ }
retloc = host_buffer;
host_buffer += size;
diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c
index 4c8c672fd..e1ff3c092 100644
--- a/arch/ppc/8260_io/enet.c
+++ b/arch/ppc/8260_io/enet.c
@@ -466,8 +466,11 @@ for (;;) {
cep->stats.rx_bytes += pkt_len;
/* This does 16 byte alignment, much more than we need.
- */
- skb = dev_alloc_skb(pkt_len);
+ * The packet length includes FCS, but we don't want to
+ * include that when passing upstream as it messes up
+ * bridging applications.
+ */
+ skb = dev_alloc_skb(pkt_len-4);
if (skb == NULL) {
printk("%s: Memory squeeze, dropping packet.\n", dev->name);
@@ -475,10 +478,10 @@ for (;;) {
}
else {
skb->dev = dev;
- skb_put(skb,pkt_len); /* Make room */
+ skb_put(skb,pkt_len-4); /* Make room */
eth_copy_and_sum(skb,
(unsigned char *)__va(bdp->cbd_bufaddr),
- pkt_len, 0);
+ pkt_len-4, 0);
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
}
@@ -549,10 +552,10 @@ static void set_multicast_list(struct net_device *dev)
/* Log any net taps. */
printk("%s: Promiscuous mode enabled.\n", dev->name);
- cep->sccp->scc_pmsr |= SCC_PMSR_PRO;
+ cep->sccp->scc_pmsr |= SCC_PSMR_PRO;
} else {
- cep->sccp->scc_pmsr &= ~SCC_PMSR_PRO;
+ cep->sccp->scc_pmsr &= ~SCC_PSMR_PRO;
if (dev->flags & IFF_ALLMULTI) {
/* Catch all multicast addresses, so set the
@@ -678,11 +681,11 @@ int __init scc_enet_init(void)
* These are relative offsets in the DP ram address space.
* Initialize base addresses for the buffer descriptors.
*/
- i = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE);
+ i = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8);
ep->sen_genscc.scc_rbase = i;
cep->rx_bd_base = (cbd_t *)&immap->im_dprambase[i];
- i = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE);
+ i = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8);
ep->sen_genscc.scc_tbase = i;
cep->tx_bd_base = (cbd_t *)&immap->im_dprambase[i];
@@ -816,7 +819,7 @@ int __init scc_enet_init(void)
/* Set processing mode. Use Ethernet CRC, catch broadcast, and
* start frame search 22 bit times after RENA.
*/
- sccp->scc_pmsr = (SCC_PMSR_ENCRC | SCC_PMSR_NIB22);
+ sccp->scc_pmsr = (SCC_PSMR_ENCRC | SCC_PSMR_NIB22);
/* It is now OK to enable the Ethernet transmitter.
* Unfortunately, there are board implementation differences here.
diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c
new file mode 100644
index 000000000..da3991ae3
--- /dev/null
+++ b/arch/ppc/8260_io/fcc_enet.c
@@ -0,0 +1,1601 @@
+/*
+ * Fast Ethernet Controller (FCC) driver for Motorola MPC8260.
+ * Copyright (c) 2000 MontaVista Software, Inc. Dan Malek (dmalek@jlc.net)
+ *
+ * This version of the driver is a combination of the 8xx fec and
+ * 8260 SCC Ethernet drivers. People seem to be choosing common I/O
+ * configurations, so this driver will work on the EST8260 boards and
+ * others yet to be announced.
+ *
+ * Right now, I am very watseful with the buffers. I allocate memory
+ * pages and then divide them into 2K frame buffers. This way I know I
+ * have buffers large enough to hold one frame within one buffer descriptor.
+ * Once I get this working, I will use 64 or 128 byte CPM buffers, which
+ * will be much more memory efficient and will easily handle lots of
+ * small packets.
+ *
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+
+#include <asm/immap_8260.h>
+#include <asm/pgtable.h>
+#include <asm/mpc8260.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+#include <asm/uaccess.h>
+#include <asm/cpm_8260.h>
+
+/* The transmitter timeout
+ */
+#define TX_TIMEOUT (2*HZ)
+
+/* The number of Tx and Rx buffers. These are allocated from the page
+ * pool. The code may assume these are power of two, so it it best
+ * to keep them that size.
+ * We don't need to allocate pages for the transmitter. We just use
+ * the skbuffer directly.
+ */
+#define FCC_ENET_RX_PAGES 16
+#define FCC_ENET_RX_FRSIZE 2048
+#define FCC_ENET_RX_FRPPG (PAGE_SIZE / FCC_ENET_RX_FRSIZE)
+#define RX_RING_SIZE (FCC_ENET_RX_FRPPG * FCC_ENET_RX_PAGES)
+#define TX_RING_SIZE 16 /* Must be power of two */
+#define TX_RING_MOD_MASK 15 /* for this to work */
+
+/* The FCC stores dest/src/type, data, and checksum for receive packets.
+ */
+#define PKT_MAXBUF_SIZE 1518
+#define PKT_MINBUF_SIZE 64
+
+/* Maximum input DMA size. Must be a should(?) be a multiple of 4.
+*/
+#define PKT_MAXDMA_SIZE 1520
+
+/* Maximum input buffer size. Must be a multiple of 32.
+*/
+#define PKT_MAXBLR_SIZE 1536
+
+static int fcc_enet_open(struct net_device *dev);
+static int fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static int fcc_enet_rx(struct net_device *dev);
+static void fcc_enet_mii(struct net_device *dev);
+static void fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs);
+static int fcc_enet_close(struct net_device *dev);
+static struct net_device_stats *fcc_enet_get_stats(struct net_device *dev);
+static void set_multicast_list(struct net_device *dev);
+static void restart_fcc(struct net_device *dev);
+
+/* These will be configurable for the FCC choice.
+ * Multiple ports can be configured. There is little choice among the
+ * I/O pins to the PHY, except the clocks. We will need some board
+ * dependent clock selection.
+ * Why in the hell did I put these inside #ifdef's? I dunno, maybe to
+ * help show what pins are used for each device.
+ */
+
+/* I/O Pin assignment for FCC1. I don't yet know the best way to do this,
+ * but there is little variation among the choices.
+ */
+#define PA1_COL ((uint)0x00000001)
+#define PA1_CRS ((uint)0x00000002)
+#define PA1_TXER ((uint)0x00000004)
+#define PA1_TXEN ((uint)0x00000008)
+#define PA1_RXDV ((uint)0x00000010)
+#define PA1_RXER ((uint)0x00000020)
+#define PA1_TXDAT ((uint)0x00003c00)
+#define PA1_RXDAT ((uint)0x0003c000)
+#define PA1_PSORA0 (PA1_RXDAT | PA1_TXDAT)
+#define PA1_PSORA1 (PA1_COL | PA1_CRS | PA1_TXER | PA1_TXEN | \
+ PA1_RXDV | PA1_RXER)
+#define PA1_DIRA0 (PA1_RXDAT | PA1_CRS | PA1_COL | PA1_RXER | PA1_RXDV)
+#define PA1_DIRA1 (PA1_TXDAT | PA1_TXEN | PA1_TXER)
+
+/* CLK12 is receive, CLK11 is transmit. These are board specific.
+*/
+#define PC_F1RXCLK ((uint)0x00000800)
+#define PC_F1TXCLK ((uint)0x00000400)
+#define CMX1_CLK_ROUTE ((uint)0x3e000000)
+#define CMX1_CLK_MASK ((uint)0xff000000)
+
+/* I/O Pin assignment for FCC2. I don't yet know the best way to do this,
+ * but there is little variation among the choices.
+ */
+#define PB2_TXER ((uint)0x00000001)
+#define PB2_RXDV ((uint)0x00000002)
+#define PB2_TXEN ((uint)0x00000004)
+#define PB2_RXER ((uint)0x00000008)
+#define PB2_COL ((uint)0x00000010)
+#define PB2_CRS ((uint)0x00000020)
+#define PB2_TXDAT ((uint)0x000003c0)
+#define PB2_RXDAT ((uint)0x00003c00)
+#define PB2_PSORB0 (PB2_RXDAT | PB2_TXDAT | PB2_CRS | PB2_COL | \
+ PB2_RXER | PB2_RXDV | PB2_TXER)
+#define PB2_PSORB1 (PB2_TXEN)
+#define PB2_DIRB0 (PB2_RXDAT | PB2_CRS | PB2_COL | PB2_RXER | PB2_RXDV)
+#define PB2_DIRB1 (PB2_TXDAT | PB2_TXEN | PB2_TXER)
+
+/* CLK13 is receive, CLK14 is transmit. These are board dependent.
+*/
+#define PC_F2RXCLK ((uint)0x00001000)
+#define PC_F2TXCLK ((uint)0x00002000)
+#define CMX2_CLK_ROUTE ((uint)0x00250000)
+#define CMX2_CLK_MASK ((uint)0x00ff0000)
+
+/* I/O Pin assignment for FCC3. I don't yet know the best way to do this,
+ * but there is little variation among the choices.
+ */
+#define PB3_RXDV ((uint)0x00004000)
+#define PB3_RXER ((uint)0x00008000)
+#define PB3_TXER ((uint)0x00010000)
+#define PB3_TXEN ((uint)0x00020000)
+#define PB3_COL ((uint)0x00040000)
+#define PB3_CRS ((uint)0x00080000)
+#define PB3_TXDAT ((uint)0x0f000000)
+#define PB3_RXDAT ((uint)0x00f00000)
+#define PB3_PSORB0 (PB3_RXDAT | PB3_TXDAT | PB3_CRS | PB3_COL | \
+ PB3_RXER | PB3_RXDV | PB3_TXER | PB3_TXEN)
+#define PB3_PSORB1 (0)
+#define PB3_DIRB0 (PB3_RXDAT | PB3_CRS | PB3_COL | PB3_RXER | PB3_RXDV)
+#define PB3_DIRB1 (PB3_TXDAT | PB3_TXEN | PB3_TXER)
+
+/* CLK15 is receive, CLK16 is transmit. These are board dependent.
+*/
+#define PC_F3RXCLK ((uint)0x00004000)
+#define PC_F3TXCLK ((uint)0x00008000)
+#define CMX3_CLK_ROUTE ((uint)0x00003700)
+#define CMX3_CLK_MASK ((uint)0x0000ff00)
+
+/* MII status/control serial interface.
+*/
+#define PC_MDIO ((uint)0x00400000)
+#define PC_MDCK ((uint)0x00200000)
+
+/* A table of information for supporting FCCs. This does two things.
+ * First, we know how many FCCs we have and they are always externally
+ * numbered from zero. Second, it holds control register and I/O
+ * information that could be different among board designs.
+ */
+typedef struct fcc_info {
+ uint fc_fccnum;
+ uint fc_cpmblock;
+ uint fc_cpmpage;
+ uint fc_proff;
+ uint fc_interrupt;
+ uint fc_trxclocks;
+ uint fc_clockroute;
+ uint fc_clockmask;
+ uint fc_mdio;
+ uint fc_mdck;
+} fcc_info_t;
+
+static fcc_info_t fcc_ports[] = {
+#ifdef CONFIG_FCC1_ENET
+ { 0, CPM_CR_FCC1_SBLOCK, CPM_CR_FCC1_PAGE, PROFF_FCC1, SIU_INT_FCC1,
+ (PC_F1RXCLK | PC_F1TXCLK), CMX1_CLK_ROUTE, CMX1_CLK_MASK,
+ PC_MDIO, PC_MDCK },
+#endif
+#ifdef CONFIG_FCC2_ENET
+ { 1, CPM_CR_FCC2_SBLOCK, CPM_CR_FCC2_PAGE, PROFF_FCC2, SIU_INT_FCC2,
+ (PC_F2RXCLK | PC_F2TXCLK), CMX2_CLK_ROUTE, CMX2_CLK_MASK,
+ PC_MDIO, PC_MDCK },
+#endif
+#ifdef CONFIG_FCC3_ENET
+ { 2, CPM_CR_FCC3_SBLOCK, CPM_CR_FCC3_PAGE, PROFF_FCC3, SIU_INT_FCC3,
+ (PC_F3RXCLK | PC_F3TXCLK), CMX3_CLK_ROUTE, CMX3_CLK_MASK,
+ PC_MDIO, PC_MDCK },
+#endif
+};
+
+/* The FCC buffer descriptors track the ring buffers. The rx_bd_base and
+ * tx_bd_base always point to the base of the buffer descriptors. The
+ * cur_rx and cur_tx point to the currently available buffer.
+ * The dirty_tx tracks the current buffer that is being sent by the
+ * controller. The cur_tx and dirty_tx are equal under both completely
+ * empty and completely full conditions. The empty/ready indicator in
+ * the buffer descriptor determines the actual condition.
+ */
+struct fcc_enet_private {
+ /* The saved address of a sent-in-place packet/buffer, for skfree(). */
+ struct sk_buff* tx_skbuff[TX_RING_SIZE];
+ ushort skb_cur;
+ ushort skb_dirty;
+
+ /* CPM dual port RAM relative addresses.
+ */
+ cbd_t *rx_bd_base; /* Address of Rx and Tx buffers. */
+ cbd_t *tx_bd_base;
+ cbd_t *cur_rx, *cur_tx; /* The next free ring entry */
+ cbd_t *dirty_tx; /* The ring entries to be free()ed. */
+ volatile fcc_t *fccp;
+ volatile fcc_enet_t *ep;
+ struct net_device_stats stats;
+ uint tx_full;
+ spinlock_t lock;
+ uint phy_address;
+ uint phy_type;
+ uint phy_duplex;
+ fcc_info_t *fip;
+};
+
+static void init_fcc_shutdown(fcc_info_t *fip, struct fcc_enet_private *cep,
+ volatile immap_t *immap);
+static void init_fcc_startup(fcc_info_t *fip, struct net_device *dev);
+static void init_fcc_ioports(fcc_info_t *fip, volatile iop8260_t *io,
+ volatile immap_t *immap);
+static void init_fcc_param(fcc_info_t *fip, struct net_device *dev,
+ volatile immap_t *immap);
+
+/* MII processing. We keep this as simple as possible. Requests are
+ * placed on the list (if there is room). When the request is finished
+ * by the MII, an optional function may be called.
+ */
+typedef struct mii_list {
+ uint mii_regval;
+ void (*mii_func)(uint val, struct net_device *dev);
+ struct mii_list *mii_next;
+} mii_list_t;
+
+#define NMII 20
+mii_list_t mii_cmds[NMII];
+mii_list_t *mii_free;
+mii_list_t *mii_head;
+mii_list_t *mii_tail;
+
+static int phyaddr;
+static uint phytype;
+
+static int mii_queue(int request, void (*func)(uint, struct net_device *));
+static void mii_startup_cmds(void);
+static uint mii_send_receive(fcc_info_t *fip, uint cmd);
+
+/* Make MII read/write commands for the FCC.
+*/
+
+#define mk_mii_phyaddr(ADDR) (0x60020000 | ((ADDR) << 23) | (2 << 18))
+
+#define mk_mii_read(REG) (0x60020000 | ((phyaddr << 23) | \
+ (REG & 0x1f) << 18))
+
+#define mk_mii_write(REG, VAL) (0x50020000 | ((phyaddr << 23) | \
+ (REG & 0x1f) << 18) | \
+ (VAL & 0xffff))
+
+
+static int
+fcc_enet_open(struct net_device *dev)
+{
+ netif_start_queue(dev);
+ return 0; /* Always succeed */
+}
+
+static int
+fcc_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv;
+ volatile cbd_t *bdp;
+
+
+ /* Fill in a Tx ring entry */
+ bdp = cep->cur_tx;
+
+#ifndef final_version
+ if (bdp->cbd_sc & BD_ENET_TX_READY) {
+ /* Ooops. All transmit buffers are full. Bail out.
+ * This should not happen, since cep->tx_full should be set.
+ */
+ printk("%s: tx queue full!.\n", dev->name);
+ return 1;
+ }
+#endif
+
+ /* Clear all of the status flags.
+ */
+ bdp->cbd_sc &= ~BD_ENET_TX_STATS;
+
+ /* If the frame is short, tell CPM to pad it.
+ */
+ if (skb->len <= ETH_ZLEN)
+ bdp->cbd_sc |= BD_ENET_TX_PAD;
+ else
+ bdp->cbd_sc &= ~BD_ENET_TX_PAD;
+
+ /* Set buffer length and buffer pointer.
+ */
+ bdp->cbd_datlen = skb->len;
+ bdp->cbd_bufaddr = __pa(skb->data);
+
+ /* Save skb pointer.
+ */
+ cep->tx_skbuff[cep->skb_cur] = skb;
+
+ cep->stats.tx_bytes += skb->len;
+ cep->skb_cur = (cep->skb_cur+1) & TX_RING_MOD_MASK;
+
+ spin_lock_irq(&cep->lock);
+
+ /* Send it on its way. Tell CPM its ready, interrupt when done,
+ * its the last BD of the frame, and to put the CRC on the end.
+ */
+ bdp->cbd_sc |= (BD_ENET_TX_READY | BD_ENET_TX_INTR | BD_ENET_TX_LAST | BD_ENET_TX_TC);
+
+#if 0
+ /* Errata says don't do this.
+ */
+ cep->fccp->fcc_ftodr = 0x8000;
+#endif
+ dev->trans_start = jiffies;
+
+ /* If this was the last BD in the ring, start at the beginning again.
+ */
+ if (bdp->cbd_sc & BD_ENET_TX_WRAP)
+ bdp = cep->tx_bd_base;
+ else
+ bdp++;
+
+ if (bdp->cbd_sc & BD_ENET_TX_READY) {
+ netif_stop_queue(dev);
+ cep->tx_full = 1;
+ }
+
+ cep->cur_tx = (cbd_t *)bdp;
+
+ spin_unlock_irq(&cep->lock);
+
+ return 0;
+}
+
+
+static void
+fcc_enet_timeout(struct net_device *dev)
+{
+ struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv;
+
+ printk("%s: transmit timed out.\n", dev->name);
+ cep->stats.tx_errors++;
+#ifndef final_version
+ {
+ int i;
+ cbd_t *bdp;
+ printk(" Ring data dump: cur_tx %p%s cur_rx %p.\n",
+ cep->cur_tx, cep->tx_full ? " (full)" : "",
+ cep->cur_rx);
+ bdp = cep->tx_bd_base;
+ printk(" Tx @base %p :\n", bdp);
+ for (i = 0 ; i < TX_RING_SIZE; i++, bdp++)
+ printk("%04x %04x %08x\n",
+ bdp->cbd_sc,
+ bdp->cbd_datlen,
+ bdp->cbd_bufaddr);
+ bdp = cep->rx_bd_base;
+ printk(" Rx @base %p :\n", bdp);
+ for (i = 0 ; i < RX_RING_SIZE; i++, bdp++)
+ printk("%04x %04x %08x\n",
+ bdp->cbd_sc,
+ bdp->cbd_datlen,
+ bdp->cbd_bufaddr);
+ }
+#endif
+ if (!cep->tx_full)
+ netif_wake_queue(dev);
+}
+
+/* The interrupt handler.
+ */
+static void
+fcc_enet_interrupt(int irq, void * dev_id, struct pt_regs * regs)
+{
+ struct net_device *dev = dev_id;
+ volatile struct fcc_enet_private *cep;
+ volatile cbd_t *bdp;
+ ushort int_events;
+ int must_restart;
+
+ cep = (struct fcc_enet_private *)dev->priv;
+
+ /* Get the interrupt events that caused us to be here.
+ */
+ int_events = cep->fccp->fcc_fcce;
+ cep->fccp->fcc_fcce = int_events;
+ must_restart = 0;
+
+ /* Handle receive event in its own function.
+ */
+ if (int_events & FCC_ENET_RXF)
+ fcc_enet_rx(dev_id);
+
+ /* Check for a transmit error. The manual is a little unclear
+ * about this, so the debug code until I get it figured out. It
+ * appears that if TXE is set, then TXB is not set. However,
+ * if carrier sense is lost during frame transmission, the TXE
+ * bit is set, "and continues the buffer transmission normally."
+ * I don't know if "normally" implies TXB is set when the buffer
+ * descriptor is closed.....trial and error :-).
+ */
+
+ /* Transmit OK, or non-fatal error. Update the buffer descriptors.
+ */
+ if (int_events & (FCC_ENET_TXE | FCC_ENET_TXB)) {
+ spin_lock(&cep->lock);
+ bdp = cep->dirty_tx;
+ while ((bdp->cbd_sc&BD_ENET_TX_READY)==0) {
+ if ((bdp==cep->cur_tx) && (cep->tx_full == 0))
+ break;
+
+ if (bdp->cbd_sc & BD_ENET_TX_HB) /* No heartbeat */
+ cep->stats.tx_heartbeat_errors++;
+ if (bdp->cbd_sc & BD_ENET_TX_LC) /* Late collision */
+ cep->stats.tx_window_errors++;
+ if (bdp->cbd_sc & BD_ENET_TX_RL) /* Retrans limit */
+ cep->stats.tx_aborted_errors++;
+ if (bdp->cbd_sc & BD_ENET_TX_UN) /* Underrun */
+ cep->stats.tx_fifo_errors++;
+ if (bdp->cbd_sc & BD_ENET_TX_CSL) /* Carrier lost */
+ cep->stats.tx_carrier_errors++;
+
+
+ /* No heartbeat or Lost carrier are not really bad errors.
+ * The others require a restart transmit command.
+ */
+ if (bdp->cbd_sc &
+ (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
+ must_restart = 1;
+ cep->stats.tx_errors++;
+ }
+
+ cep->stats.tx_packets++;
+
+ /* Deferred means some collisions occurred during transmit,
+ * but we eventually sent the packet OK.
+ */
+ if (bdp->cbd_sc & BD_ENET_TX_DEF)
+ cep->stats.collisions++;
+
+ /* Free the sk buffer associated with this last transmit.
+ */
+ dev_kfree_skb_irq(cep->tx_skbuff[cep->skb_dirty]);
+ cep->skb_dirty = (cep->skb_dirty + 1) & TX_RING_MOD_MASK;
+
+ /* Update pointer to next buffer descriptor to be transmitted.
+ */
+ if (bdp->cbd_sc & BD_ENET_TX_WRAP)
+ bdp = cep->tx_bd_base;
+ else
+ bdp++;
+
+ /* I don't know if we can be held off from processing these
+ * interrupts for more than one frame time. I really hope
+ * not. In such a case, we would now want to check the
+ * currently available BD (cur_tx) and determine if any
+ * buffers between the dirty_tx and cur_tx have also been
+ * sent. We would want to process anything in between that
+ * does not have BD_ENET_TX_READY set.
+ */
+
+ /* Since we have freed up a buffer, the ring is no longer
+ * full.
+ */
+ if (cep->tx_full) {
+ cep->tx_full = 0;
+ if (netif_queue_stopped(dev)) {
+ netif_wake_queue(dev);
+ }
+ }
+
+ cep->dirty_tx = (cbd_t *)bdp;
+ }
+
+ if (must_restart) {
+ volatile cpm8260_t *cp;
+
+ /* Some transmit errors cause the transmitter to shut
+ * down. We now issue a restart transmit. Since the
+ * errors close the BD and update the pointers, the restart
+ * _should_ pick up without having to reset any of our
+ * pointers either.
+ */
+
+ cp = cpmp;
+ cp->cp_cpcr =
+ mk_cr_cmd(cep->fip->fc_cpmpage, cep->fip->fc_cpmblock,
+ 0x0c, CPM_CR_RESTART_TX) | CPM_CR_FLG;
+ while (cp->cp_cpcr & CPM_CR_FLG);
+ }
+ spin_unlock(&cep->lock);
+ }
+
+ /* Check for receive busy, i.e. packets coming but no place to
+ * put them.
+ */
+ if (int_events & FCC_ENET_BSY) {
+ cep->stats.rx_dropped++;
+ }
+ return;
+}
+
+/* During a receive, the cur_rx points to the current incoming buffer.
+ * When we update through the ring, if the next incoming buffer has
+ * not been given to the system, we just set the empty indicator,
+ * effectively tossing the packet.
+ */
+static int
+fcc_enet_rx(struct net_device *dev)
+{
+ struct fcc_enet_private *cep;
+ volatile cbd_t *bdp;
+ struct sk_buff *skb;
+ ushort pkt_len;
+
+ cep = (struct fcc_enet_private *)dev->priv;
+
+ /* First, grab all of the stats for the incoming packet.
+ * These get messed up if we get called due to a busy condition.
+ */
+ bdp = cep->cur_rx;
+
+for (;;) {
+ if (bdp->cbd_sc & BD_ENET_RX_EMPTY)
+ break;
+
+#ifndef final_version
+ /* Since we have allocated space to hold a complete frame, both
+ * the first and last indicators should be set.
+ */
+ if ((bdp->cbd_sc & (BD_ENET_RX_FIRST | BD_ENET_RX_LAST)) !=
+ (BD_ENET_RX_FIRST | BD_ENET_RX_LAST))
+ printk("CPM ENET: rcv is not first+last\n");
+#endif
+
+ /* Frame too long or too short.
+ */
+ if (bdp->cbd_sc & (BD_ENET_RX_LG | BD_ENET_RX_SH))
+ cep->stats.rx_length_errors++;
+ if (bdp->cbd_sc & BD_ENET_RX_NO) /* Frame alignment */
+ cep->stats.rx_frame_errors++;
+ if (bdp->cbd_sc & BD_ENET_RX_CR) /* CRC Error */
+ cep->stats.rx_crc_errors++;
+ if (bdp->cbd_sc & BD_ENET_RX_OV) /* FIFO overrun */
+ cep->stats.rx_crc_errors++;
+
+ /* Report late collisions as a frame error.
+ * On this error, the BD is closed, but we don't know what we
+ * have in the buffer. So, just drop this frame on the floor.
+ */
+ if (bdp->cbd_sc & BD_ENET_RX_CL) {
+ cep->stats.rx_frame_errors++;
+ }
+ else {
+
+ /* Process the incoming frame.
+ */
+ cep->stats.rx_packets++;
+ pkt_len = bdp->cbd_datlen;
+ cep->stats.rx_bytes += pkt_len;
+
+ /* This does 16 byte alignment, much more than we need.
+ * The packet length includes FCS, but we don't want to
+ * include that when passing upstream as it messes up
+ * bridging applications.
+ */
+ skb = dev_alloc_skb(pkt_len-4);
+
+ if (skb == NULL) {
+ printk("%s: Memory squeeze, dropping packet.\n", dev->name);
+ cep->stats.rx_dropped++;
+ }
+ else {
+ skb->dev = dev;
+ skb_put(skb,pkt_len-4); /* Make room */
+ eth_copy_and_sum(skb,
+ (unsigned char *)__va(bdp->cbd_bufaddr),
+ pkt_len-4, 0);
+ skb->protocol=eth_type_trans(skb,dev);
+ netif_rx(skb);
+ }
+ }
+
+ /* Clear the status flags for this buffer.
+ */
+ bdp->cbd_sc &= ~BD_ENET_RX_STATS;
+
+ /* Mark the buffer empty.
+ */
+ bdp->cbd_sc |= BD_ENET_RX_EMPTY;
+
+ /* Update BD pointer to next entry.
+ */
+ if (bdp->cbd_sc & BD_ENET_RX_WRAP)
+ bdp = cep->rx_bd_base;
+ else
+ bdp++;
+
+ }
+ cep->cur_rx = (cbd_t *)bdp;
+
+ return 0;
+}
+
+static int
+fcc_enet_close(struct net_device *dev)
+{
+ /* Don't know what to do yet.
+ */
+ netif_stop_queue(dev);
+
+ return 0;
+}
+
+static struct net_device_stats *fcc_enet_get_stats(struct net_device *dev)
+{
+ struct fcc_enet_private *cep = (struct fcc_enet_private *)dev->priv;
+
+ return &cep->stats;
+}
+
+/* The MII is simulated from the 8xx FEC implementation. The FCC
+ * is not responsible for the MII control/status interface.
+ */
+static void
+fcc_enet_mii(struct net_device *dev)
+{
+ struct fcc_enet_private *fep;
+ mii_list_t *mip;
+ uint mii_reg;
+
+ fep = (struct fcc_enet_private *)dev->priv;
+#if 0
+ ep = &(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec);
+ mii_reg = ep->fec_mii_data;
+#endif
+
+ if ((mip = mii_head) == NULL) {
+ printk("MII and no head!\n");
+ return;
+ }
+
+ if (mip->mii_func != NULL)
+ (*(mip->mii_func))(mii_reg, dev);
+
+ mii_head = mip->mii_next;
+ mip->mii_next = mii_free;
+ mii_free = mip;
+
+#if 0
+ if ((mip = mii_head) != NULL)
+ ep->fec_mii_data = mip->mii_regval;
+#endif
+}
+
+static int
+mii_queue(int regval, void (*func)(uint, struct net_device *))
+{
+ unsigned long flags;
+ mii_list_t *mip;
+ int retval;
+
+ retval = 0;
+
+ save_flags(flags);
+ cli();
+
+ if ((mip = mii_free) != NULL) {
+ mii_free = mip->mii_next;
+ mip->mii_regval = regval;
+ mip->mii_func = func;
+ mip->mii_next = NULL;
+ if (mii_head) {
+ mii_tail->mii_next = mip;
+ mii_tail = mip;
+ }
+ else {
+ mii_head = mii_tail = mip;
+#if 0
+ (&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec))->fec_mii_data = regval;
+#endif
+ }
+ }
+ else {
+ retval = 1;
+ }
+
+ restore_flags(flags);
+
+ return(retval);
+}
+
+static volatile uint full_duplex;
+
+static void
+mii_status(uint mii_reg, struct net_device *dev)
+{
+ volatile uint prev_duplex;
+
+ if (((mii_reg >> 18) & 0x1f) == 1) {
+ /* status register.
+ */
+ printk("fec: ");
+ if (mii_reg & 0x0004)
+ printk("link up");
+ else
+ printk("link down");
+
+ if (mii_reg & 0x0010)
+ printk(",remote fault");
+ if (mii_reg & 0x0020)
+ printk(",auto complete");
+ printk("\n");
+ }
+ if (((mii_reg >> 18) & 0x1f) == 0x14) {
+ /* Extended chip status register.
+ */
+ prev_duplex = full_duplex;
+ printk("fec: ");
+ if (mii_reg & 0x0800)
+ printk("100 Mbps");
+ else
+ printk("10 Mbps");
+
+ if (mii_reg & 0x1000) {
+ printk(", Full-Duplex\n");
+ full_duplex = 1;
+ }
+ else {
+ printk(", Half-Duplex\n");
+ full_duplex = 0;
+ }
+#if 0
+ if (prev_duplex != full_duplex)
+ restart_fec(dev);
+#endif
+ }
+ if (((mii_reg >> 18) & 0x1f) == 31) {
+ /* QS6612 PHY Control/Status.
+ * OK, now we have it all, so figure out what is going on.
+ */
+ prev_duplex = full_duplex;
+ printk("fec: ");
+
+ mii_reg = (mii_reg >> 2) & 7;
+
+ if (mii_reg & 1)
+ printk("10 Mbps");
+ else
+ printk("100 Mbps");
+
+ if (mii_reg > 4) {
+ printk(", Full-Duplex\n");
+ full_duplex = 1;
+ }
+ else {
+ printk(", Half-Duplex\n");
+ full_duplex = 0;
+ }
+
+#if 0
+ if (prev_duplex != full_duplex)
+ restart_fec(dev);
+#endif
+ }
+}
+
+static uint phyno;
+
+static void
+mii_discover_phy3(uint mii_reg, struct net_device *dev)
+{
+ phytype <<= 16;
+ phytype |= (mii_reg & 0xffff);
+ printk("fec: Phy @ 0x%x, type 0x%08x\n", phyno, phytype);
+ mii_startup_cmds();
+}
+
+static void
+mii_discover_phy(uint mii_reg, struct net_device *dev)
+{
+ if (phyno < 32) {
+ if ((phytype = (mii_reg & 0xffff)) != 0xffff) {
+ phyaddr = phyno;
+ mii_queue(mk_mii_read(3), mii_discover_phy3);
+ }
+ else {
+ phyno++;
+ mii_queue(mk_mii_phyaddr(phyno), mii_discover_phy);
+ }
+ }
+ else {
+ printk("FEC: No PHY device found.\n");
+ }
+}
+
+static void
+mii_discover_phy_poll(fcc_info_t *fip)
+{
+ uint rv;
+ int i;
+
+ for (i=0; i<32; i++) {
+ rv = mii_send_receive(fip, mk_mii_phyaddr(i));
+ if ((phytype = (rv & 0xffff)) != 0xffff) {
+ phyaddr = i;
+ rv = mii_send_receive(fip, mk_mii_read(3));
+ phytype <<= 16;
+ phytype |= (rv & 0xffff);
+ printk("fec: Phy @ 0x%x, type 0x%08x\n", phyaddr, phytype);
+ }
+ }
+}
+
+static void
+mii_startup_cmds(void)
+{
+
+#if 1
+ /* Level One PHY.
+ */
+
+ /* Read status registers to clear any pending interrupt.
+ */
+ mii_queue(mk_mii_read(1), mii_status);
+ mii_queue(mk_mii_read(18), mii_status);
+
+ /* Read extended chip status register.
+ */
+ mii_queue(mk_mii_read(0x14), mii_status);
+
+ /* Set default operation of 100-TX....for some reason
+ * some of these bits are set on power up, which is wrong.
+ */
+ mii_queue(mk_mii_write(0x13, 0), NULL);
+
+ /* Enable Link status change interrupts.
+ */
+ mii_queue(mk_mii_write(0x11, 0x0002), NULL);
+
+ /* Don't advertize Full duplex.
+ mii_queue(mk_mii_write(0x04, 0x0021), NULL);
+ */
+#endif
+
+}
+
+/* This supports the mii_link interrupt below.
+ * We should get called three times. Once for register 1, once for
+ * register 18, and once for register 20.
+ */
+static uint mii_saved_reg1;
+
+static void
+mii_relink(uint mii_reg, struct net_device *dev)
+{
+ volatile uint prev_duplex;
+ unsigned long flags;
+
+ if (((mii_reg >> 18) & 0x1f) == 1) {
+ /* Just save the status register and get out.
+ */
+ mii_saved_reg1 = mii_reg;
+ return;
+ }
+ if (((mii_reg >> 18) & 0x1f) == 18) {
+ /* Not much here, but has to be read to clear the
+ * interrupt condition.
+ */
+ if ((mii_reg & 0x8000) == 0)
+ printk("fec: re-link and no IRQ?\n");
+ if ((mii_reg & 0x4000) == 0)
+ printk("fec: no PHY power?\n");
+ }
+ if (((mii_reg >> 18) & 0x1f) == 20) {
+ /* Extended chip status register.
+ * OK, now we have it all, so figure out what is going on.
+ */
+ prev_duplex = full_duplex;
+ printk("fec: ");
+ if (mii_saved_reg1 & 0x0004)
+ printk("link up");
+ else
+ printk("link down");
+
+ if (mii_saved_reg1 & 0x0010)
+ printk(", remote fault");
+ if (mii_saved_reg1 & 0x0020)
+ printk(", auto complete");
+
+ if (mii_reg & 0x0800)
+ printk(", 100 Mbps");
+ else
+ printk(", 10 Mbps");
+
+ if (mii_reg & 0x1000) {
+ printk(", Full-Duplex\n");
+ full_duplex = 1;
+ }
+ else {
+ printk(", Half-Duplex\n");
+ full_duplex = 0;
+ }
+ if (prev_duplex != full_duplex) {
+ save_flags(flags);
+ cli();
+#if 0
+ restart_fec(dev);
+#endif
+ restore_flags(flags);
+ }
+ }
+ if (((mii_reg >> 18) & 0x1f) == 31) {
+ /* QS6612 PHY Control/Status.
+ * OK, now we have it all, so figure out what is going on.
+ */
+ prev_duplex = full_duplex;
+ printk("fec: ");
+ if (mii_saved_reg1 & 0x0004)
+ printk("link up");
+ else
+ printk("link down");
+
+ if (mii_saved_reg1 & 0x0010)
+ printk(", remote fault");
+ if (mii_saved_reg1 & 0x0020)
+ printk(", auto complete");
+
+ mii_reg = (mii_reg >> 2) & 7;
+
+ if (mii_reg & 1)
+ printk(", 10 Mbps");
+ else
+ printk(", 100 Mbps");
+
+ if (mii_reg > 4) {
+ printk(", Full-Duplex\n");
+ full_duplex = 1;
+ }
+ else {
+ printk(", Half-Duplex\n");
+ full_duplex = 0;
+ }
+
+#if 0
+ if (prev_duplex != full_duplex) {
+ save_flags(flags);
+ cli();
+ restart_fec(dev);
+ restore_flags(flags);
+ }
+#endif
+ }
+}
+
+/* Set or clear the multicast filter for this adaptor.
+ * Skeleton taken from sunlance driver.
+ * The CPM Ethernet implementation allows Multicast as well as individual
+ * MAC address filtering. Some of the drivers check to make sure it is
+ * a group multicast address, and discard those that are not. I guess I
+ * will do the same for now, but just remove the test if you want
+ * individual filtering as well (do the upper net layers want or support
+ * this kind of feature?).
+ */
+static void
+set_multicast_list(struct net_device *dev)
+{
+ struct fcc_enet_private *cep;
+ struct dev_mc_list *dmi;
+ u_char *mcptr, *tdptr;
+ volatile fcc_enet_t *ep;
+ int i, j;
+
+ cep = (struct fcc_enet_private *)dev->priv;
+
+return;
+ /* Get pointer to FCC area in parameter RAM.
+ */
+ ep = (fcc_enet_t *)dev->base_addr;
+
+ if (dev->flags&IFF_PROMISC) {
+
+ /* Log any net taps. */
+ printk("%s: Promiscuous mode enabled.\n", dev->name);
+ cep->fccp->fcc_fpsmr |= FCC_PSMR_PRO;
+ } else {
+
+ cep->fccp->fcc_fpsmr &= ~FCC_PSMR_PRO;
+
+ if (dev->flags & IFF_ALLMULTI) {
+ /* Catch all multicast addresses, so set the
+ * filter to all 1's.
+ */
+ ep->fen_gaddrh = 0xffffffff;
+ ep->fen_gaddrl = 0xffffffff;
+ }
+ else {
+ /* Clear filter and add the addresses in the list.
+ */
+ ep->fen_gaddrh = 0;
+ ep->fen_gaddrl = 0;
+
+ dmi = dev->mc_list;
+
+ for (i=0; i<dev->mc_count; i++) {
+
+ /* Only support group multicast for now.
+ */
+ if (!(dmi->dmi_addr[0] & 1))
+ continue;
+
+ /* The address in dmi_addr is LSB first,
+ * and taddr is MSB first. We have to
+ * copy bytes MSB first from dmi_addr.
+ */
+ mcptr = (u_char *)dmi->dmi_addr + 5;
+ tdptr = (u_char *)&ep->fen_taddrh;
+ for (j=0; j<6; j++)
+ *tdptr++ = *mcptr--;
+
+ /* Ask CPM to run CRC and set bit in
+ * filter mask.
+ */
+ cpmp->cp_cpcr = mk_cr_cmd(cep->fip->fc_cpmpage,
+ cep->fip->fc_cpmblock, 0x0c,
+ CPM_CR_SET_GADDR) | CPM_CR_FLG;
+ udelay(10);
+ while (cpmp->cp_cpcr & CPM_CR_FLG);
+ }
+ }
+ }
+}
+
+/* Initialize the CPM Ethernet on FCC.
+ */
+int __init fec_enet_init(void)
+{
+ struct net_device *dev;
+ struct fcc_enet_private *cep;
+ fcc_info_t *fip;
+ int i, np;
+ volatile immap_t *immap;
+ volatile iop8260_t *io;
+
+ immap = (immap_t *)IMAP_ADDR; /* and to internal registers */
+ io = &immap->im_ioport;
+
+ np = sizeof(fcc_ports) / sizeof(fcc_info_t);
+ fip = fcc_ports;
+
+ while (np-- > 0) {
+
+ /* Allocate some private information.
+ */
+ cep = (struct fcc_enet_private *)
+ kmalloc(sizeof(*cep), GFP_KERNEL);
+ __clear_user(cep,sizeof(*cep));
+ spin_lock_init(&cep->lock);
+ cep->fip = fip;
+
+ /* Create an Ethernet device instance.
+ */
+ dev = init_etherdev(0, 0);
+ dev->priv = cep;
+
+ init_fcc_shutdown(fip, cep, immap);
+ init_fcc_ioports(fip, io, immap);
+ init_fcc_param(fip, dev, immap);
+
+ dev->base_addr = (unsigned long)(cep->ep);
+
+ /* The CPM Ethernet specific entries in the device
+ * structure.
+ */
+ dev->open = fcc_enet_open;
+ dev->hard_start_xmit = fcc_enet_start_xmit;
+ dev->tx_timeout = fcc_enet_timeout;
+ dev->watchdog_timeo = TX_TIMEOUT;
+ dev->stop = fcc_enet_close;
+ dev->get_stats = fcc_enet_get_stats;
+ dev->set_multicast_list = set_multicast_list;
+
+ init_fcc_startup(fip, dev);
+
+ printk("%s: FCC ENET Version 0.2, ", dev->name);
+ for (i=0; i<5; i++)
+ printk("%02x:", dev->dev_addr[i]);
+ printk("%02x\n", dev->dev_addr[5]);
+
+ /* This is just a hack for now that works only on the EST
+ * board, or anything else that has MDIO/CK configured.
+ * It is mainly to test the MII software clocking.
+ */
+ mii_discover_phy_poll(fip);
+
+ fip++;
+ }
+
+ return 0;
+}
+
+/* Make sure the device is shut down during initialization.
+*/
+static void __init
+init_fcc_shutdown(fcc_info_t *fip, struct fcc_enet_private *cep,
+ volatile immap_t *immap)
+{
+ volatile fcc_enet_t *ep;
+ volatile fcc_t *fccp;
+
+ /* Get pointer to FCC area in parameter RAM.
+ */
+ ep = (fcc_enet_t *)(&immap->im_dprambase[fip->fc_proff]);
+
+ /* And another to the FCC register area.
+ */
+ fccp = (volatile fcc_t *)(&immap->im_fcc[fip->fc_fccnum]);
+ cep->fccp = fccp; /* Keep the pointers handy */
+ cep->ep = ep;
+
+ /* Disable receive and transmit in case someone left it running.
+ */
+ fccp->fcc_gfmr &= ~(FCC_GFMR_ENR | FCC_GFMR_ENT);
+}
+
+/* Initialize the I/O pins for the FCC Ethernet.
+*/
+static void __init
+init_fcc_ioports(fcc_info_t *fip, volatile iop8260_t *io,
+ volatile immap_t *immap)
+{
+
+ /* FCC1 pins are on port A/C. FCC2/3 are port B/C.
+ */
+ if (fip->fc_proff == PROFF_FCC1) {
+ /* Configure port A and C pins for FCC1 Ethernet.
+ */
+ io->iop_pdira &= ~PA1_DIRA0;
+ io->iop_pdira |= PA1_DIRA1;
+ io->iop_psora &= ~PA1_PSORA0;
+ io->iop_psora |= PA1_PSORA1;
+ io->iop_ppara |= (PA1_DIRA0 | PA1_DIRA1);
+ }
+ if (fip->fc_proff == PROFF_FCC2) {
+ /* Configure port B and C pins for FCC Ethernet.
+ */
+ io->iop_pdirb &= ~PB2_DIRB0;
+ io->iop_pdirb |= PB2_DIRB1;
+ io->iop_psorb &= ~PB2_PSORB0;
+ io->iop_psorb |= PB2_PSORB1;
+ io->iop_pparb |= (PB2_DIRB0 | PB2_DIRB1);
+ }
+ if (fip->fc_proff == PROFF_FCC3) {
+ /* Configure port B and C pins for FCC Ethernet.
+ */
+ io->iop_pdirb &= ~PB3_DIRB0;
+ io->iop_pdirb |= PB3_DIRB1;
+ io->iop_psorb &= ~PB3_PSORB0;
+ io->iop_psorb |= PB3_PSORB1;
+ io->iop_pparb |= (PB3_DIRB0 | PB3_DIRB1);
+ }
+
+ /* Port C has clocks......
+ */
+ io->iop_psorc &= ~(fip->fc_trxclocks);
+ io->iop_pdirc &= ~(fip->fc_trxclocks);
+ io->iop_pparc |= fip->fc_trxclocks;
+
+ /* ....and the MII serial clock/data.
+ */
+ io->iop_pdatc |= (fip->fc_mdio | fip->fc_mdck);
+ io->iop_podrc |= fip->fc_mdio;
+ io->iop_pdirc |= (fip->fc_mdio | fip->fc_mdck);
+ io->iop_pparc &= ~(fip->fc_mdio | fip->fc_mdck);
+
+ /* Configure Serial Interface clock routing.
+ * First, clear all FCC bits to zero,
+ * then set the ones we want.
+ */
+ immap->im_cpmux.cmx_fcr &= ~(fip->fc_clockmask);
+ immap->im_cpmux.cmx_fcr |= fip->fc_clockroute;
+}
+
+static void __init
+init_fcc_param(fcc_info_t *fip, struct net_device *dev,
+ volatile immap_t *immap)
+{
+ unsigned char *eap;
+ unsigned long mem_addr;
+ bd_t *bd;
+ int i, j;
+ struct fcc_enet_private *cep;
+ volatile fcc_enet_t *ep;
+ volatile cbd_t *bdp;
+ volatile cpm8260_t *cp;
+
+ cep = (struct fcc_enet_private *)(dev->priv);
+ ep = cep->ep;
+ cp = cpmp;
+
+ bd = (bd_t *)__res;
+
+ /* Zero the whole thing.....I must have missed some individually.
+ * It works when I do this.
+ */
+ memset((char *)ep, 0, sizeof(fcc_enet_t));
+
+ /* Allocate space for the buffer descriptors in the DP ram.
+ * These are relative offsets in the DP ram address space.
+ * Initialize base addresses for the buffer descriptors.
+ */
+#if 0
+ /* I really want to do this, but for some reason it doesn't
+ * work with the data cache enabled, so I allocate from the
+ * main memory instead.
+ */
+ i = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_RING_SIZE, 8);
+ ep->fen_genfcc.fcc_rbase = (uint)&immap->im_dprambase[i];
+ cep->rx_bd_base = (cbd_t *)&immap->im_dprambase[i];
+
+ i = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_RING_SIZE, 8);
+ ep->fen_genfcc.fcc_tbase = (uint)&immap->im_dprambase[i];
+ cep->tx_bd_base = (cbd_t *)&immap->im_dprambase[i];
+#else
+ cep->rx_bd_base = (cbd_t *)m8260_cpm_hostalloc(sizeof(cbd_t) * RX_RING_SIZE, 8);
+ ep->fen_genfcc.fcc_rbase = __pa(cep->rx_bd_base);
+ cep->tx_bd_base = (cbd_t *)m8260_cpm_hostalloc(sizeof(cbd_t) * TX_RING_SIZE, 8);
+ ep->fen_genfcc.fcc_tbase = __pa(cep->tx_bd_base);
+#endif
+
+ cep->dirty_tx = cep->cur_tx = cep->tx_bd_base;
+ cep->cur_rx = cep->rx_bd_base;
+
+ ep->fen_genfcc.fcc_rstate = (CPMFCR_GBL | CPMFCR_EB) << 24;
+ ep->fen_genfcc.fcc_tstate = (CPMFCR_GBL | CPMFCR_EB) << 24;
+
+ /* Set maximum bytes per receive buffer.
+ * It must be a multiple of 32.
+ */
+ ep->fen_genfcc.fcc_mrblr = PKT_MAXBLR_SIZE;
+
+ /* Allocate space in the reserved FCC area of DPRAM for the
+ * internal buffers. No one uses this space (yet), so we
+ * can do this. Later, we will add resource management for
+ * this area.
+ */
+ mem_addr = CPM_FCC_SPECIAL_BASE + (fip->fc_fccnum * 128);
+ ep->fen_genfcc.fcc_riptr = mem_addr;
+ ep->fen_genfcc.fcc_tiptr = mem_addr+32;
+ ep->fen_padptr = mem_addr+64;
+ memset((char *)(&(immap->im_dprambase[(mem_addr+64)])), 0x88, 32);
+
+ ep->fen_genfcc.fcc_rbptr = 0;
+ ep->fen_genfcc.fcc_tbptr = 0;
+ ep->fen_genfcc.fcc_rcrc = 0;
+ ep->fen_genfcc.fcc_tcrc = 0;
+ ep->fen_genfcc.fcc_res1 = 0;
+ ep->fen_genfcc.fcc_res2 = 0;
+
+ ep->fen_camptr = 0; /* CAM isn't used in this driver */
+
+ /* Set CRC preset and mask.
+ */
+ ep->fen_cmask = 0xdebb20e3;
+ ep->fen_cpres = 0xffffffff;
+
+ ep->fen_crcec = 0; /* CRC Error counter */
+ ep->fen_alec = 0; /* alignment error counter */
+ ep->fen_disfc = 0; /* discard frame counter */
+ ep->fen_retlim = 15; /* Retry limit threshold */
+ ep->fen_pper = 0; /* Normal persistence */
+
+ /* Clear hash filter tables.
+ */
+ ep->fen_gaddrh = 0;
+ ep->fen_gaddrl = 0;
+ ep->fen_iaddrh = 0;
+ ep->fen_iaddrl = 0;
+
+ /* Clear the Out-of-sequence TxBD.
+ */
+ ep->fen_tfcstat = 0;
+ ep->fen_tfclen = 0;
+ ep->fen_tfcptr = 0;
+
+ ep->fen_mflr = PKT_MAXBUF_SIZE; /* maximum frame length register */
+ ep->fen_minflr = PKT_MINBUF_SIZE; /* minimum frame length register */
+
+ /* Set Ethernet station address.
+ *
+ * This is supplied in the board information structure, so we
+ * copy that into the controller.
+ * So, far we have only been given one Ethernet address. We make
+ * it unique by setting a few bits in the upper byte of the
+ * non-static part of the address.
+ */
+ eap = (unsigned char *)&(ep->fen_paddrh);
+ for (i=5; i>=0; i--) {
+ if (i == 3) {
+ dev->dev_addr[i] = bd->bi_enetaddr[i];
+ dev->dev_addr[i] |= (1 << (7 - fip->fc_fccnum));
+ *eap++ = dev->dev_addr[i];
+ }
+ else {
+ *eap++ = dev->dev_addr[i] = bd->bi_enetaddr[i];
+ }
+ }
+
+ ep->fen_taddrh = 0;
+ ep->fen_taddrm = 0;
+ ep->fen_taddrl = 0;
+
+ ep->fen_maxd1 = PKT_MAXDMA_SIZE; /* maximum DMA1 length */
+ ep->fen_maxd2 = PKT_MAXDMA_SIZE; /* maximum DMA2 length */
+
+ /* Clear stat counters, in case we ever enable RMON.
+ */
+ ep->fen_octc = 0;
+ ep->fen_colc = 0;
+ ep->fen_broc = 0;
+ ep->fen_mulc = 0;
+ ep->fen_uspc = 0;
+ ep->fen_frgc = 0;
+ ep->fen_ospc = 0;
+ ep->fen_jbrc = 0;
+ ep->fen_p64c = 0;
+ ep->fen_p65c = 0;
+ ep->fen_p128c = 0;
+ ep->fen_p256c = 0;
+ ep->fen_p512c = 0;
+ ep->fen_p1024c = 0;
+
+ ep->fen_rfthr = 0; /* Suggested by manual */
+ ep->fen_rfcnt = 0;
+ ep->fen_cftype = 0;
+
+ /* Now allocate the host memory pages and initialize the
+ * buffer descriptors.
+ */
+ bdp = cep->tx_bd_base;
+ for (i=0; i<TX_RING_SIZE; i++) {
+
+ /* Initialize the BD for every fragment in the page.
+ */
+ bdp->cbd_sc = 0;
+ bdp->cbd_datlen = 0;
+ bdp->cbd_bufaddr = 0;
+ bdp++;
+ }
+
+ /* Set the last buffer to wrap.
+ */
+ bdp--;
+ bdp->cbd_sc |= BD_SC_WRAP;
+
+ bdp = cep->rx_bd_base;
+ for (i=0; i<FCC_ENET_RX_PAGES; i++) {
+
+ /* Allocate a page.
+ */
+ mem_addr = __get_free_page(GFP_KERNEL);
+
+ /* Initialize the BD for every fragment in the page.
+ */
+ for (j=0; j<FCC_ENET_RX_FRPPG; j++) {
+ bdp->cbd_sc = BD_ENET_RX_EMPTY | BD_ENET_RX_INTR;
+ bdp->cbd_datlen = 0;
+ bdp->cbd_bufaddr = __pa(mem_addr);
+ mem_addr += FCC_ENET_RX_FRSIZE;
+ bdp++;
+ }
+ }
+
+ /* Set the last buffer to wrap.
+ */
+ bdp--;
+ bdp->cbd_sc |= BD_SC_WRAP;
+
+ /* Let's re-initialize the channel now. We have to do it later
+ * than the manual describes because we have just now finished
+ * the BD initialization.
+ */
+ cp->cp_cpcr = mk_cr_cmd(fip->fc_cpmpage, fip->fc_cpmblock, 0x0c,
+ CPM_CR_INIT_TRX) | CPM_CR_FLG;
+ while (cp->cp_cpcr & CPM_CR_FLG);
+
+ cep->skb_cur = cep->skb_dirty = 0;
+}
+
+/* Let 'er rip.
+*/
+static void __init
+init_fcc_startup(fcc_info_t *fip, struct net_device *dev)
+{
+ volatile fcc_t *fccp;
+ struct fcc_enet_private *cep;
+
+ cep = (struct fcc_enet_private *)(dev->priv);
+ fccp = cep->fccp;
+
+ fccp->fcc_fcce = 0xffff; /* Clear any pending events */
+
+ /* Enable interrupts for transmit error, complete frame
+ * received, and any transmit buffer we have also set the
+ * interrupt flag.
+ */
+ fccp->fcc_fccm = (FCC_ENET_TXE | FCC_ENET_RXF | FCC_ENET_TXB);
+
+ /* Install our interrupt handler.
+ */
+ if (request_8xxirq(fip->fc_interrupt, fcc_enet_interrupt, 0,
+ "fenet", dev) < 0)
+ printk("Can't get FCC IRQ %d\n", fip->fc_interrupt);
+
+ /* Set GFMR to enable Ethernet operating mode.
+ */
+ fccp->fcc_gfmr = (FCC_GFMR_TCI | FCC_GFMR_MODE_ENET);
+
+ /* Set sync/delimiters.
+ */
+ fccp->fcc_fdsr = 0xd555;
+
+ /* Set protocol specific processing mode for Ethernet.
+ * This has to be adjusted for Full Duplex operation after we can
+ * determine how to detect that.
+ */
+ fccp->fcc_fpsmr = FCC_PSMR_ENCRC;
+
+ /* And last, enable the transmit and receive processing.
+ */
+ fccp->fcc_gfmr |= (FCC_GFMR_ENR | FCC_GFMR_ENT);
+}
+
+/* MII command/status interface.
+ * I'm not going to describe all of the details. You can find the
+ * protocol definition in many other places, including the data sheet
+ * of most PHY parts.
+ * I wonder what "they" were thinking (maybe weren't) when they leave
+ * the I2C in the CPM but I have to toggle these bits......
+ */
+static uint
+mii_send_receive(fcc_info_t *fip, uint cmd)
+{
+ unsigned long flags;
+ uint retval;
+ int read_op, i;
+ volatile immap_t *immap;
+ volatile iop8260_t *io;
+
+ immap = (immap_t *)IMAP_ADDR;
+ io = &immap->im_ioport;
+
+ /* When we get here, both clock and data are high, outputs.
+ * Output is open drain.
+ * Data transitions on high->low clock, is valid on low->high clock.
+ * Spec says edge transitions no closer than 160 nSec, minimum clock
+ * cycle 400 nSec. I could only manage about 500 nSec edges with
+ * an XOR loop, so I won't worry about delays yet.
+ * I disable interrupts during bit flipping to ensure atomic
+ * updates of the registers. I do lots of interrupt disable/enable
+ * to ensure we don't hang out too long with interrupts disabled.
+ */
+
+ /* First, crank out 32 1-bits as preamble.
+ * This is 64 transitions to clock the bits, with clock/data
+ * left high.
+ */
+ save_flags(flags);
+ cli();
+ for (i=0; i<64; i++) {
+ io->iop_pdatc ^= fip->fc_mdck;
+ udelay(0);
+ }
+ restore_flags(flags);
+
+ read_op = ((cmd & 0xf0000000) == 0x60000000);
+
+ /* We return the command word on a write op, or the command portion
+ * plus the new data on a read op. This is what the 8xx FEC does,
+ * and it allows the functions to simply look at the returned value
+ * and know the PHY/register as well.
+ */
+ if (read_op)
+ retval = cmd;
+ else
+ retval = (cmd >> 16);
+
+ /* Clock out the first 16 MS bits of the command.
+ */
+ save_flags(flags);
+ cli();
+ for (i=0; i<16; i++) {
+ io->iop_pdatc &= ~(fip->fc_mdck);
+ if (cmd & 0x80000000)
+ io->iop_pdatc |= fip->fc_mdio;
+ else
+ io->iop_pdatc &= ~(fip->fc_mdio);
+ cmd <<= 1;
+ io->iop_pdatc |= fip->fc_mdck;
+ udelay(0);
+ }
+
+ /* Do the turn-around. If read op, we make the IO and input.
+ * If write op, do the 1/0 thing.
+ */
+ io->iop_pdatc &= ~(fip->fc_mdck);
+ if (read_op)
+ io->iop_pdirc &= ~(fip->fc_mdio);
+ else
+ io->iop_pdatc |= fip->fc_mdio;
+ io->iop_pdatc |= fip->fc_mdck;
+
+ /* I do this mainly to get just a little delay.
+ */
+ restore_flags(flags);
+ save_flags(flags);
+ cli();
+ io->iop_pdatc &= ~(fip->fc_mdck);
+ io->iop_pdirc &= ~(fip->fc_mdio);
+ io->iop_pdatc |= fip->fc_mdck;
+
+ restore_flags(flags);
+ save_flags(flags);
+ cli();
+
+ /* For read, clock in 16 bits. For write, clock out
+ * rest of command.
+ */
+ if (read_op) {
+ io->iop_pdatc &= ~(fip->fc_mdck);
+ udelay(0);
+ for (i=0; i<16; i++) {
+ io->iop_pdatc |= fip->fc_mdck;
+ udelay(0);
+ retval <<= 1;
+ if (io->iop_pdatc & fip->fc_mdio)
+ retval |= 1;
+ io->iop_pdatc &= ~(fip->fc_mdck);
+ udelay(0);
+ }
+ }
+ else {
+ for (i=0; i<16; i++) {
+ io->iop_pdatc &= ~(fip->fc_mdck);
+ if (cmd & 0x80000000)
+ io->iop_pdatc |= fip->fc_mdio;
+ else
+ io->iop_pdatc &= ~(fip->fc_mdio);
+ cmd <<= 1;
+ io->iop_pdatc |= fip->fc_mdck;
+ udelay(0);
+ }
+ io->iop_pdatc &= ~(fip->fc_mdck);
+ }
+ restore_flags(flags);
+
+ /* Some diagrams show two 1 bits for "idle". I don't know if
+ * this is really necessary or if it was just to indicate nothing
+ * is going to happen for a while.
+ * Make the data pin an output, set the data high, and clock it.
+ */
+ save_flags(flags);
+ cli();
+ io->iop_pdatc |= fip->fc_mdio;
+ io->iop_pdirc |= fip->fc_mdio;
+ for (i=0; i<3; i++)
+ io->iop_pdatc ^= fip->fc_mdck;
+ restore_flags(flags);
+
+ /* We exit with the same conditions as entry.
+ */
+ return(retval);
+}
diff --git a/arch/ppc/8260_io/uart.c b/arch/ppc/8260_io/uart.c
index caa5ca8b0..97c4cb880 100644
--- a/arch/ppc/8260_io/uart.c
+++ b/arch/ppc/8260_io/uart.c
@@ -977,8 +977,7 @@ static int rs_8xx_write(struct tty_struct * tty, int from_user,
}
if (from_user) {
- if (c !=
- copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) {
+ if (copy_from_user(__va(bdp->cbd_bufaddr), buf, c)) {
if (!ret)
ret = -EFAULT;
break;
@@ -2396,10 +2395,10 @@ int __init rs_8xx_init(void)
io->iop_pdird &= ~0x00800000;
io->iop_psord &= ~0x00c00000;
#if USE_SMC2
- io->iop_ppara |= 0x01800000;
- io->iop_pdira |= 0x00800000;
- io->iop_pdira &= ~0x01000000;
- io->iop_psora &= ~0x01800000;
+ io->iop_ppara |= 0x00c00000;
+ io->iop_pdira |= 0x00400000;
+ io->iop_pdira &= ~0x00800000;
+ io->iop_psora &= ~0x00c00000;
#endif
/* Configure SCC2 and SCC3. Be careful about the fine print.
@@ -2473,11 +2472,11 @@ int __init rs_8xx_init(void)
* descriptors from dual port ram, and a character
* buffer area from host mem.
*/
- dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_NUM_FIFO);
+ dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * RX_NUM_FIFO, 8);
/* Allocate space for FIFOs in the host memory.
*/
- mem_addr = m8260_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE);
+ mem_addr = m8260_cpm_hostalloc(RX_NUM_FIFO * RX_BUF_SIZE, 1);
/* Set the physical address of the host memory
* buffers in the buffer descriptors, and the
@@ -2506,11 +2505,11 @@ int __init rs_8xx_init(void)
sup->scc_genscc.scc_rbase = dp_addr;
}
- dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_NUM_FIFO);
+ dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * TX_NUM_FIFO, 8);
/* Allocate space for FIFOs in the host memory.
*/
- mem_addr = m8260_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE);
+ mem_addr = m8260_cpm_hostalloc(TX_NUM_FIFO * TX_BUF_SIZE, 1);
/* Set the physical address of the host memory
* buffers in the buffer descriptors, and the
@@ -2716,11 +2715,11 @@ static int __init serial_console_setup(struct console *co, char *options)
/* Allocate space for two buffer descriptors in the DP ram.
*/
- dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * 2);
+ dp_addr = m8260_cpm_dpalloc(sizeof(cbd_t) * 2, 8);
/* Allocate space for two 2 byte FIFOs in the host memory.
*/
- mem_addr = m8260_cpm_hostalloc(4);
+ mem_addr = m8260_cpm_hostalloc(4, 1);
/* Set the physical address of the host memory buffers in
* the buffer descriptors.
diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c
index 730453bbb..b77cf32da 100644
--- a/arch/ppc/8xx_io/enet.c
+++ b/arch/ppc/8xx_io/enet.c
@@ -484,8 +484,11 @@ for (;;) {
cep->stats.rx_bytes += pkt_len;
/* This does 16 byte alignment, much more than we need.
- */
- skb = dev_alloc_skb(pkt_len);
+ * The packet length includes FCS, but we don't want to
+ * include that when passing upstream as it messes up
+ * bridging applications.
+ */
+ skb = dev_alloc_skb(pkt_len-4);
if (skb == NULL) {
printk("%s: Memory squeeze, dropping packet.\n", dev->name);
@@ -493,10 +496,10 @@ for (;;) {
}
else {
skb->dev = dev;
- skb_put(skb,pkt_len); /* Make room */
+ skb_put(skb,pkt_len-4); /* Make room */
eth_copy_and_sum(skb,
(unsigned char *)__va(bdp->cbd_bufaddr),
- pkt_len, 0);
+ pkt_len-4, 0);
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
}
diff --git a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c
index f69d0dfbd..45f10b635 100644
--- a/arch/ppc/8xx_io/fec.c
+++ b/arch/ppc/8xx_io/fec.c
@@ -669,18 +669,21 @@ while (!(bdp->cbd_sc & BD_ENET_RX_EMPTY)) {
#endif
/* This does 16 byte alignment, exactly what we need.
+ * The packet length includes FCS, but we don't want to
+ * include that when passing upstream as it messes up
+ * bridging applications.
*/
- skb = dev_alloc_skb(pkt_len);
+ skb = dev_alloc_skb(pkt_len-4);
if (skb == NULL) {
printk("%s: Memory squeeze, dropping packet.\n", dev->name);
fep->stats.rx_dropped++;
} else {
skb->dev = dev;
- skb_put(skb,pkt_len); /* Make room */
+ skb_put(skb,pkt_len-4); /* Make room */
eth_copy_and_sum(skb,
(unsigned char *)__va(bdp->cbd_bufaddr),
- pkt_len, 0);
+ pkt_len-4, 0);
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);
}
diff --git a/arch/ppc/amiga/time.c b/arch/ppc/amiga/time.c
index a78f8aa41..0073527a7 100644
--- a/arch/ppc/amiga/time.c
+++ b/arch/ppc/amiga/time.c
@@ -11,10 +11,6 @@
#include <linux/timex.h>
-static inline unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec);
-
unsigned long m68k_get_rtc_time(void)
{
unsigned int year, mon, day, hour, min, sec;
@@ -37,38 +33,6 @@ int m68k_set_rtc_time(unsigned long nowtime)
return -1;
}
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static inline unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
-
void apus_heartbeat (void)
{
#ifdef CONFIG_HEARTBEAT
diff --git a/arch/ppc/chrpboot/Makefile b/arch/ppc/chrpboot/Makefile
index 48750982e..f7ea3a3fa 100644
--- a/arch/ppc/chrpboot/Makefile
+++ b/arch/ppc/chrpboot/Makefile
@@ -67,11 +67,13 @@ initrd.o: ramdisk.image.gz piggyback
zImage: $(OBJS) no_initrd.o addnote
$(LD) $(LD_ARGS) -o $@ $(OBJS) no_initrd.o $(LIBS)
- ./addnote $@
+ cp $@ $@.rs6k
+ ./addnote $@.rs6k
zImage.initrd: $(OBJS) initrd.o addnote
$(LD) $(LD_ARGS) -o $@ $(OBJS) initrd.o $(LIBS)
- ./addnote $@
+ cp $@ $@.rs6k
+ ./addnote $@.rs6k
else
znetboot:
diff --git a/arch/ppc/chrpboot/addnote.c b/arch/ppc/chrpboot/addnote.c
index 5f0934f6e..b2374df7c 100644
--- a/arch/ppc/chrpboot/addnote.c
+++ b/arch/ppc/chrpboot/addnote.c
@@ -22,12 +22,23 @@ char arch[] = "PowerPC";
#define N_DESCR 6
unsigned int descr[N_DESCR] = {
+#if 1
+ /* values for IBM RS/6000 machines */
0xffffffff, /* real-mode = true */
0x00c00000, /* real-base, i.e. where we expect OF to be */
0xffffffff, /* real-size */
0xffffffff, /* virt-base */
0xffffffff, /* virt-size */
0x4000, /* load-base */
+#else
+ /* values for longtrail CHRP */
+ 0, /* real-mode = false */
+ 0xffffffff, /* real-base */
+ 0xffffffff, /* real-size */
+ 0xffffffff, /* virt-base */
+ 0xffffffff, /* virt-size */
+ 0x00600000, /* load-base */
+#endif
};
unsigned char buf[512];
@@ -63,7 +74,7 @@ unsigned char buf[512];
unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' };
-main(int ac, char **av)
+int main(int ac, char **av)
{
int fd, n, i;
int ph, ps, np;
diff --git a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile
index 23afda4a8..494026e42 100644
--- a/arch/ppc/coffboot/Makefile
+++ b/arch/ppc/coffboot/Makefile
@@ -8,7 +8,7 @@ HOSTCFLAGS = -O -I$(TOPDIR)/include
CFLAGS = $(CPPFLAGS) -O -fno-builtin
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
+CHRP_LD_ARGS = -Ttext 0x01000000
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
diff --git a/arch/ppc/coffboot/chrpmain.c b/arch/ppc/coffboot/chrpmain.c
index 4d994d17e..08b238b16 100644
--- a/arch/ppc/coffboot/chrpmain.c
+++ b/arch/ppc/coffboot/chrpmain.c
@@ -22,13 +22,18 @@ 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 RAM_END (16 << 20)
#define PROG_START 0x00010000
+#define PROG_SIZE 0x003f0000
+
+#define SCRATCH_SIZE (128 << 10)
char *avail_ram;
-char *end_avail;
+char *begin_avail, *end_avail;
+char *avail_high;
+unsigned int heap_use;
+unsigned int heap_max;
extern char _end[];
extern char image_data[];
@@ -60,29 +65,30 @@ boot(int a1, int a2, void *prom)
im = image_data;
len = image_len;
/* claim 3MB starting at PROG_START */
- claim(PROG_START, 3 << 20, 0);
+ claim(PROG_START, PROG_SIZE, 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);
+ /* claim some memory for scratch space */
+ avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10);
+ begin_avail = avail_high = avail_ram;
+ end_avail = avail_ram + SCRATCH_SIZE;
+ printf("heap at 0x%x\n", avail_ram);
printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
- gunzip(dst, 3 << 20, im, &len);
+ gunzip(dst, PROG_SIZE, im, &len);
printf("done %u bytes\n", len);
+ printf("%u bytes of heap consumed, max in use %u\n",
+ avail_high - begin_avail, heap_max);
} 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);
+ (*(void (*)())sa)(a1, a2, prom);
printf("returned?\n");
@@ -122,6 +128,7 @@ void make_bi_recs(unsigned long addr)
rec = (struct bi_record *)((unsigned long)rec + rec->size);
}
+#if 0
#define eieio() asm volatile("eieio");
void stop_imac_ethernet(void)
@@ -172,14 +179,35 @@ void stop_imac_usb(void)
*usb_ctrl = 0x01000000; /* cpu_to_le32(1) */
eieio();
}
+#endif
+
+struct memchunk {
+ unsigned int size;
+ struct memchunk *next;
+};
+
+static struct memchunk *freechunks;
void *zalloc(void *x, unsigned items, unsigned size)
{
- void *p = avail_ram;
+ void *p;
+ struct memchunk **mpp, *mp;
size *= items;
size = (size + 7) & -8;
+ heap_use += size;
+ if (heap_use > heap_max)
+ heap_max = heap_use;
+ for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) {
+ if (mp->size == size) {
+ *mpp = mp->next;
+ return mp;
+ }
+ }
+ p = avail_ram;
avail_ram += size;
+ if (avail_ram > avail_high)
+ avail_high = avail_ram;
if (avail_ram > end_avail) {
printf("oops... out of memory\n");
pause();
@@ -189,6 +217,17 @@ void *zalloc(void *x, unsigned items, unsigned size)
void zfree(void *x, void *addr, unsigned nb)
{
+ struct memchunk *mp = addr;
+
+ nb = (nb + 7) & -8;
+ heap_use -= nb;
+ if (avail_ram == addr + nb) {
+ avail_ram = addr;
+ return;
+ }
+ mp->size = nb;
+ mp->next = freechunks;
+ freechunks = mp;
}
#define HEAD_CRC 2
diff --git a/arch/ppc/config.in b/arch/ppc/config.in
index 950118eb2..0a217d4c9 100644
--- a/arch/ppc/config.in
+++ b/arch/ppc/config.in
@@ -88,11 +88,15 @@ fi
if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then
bool 'Math emulation' CONFIG_MATH_EMULATION
fi
+
endmenu
mainmenu_option next_comment
comment 'General setup'
+bool 'High memory support (experimental)' CONFIG_HIGHMEM
+bool 'Mac-on-Linux support' CONFIG_MOL
+
define_bool CONFIG_ISA n
define_bool CONFIG_SBUS n
@@ -140,20 +144,6 @@ if [ "$CONFIG_4xx" != "y" -a "$CONFIG_8xx" != "y" ]; then
bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC
fi
- bool 'Power management support for PowerBooks' CONFIG_PMAC_PBOOK
- bool 'Support for PowerMac floppy' CONFIG_MAC_FLOPPY
- tristate 'Support for PowerMac serial ports' CONFIG_MAC_SERIAL
- if [ "$CONFIG_MAC_SERIAL" = "y" ]; then
- bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE
- fi
- bool 'Apple Desktop Bus (ADB) support' CONFIG_ADB
- if [ "$CONFIG_ADB" = "y" ]; then
- bool ' Include CUDA ADB driver' CONFIG_ADB_CUDA
- bool ' Include MacIO ADB driver' CONFIG_ADB_MACIO
- bool ' Include PMU (Powerbook) ADB driver' CONFIG_ADB_PMU
- bool 'Support for ADB keyboard' CONFIG_ADB_KEYBOARD
- bool 'Support for ADB mouse' CONFIG_ADBMOUSE
- fi
tristate 'Support for /dev/rtc' CONFIG_PPC_RTC
bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE
bool 'Support for early boot text console (BootX only)' CONFIG_BOOTX_TEXT
@@ -192,7 +182,7 @@ endmenu
source drivers/mtd/Config.in
source drivers/pnp/Config.in
source drivers/block/Config.in
-#source drivers.new/Config.in
+source drivers/md/Config.in
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
@@ -262,6 +252,43 @@ comment 'Console drivers'
source drivers/video/Config.in
endmenu
+source drivers/input/Config.in
+
+mainmenu_option next_comment
+comment 'Macintosh device drivers'
+
+if [ "$CONFIG_ALL_PPC" = "y" ]; then
+ # we want to change this to something like CONFIG_SYSCTRL_CUDA/PMU
+ bool 'Support for CUDA based PowerMacs' CONFIG_ADB_CUDA
+ bool 'Support for PMU based PowerMacs' CONFIG_ADB_PMU
+ if [ "$CONFIG_ADB_PMU" = "y" ]; then
+ bool ' Power management support for PowerBooks' CONFIG_PMAC_PBOOK
+ # made a separate option since backlight may end up beeing used
+ # on non-powerbook machines (but only on PMU based ones AFAIK)
+ bool ' Backlight control for LCD screens' CONFIG_PMAC_BACKLIGHT
+ fi
+ bool 'Support for PowerMac floppy' CONFIG_MAC_FLOPPY
+ tristate 'Support for PowerMac serial ports' CONFIG_MAC_SERIAL
+ if [ "$CONFIG_MAC_SERIAL" = "y" ]; then
+ bool ' Support for console on serial port' CONFIG_SERIAL_CONSOLE
+ fi
+ bool 'Apple Desktop Bus (ADB) support' CONFIG_ADB
+ if [ "$CONFIG_ADB" = "y" ]; then
+ bool ' Include MacIO (CHRP) ADB driver' CONFIG_ADB_MACIO
+ fi
+fi
+if [ "$CONFIG_ADB" = "y" ]; then
+ dep_bool ' Use input layer for ADB devices' CONFIG_INPUT_ADBHID $CONFIG_INPUT
+ if [ "$CONFIG_INPUT_ADBHID" = "y" ]; then
+ define_bool CONFIG_MAC_HID y
+ bool ' Support for ADB raw keycodes' CONFIG_MAC_ADBKEYCODES
+ bool ' Support for mouse button 2+3 emulation' CONFIG_MAC_EMUMOUSEBTN
+ else
+ bool ' Support for ADB keyboard (old driver)' CONFIG_ADB_KEYBOARD
+ fi
+fi
+endmenu
+
source drivers/char/Config.in
source drivers/media/Config.in
@@ -287,7 +314,6 @@ source arch/ppc/8260_io/Config.in
fi
source drivers/usb/Config.in
-source drivers/input/Config.in
mainmenu_option next_comment
comment 'Kernel hacking'
diff --git a/arch/ppc/configs/common_defconfig b/arch/ppc/configs/common_defconfig
index 68e49c148..a9ae80db0 100644
--- a/arch/ppc/configs/common_defconfig
+++ b/arch/ppc/configs/common_defconfig
@@ -1,5 +1,5 @@
#
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
#
# CONFIG_UID16 is not set
@@ -9,12 +9,20 @@
CONFIG_EXPERIMENTAL=y
#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
# Platform support
#
CONFIG_PPC=y
CONFIG_6xx=y
# CONFIG_4xx is not set
-# CONFIG_PPC64BRIDGE is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
# CONFIG_8260 is not set
# CONFIG_8xx is not set
CONFIG_ALL_PPC=y
@@ -25,15 +33,9 @@ CONFIG_ALL_PPC=y
CONFIG_ALTIVEC=y
#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
-
-#
# General setup
#
+# CONFIG_HIGHMEM is not set
# CONFIG_ISA is not set
# CONFIG_SBUS is not set
CONFIG_PCI=y
@@ -44,8 +46,8 @@ CONFIG_SYSVIPC=y
CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_PCI_NAMES is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_PCI_NAMES=y
# CONFIG_HOTPLUG is not set
# CONFIG_PCMCIA is not set
@@ -57,21 +59,18 @@ CONFIG_VGA_CONSOLE=y
CONFIG_FB=y
CONFIG_FB_COMPAT_XPMAC=y
CONFIG_PMAC_PBOOK=y
-CONFIG_MAC_FLOPPY=y
-CONFIG_MAC_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-CONFIG_ADB=y
-CONFIG_ADB_CUDA=y
-CONFIG_ADB_MACIO=y
-CONFIG_ADB_PMU=y
-CONFIG_ADB_KEYBOARD=y
-CONFIG_ADBMOUSE=y
+CONFIG_PPC_RTC=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BOOTX_TEXT=y
# CONFIG_MOTOROLA_HOTSWAP is not set
# CONFIG_CMDLINE_BOOL is not set
#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
# Plug and Play configuration
#
# CONFIG_PNP is not set
@@ -90,8 +89,11 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_LVM is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_STRIPED is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
#
@@ -109,22 +111,24 @@ CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
# CONFIG_IP_PNP is not set
-# 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_INET_ECN is not set
CONFIG_SYN_COOKIES=y
-CONFIG_SKB_LARGE=y
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
+
+#
+#
+#
# CONFIG_IPX is not set
CONFIG_ATALK=m
# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
# CONFIG_LLC is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -145,26 +149,42 @@ CONFIG_IDE=y
# IDE, ATA and ATAPI Block devices
#
CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
# CONFIG_BLK_DEV_IDECS is not set
CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
CONFIG_BLK_DEV_IDESCSI=y
+
+#
+# IDE chipset support/bugfixes
+#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
# CONFIG_BLK_DEV_ISAPNP is not set
# CONFIG_BLK_DEV_RZ1000 is not set
CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_IDEPCI_SHARE_IRQ=y
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set
CONFIG_IDEDMA_PCI_AUTO=y
CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
# CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
# CONFIG_BLK_DEV_AEC62XX is not set
@@ -173,37 +193,40 @@ CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
# CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD7409 is not set
# CONFIG_AMD7409_OVERRIDE is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_CMD64X_RAID is not set
+CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_HPT34X_AUTODMA is not set
# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_HPT366_FIP is not set
-# CONFIG_HPT366_MODE3 is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_PDC202XX is not set
# CONFIG_PDC202XX_BURST is not set
-# CONFIG_PDC202XX_MASTER is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_VIA82CXXX_TUNING is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_SL82C105=y
CONFIG_BLK_DEV_IDE_PMAC=y
CONFIG_BLK_DEV_IDEDMA_PMAC=y
-CONFIG_IDEDMA_PMAC_AUTO=y
+CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO=y
CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDE_CHIPSETS is not set
CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
CONFIG_BLK_DEV_IDE_MODES=y
#
# SCSI support
#
CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
CONFIG_CHR_DEV_ST=y
@@ -211,6 +234,10 @@ CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_SR_EXTRA_DEVS=2
CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
# CONFIG_SCSI_DEBUG_QUEUES is not set
# CONFIG_SCSI_MULTI_LUN is not set
CONFIG_SCSI_CONSTANTS=y
@@ -296,6 +323,7 @@ CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
# CONFIG_ETHERTAP is not set
# CONFIG_NET_SB1000 is not set
@@ -327,8 +355,9 @@ CONFIG_DE4X5=y
# CONFIG_DM9102 is not set
# CONFIG_EEPRO100 is not set
# CONFIG_LNE390 is not set
-# CONFIG_NE3210 is not set
+# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
# CONFIG_RTL8129 is not set
# CONFIG_8139TOO is not set
# CONFIG_SIS900 is not set
@@ -347,11 +376,13 @@ CONFIG_DE4X5=y
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_ASYNC is not set
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
+CONFIG_PPP_DEFLATE=y
# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
# CONFIG_SLIP is not set
#
@@ -404,12 +435,13 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_FB_RIVA is not set
# CONFIG_FB_CLGEN is not set
# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
CONFIG_FB_OF=y
CONFIG_FB_CONTROL=y
CONFIG_FB_PLATINUM=y
CONFIG_FB_VALKYRIE=y
-CONFIG_FB_IMSTT=y
CONFIG_FB_CT65550=y
+CONFIG_FB_IMSTT=y
# CONFIG_FB_S3TRIO is not set
# CONFIG_FB_VGA16 is not set
CONFIG_FB_MATROX=y
@@ -420,6 +452,7 @@ CONFIG_FB_MATROX_G100=y
CONFIG_FB_ATY=y
CONFIG_FB_ATY128=y
CONFIG_FB_3DFX=y
+# CONFIG_FB_SIS is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FBCON_ADVANCED is not set
CONFIG_FBCON_CFB8=y
@@ -437,6 +470,32 @@ CONFIG_FONT_SUN12x22=y
# CONFIG_FONT_ACORN_8x8 is not set
#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+
+#
+# Macintosh device drivers
+#
+CONFIG_MAC_FLOPPY=y
+CONFIG_MAC_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
+CONFIG_ADB=y
+CONFIG_ADB_CUDA=y
+CONFIG_ADB_MACIO=y
+CONFIG_ADB_PMU=y
+CONFIG_INPUT_ADBHID=y
+CONFIG_MAC_HID=y
+CONFIG_MAC_ADBKEYCODES=y
+CONFIG_MAC_EMUMOUSEBTN=y
+
+#
# Character devices
#
CONFIG_VT=y
@@ -459,7 +518,6 @@ CONFIG_BUSMOUSE=y
# CONFIG_ATIXL_BUSMOUSE is not set
# CONFIG_LOGIBUSMOUSE is not set
# CONFIG_MS_BUSMOUSE is not set
-CONFIG_ADBMOUSE=y
CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
@@ -469,19 +527,19 @@ CONFIG_PSMOUSE=y
# Joysticks
#
# CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
# CONFIG_QIC02_TAPE is not set
#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
CONFIG_NVRAM=y
# CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -490,26 +548,31 @@ CONFIG_NVRAM=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
#
# File systems
#
# CONFIG_QUOTA is not set
CONFIG_AUTOFS_FS=y
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=y
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
-CONFIG_HFS_FS=y
+# CONFIG_HFS_FS is not set
# CONFIG_BFS_FS is not set
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
# CONFIG_UMSDOS_FS is not set
CONFIG_VFAT_FS=y
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_RAMFS is not set
CONFIG_ISO9660_FS=y
@@ -519,7 +582,8 @@ CONFIG_ISO9660_FS=y
# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
+CONFIG_DEVFS_FS=y
+# CONFIG_DEVFS_MOUNT is not set
# CONFIG_DEVFS_DEBUG is not set
CONFIG_DEVPTS_FS=y
# CONFIG_QNX4FS_FS is not set
@@ -571,12 +635,14 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
CONFIG_NLS=y
#
# Native Language Support
#
+CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
@@ -593,6 +659,10 @@ CONFIG_NLS=y
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_ISO8859_1 is not set
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
@@ -605,6 +675,7 @@ CONFIG_NLS=y
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_UTF8 is not set
#
# Sound
@@ -614,6 +685,7 @@ CONFIG_DMASOUND_AWACS=y
CONFIG_DMASOUND=y
# CONFIG_SOUND_CMPCI is not set
# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
# CONFIG_SOUND_ES1370 is not set
# CONFIG_SOUND_ES1371 is not set
# CONFIG_SOUND_ESSSOLO1 is not set
@@ -622,6 +694,7 @@ CONFIG_DMASOUND=y
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
CONFIG_SOUND_OSS=y
# CONFIG_SOUND_TRACEINIT is not set
# CONFIG_SOUND_DMAP is not set
@@ -647,24 +720,39 @@ CONFIG_SOUND_CS4232=m
# CONFIG_SOUND_AWE32_SYNTH is not set
# CONFIG_SOUND_WAVEFRONT is not set
# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_VIA82CXXX is not set
# CONFIG_SOUND_YM3812 is not set
# CONFIG_SOUND_OPL3SA1 is not set
# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMPCI is not set
# CONFIG_SOUND_UART6850 is not set
# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_TVMIXER is not set
#
# USB support
#
CONFIG_USB=y
CONFIG_USB_DEBUG=y
-# CONFIG_USB_DEVICEFS is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+
+#
+# USB Controllers
+#
# CONFIG_USB_UHCI is not set
# CONFIG_USB_UHCI_ALT is not set
CONFIG_USB_OHCI=y
+
+#
+# USB Devices
+#
# CONFIG_USB_PRINTER is not set
# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
# CONFIG_USB_AUDIO is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_SERIAL is not set
@@ -679,15 +767,13 @@ CONFIG_USB_OHCI=y
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_DSBR is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+# USB Human Interface Devices (HID)
+#
CONFIG_USB_HID=y
# CONFIG_USB_WACOM is not set
-# CONFIG_USB_WMFORCE is not set
-CONFIG_INPUT_KEYBDEV=y
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
#
# Kernel hacking
@@ -695,4 +781,3 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
CONFIG_MAGIC_SYSRQ=y
# CONFIG_KGDB is not set
CONFIG_XMON=y
-
diff --git a/arch/ppc/configs/est8260_defconfig b/arch/ppc/configs/est8260_defconfig
index 972820d21..d317c8517 100644
--- a/arch/ppc/configs/est8260_defconfig
+++ b/arch/ppc/configs/est8260_defconfig
@@ -9,12 +9,18 @@
CONFIG_EXPERIMENTAL=y
#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
# Platform support
#
CONFIG_PPC=y
# CONFIG_6xx is not set
# CONFIG_4xx is not set
-# CONFIG_PPC64BRIDGE is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
CONFIG_8260=y
# CONFIG_8xx is not set
CONFIG_6xx=y
@@ -29,13 +35,9 @@ CONFIG_EST8260=y
CONFIG_MACH_SPECIFIC=y
#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
# General setup
#
+# CONFIG_HIGHMEM is not set
# CONFIG_ISA is not set
# CONFIG_SBUS is not set
# CONFIG_PCI is not set
@@ -56,15 +58,17 @@ CONFIG_KERNEL_ELF=y
# 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_PPC_RTC is not set
# CONFIG_PROC_DEVICETREE is not set
# CONFIG_BOOTX_TEXT is not set
# CONFIG_MOTOROLA_HOTSWAP is not set
#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
# Plug and Play configuration
#
# CONFIG_PNP is not set
@@ -84,8 +88,10 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
-# CONFIG_RAID15_DANGEROUS is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
#
@@ -105,17 +111,11 @@ CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
-# 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_INET_ECN is not set
CONFIG_SYN_COOKIES=y
-
-#
-# (it is safe to leave these untouched)
-#
-CONFIG_SKB_LARGE=y
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
@@ -126,9 +126,9 @@ CONFIG_SKB_LARGE=y
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
# CONFIG_LLC is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -164,6 +164,7 @@ CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
# CONFIG_ETHERTAP is not set
# CONFIG_NET_SB1000 is not set
@@ -245,6 +246,15 @@ CONFIG_NET_ETHERNET=y
# CONFIG_FB is not set
#
+# Input core support
+#
+# CONFIG_INPUT is not set
+
+#
+# Macintosh device drivers
+#
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -269,19 +279,19 @@ CONFIG_UNIX98_PTY_COUNT=256
# Joysticks
#
# CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
# CONFIG_QIC02_TAPE is not set
#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -290,9 +300,13 @@ CONFIG_UNIX98_PTY_COUNT=256
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
#
# File systems
@@ -310,6 +324,7 @@ CONFIG_UNIX98_PTY_COUNT=256
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_RAMFS is not set
# CONFIG_ISO9660_FS is not set
@@ -369,6 +384,7 @@ CONFIG_PARTITION_ADVANCED=y
# CONFIG_MAC_PARTITION is not set
# CONFIG_MSDOS_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
@@ -382,7 +398,7 @@ CONFIG_PARTITION_ADVANCED=y
#
CONFIG_SCC_ENET=y
CONFIG_SCC1_ENET=y
-# CONFIG_FCC_ENET is not set
+# CONFIG_FEC_ENET is not set
#
# USB support
diff --git a/arch/ppc/configs/gemini_defconfig b/arch/ppc/configs/gemini_defconfig
index e141e8f54..522bd5d5d 100644
--- a/arch/ppc/configs/gemini_defconfig
+++ b/arch/ppc/configs/gemini_defconfig
@@ -14,14 +14,12 @@ CONFIG_EXPERIMENTAL=y
CONFIG_PPC=y
CONFIG_6xx=y
# CONFIG_4xx is not set
-# CONFIG_PPC64BRIDGE is not set
-# CONFIG_82xx is not set
+# CONFIG_PPC64 is not set
+# CONFIG_8260 is not set
# CONFIG_8xx is not set
-# CONFIG_PMAC is not set
-# CONFIG_PREP is not set
-# CONFIG_CHRP is not set
# CONFIG_ALL_PPC is not set
CONFIG_GEMINI=y
+# CONFIG_EST8260 is not set
# CONFIG_APUS is not set
# CONFIG_SMP is not set
CONFIG_ALTIVEC=y
@@ -37,7 +35,8 @@ CONFIG_KMOD=y
#
# General setup
#
-# CONFIG_PCI is not set
+# CONFIG_ISA is not set
+# CONFIG_SBUS is not set
CONFIG_PCI=y
CONFIG_NET=y
CONFIG_SYSCTL=y
@@ -47,8 +46,12 @@ CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
# CONFIG_BINFMT_MISC is not set
-# CONFIG_PCI_NAMES is not set
# CONFIG_HOTPLUG is not set
+# CONFIG_PCMCIA is not set
+
+#
+# Parallel port support
+#
# CONFIG_PARPORT is not set
# CONFIG_VGA_CONSOLE is not set
# CONFIG_FB is not set
@@ -57,7 +60,6 @@ CONFIG_KERNEL_ELF=y
# 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
@@ -70,22 +72,16 @@ CONFIG_KERNEL_ELF=y
# 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
+# Additional Block Devices
#
-# CONFIG_BLK_DEV_HD_ONLY is not set
-# CONFIG_BLK_CPQ_DA is not set
# CONFIG_BLK_DEV_LOOP is not set
# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_LVM is not set
# CONFIG_BLK_DEV_MD is not set
+# CONFIG_RAID15_DANGEROUS 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 is not set
-# CONFIG_BLK_DEV_IDE_MODES is not set
-# CONFIG_BLK_DEV_HD is not set
#
# Networking options
@@ -138,6 +134,13 @@ CONFIG_SKB_LARGE=y
# CONFIG_NET_SCHED is not set
#
+# ATA/IDE/MFM/RLL support
+#
+# CONFIG_IDE is not set
+# CONFIG_BLK_DEV_IDE_MODES is not set
+# CONFIG_BLK_DEV_HD is not set
+
+#
# SCSI support
#
CONFIG_SCSI=y
@@ -148,7 +151,6 @@ CONFIG_SCSI=y
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
# CONFIG_CHR_DEV_ST is not set
-CONFIG_ST_EXTRA_DEVS=2
CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_SR_EXTRA_DEVS=2
@@ -171,7 +173,6 @@ CONFIG_SCSI_CONSTANTS=y
# CONFIG_SCSI_AHA1542 is not set
# CONFIG_SCSI_AHA1740 is not set
# CONFIG_SCSI_AIC7XXX is not set
-# CONFIG_SCSI_IPS is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_SCSI_AM53C974 is not set
@@ -184,43 +185,22 @@ 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_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
-CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
-CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
-CONFIG_SCSI_NCR53C8XX_SYNC=20
-# CONFIG_SCSI_NCR53C8XX_PROFILE is not set
-# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
-# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
-# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+# CONFIG_SCSI_NCR53C7xx_sync is not set
+# CONFIG_SCSI_NCR53C7xx_FAST is not set
+# CONFIG_SCSI_NCR53C7xx_DISCONNECT is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
-# CONFIG_SCSI_QLOGIC_ISP is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
-# CONFIG_SCSI_QLOGIC_1280 is not set
-# CONFIG_SCSI_SEAGATE is not set
-# CONFIG_SCSI_DC390T is not set
# CONFIG_SCSI_T128 is not set
# CONFIG_SCSI_U14_34F is not set
-# CONFIG_SCSI_ULTRASTOR is not set
# CONFIG_SCSI_DEBUG is not set
# CONFIG_SCSI_MESH is not set
# CONFIG_SCSI_MAC53C94 is not set
-# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
-
-#
-# IEEE 1394 (FireWire) support
-#
-# CONFIG_IEEE1394 is not set
#
# Network device support
@@ -232,6 +212,7 @@ CONFIG_NETDEVICES=y
#
# CONFIG_ARCNET is not set
# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_ETHERTAP is not set
# CONFIG_NET_SB1000 is not set
@@ -249,12 +230,10 @@ 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_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_PCI is not set
# CONFIG_NET_POCKET is not set
#
@@ -274,7 +253,7 @@ CONFIG_NCR885E=y
# CONFIG_NET_RADIO is not set
#
-# Token Ring driver support
+# Token Ring devices
#
# CONFIG_TR is not set
# CONFIG_NET_FC is not set
@@ -292,6 +271,11 @@ CONFIG_NCR885E=y
# CONFIG_HAMRADIO is not set
#
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
# ISDN subsystem
#
# CONFIG_ISDN is not set
@@ -361,12 +345,7 @@ CONFIG_UNIX98_PTY_COUNT=256
# CONFIG_AGP is not set
#
-# USB support
-#
-# CONFIG_USB is not set
-
-#
-# Filesystems
+# File systems
#
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
@@ -378,12 +357,14 @@ CONFIG_UNIX98_PTY_COUNT=256
# CONFIG_FAT_FS is not set
# CONFIG_EFS_FS is not set
# CONFIG_CRAMFS is not set
+# CONFIG_RAMFS is not set
CONFIG_ISO9660_FS=y
# CONFIG_JOLIET 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_DEVFS_FS is not set
CONFIG_DEVPTS_FS=y
# CONFIG_QNX4FS_FS is not set
# CONFIG_ROMFS_FS is not set
@@ -397,6 +378,7 @@ CONFIG_EXT2_FS=y
#
# CONFIG_CODA_FS is not set
CONFIG_NFS_FS=y
+# CONFIG_NFS_V3 is not set
# CONFIG_NFSD is not set
CONFIG_SUNRPC=y
CONFIG_LOCKD=y
@@ -416,6 +398,11 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SOUND is not set
#
+# USB support
+#
+# CONFIG_USB is not set
+
+#
# Kernel hacking
#
# CONFIG_MAGIC_SYSRQ is not set
diff --git a/arch/ppc/configs/rpxcllf_defconfig b/arch/ppc/configs/rpxcllf_defconfig
index 9aaa80530..4dda3d93f 100644
--- a/arch/ppc/configs/rpxcllf_defconfig
+++ b/arch/ppc/configs/rpxcllf_defconfig
@@ -9,18 +9,27 @@
CONFIG_EXPERIMENTAL=y
#
+# Loadable module support
+#
+# CONFIG_MODULES is not set
+
+#
# Platform support
#
CONFIG_PPC=y
# CONFIG_6xx is not set
# CONFIG_4xx is not set
-# CONFIG_PPC64BRIDGE is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
# CONFIG_8260 is not set
CONFIG_8xx=y
CONFIG_SERIAL_CONSOLE=y
# CONFIG_RPXLITE is not set
CONFIG_RPXCLASSIC=y
# CONFIG_BSEIP is not set
+# CONFIG_TQM8xxL is not set
+# CONFIG_TQM860L is not set
+# CONFIG_TQM860 is not set
# CONFIG_MBX is not set
# CONFIG_WINCEPT is not set
# CONFIG_ALL_PPC is not set
@@ -29,13 +38,9 @@ CONFIG_MACH_SPECIFIC=y
CONFIG_MATH_EMULATION=y
#
-# Loadable module support
-#
-# CONFIG_MODULES is not set
-
-#
# General setup
#
+# CONFIG_HIGHMEM is not set
# CONFIG_ISA is not set
# CONFIG_SBUS is not set
# CONFIG_PCI is not set
@@ -56,6 +61,11 @@ CONFIG_KERNEL_ELF=y
# CONFIG_PARPORT is not set
#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
# Plug and Play configuration
#
# CONFIG_PNP is not set
@@ -75,8 +85,10 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
# CONFIG_MD_RAID0 is not set
-# CONFIG_RAID15_DANGEROUS is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
#
@@ -96,17 +108,11 @@ CONFIG_IP_MULTICAST=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
-# 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_INET_ECN is not set
CONFIG_SYN_COOKIES=y
-
-#
-# (it is safe to leave these untouched)
-#
-CONFIG_SKB_LARGE=y
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
@@ -117,9 +123,9 @@ CONFIG_SKB_LARGE=y
# CONFIG_IPX is not set
# CONFIG_ATALK is not set
# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
# CONFIG_LLC is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -155,6 +161,7 @@ CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
# CONFIG_ETHERTAP is not set
# CONFIG_NET_SB1000 is not set
@@ -236,6 +243,15 @@ CONFIG_NET_ETHERNET=y
# CONFIG_FB is not set
#
+# Input core support
+#
+# CONFIG_INPUT is not set
+
+#
+# Macintosh device drivers
+#
+
+#
# Character devices
#
# CONFIG_VT is not set
@@ -260,19 +276,19 @@ CONFIG_UNIX98_PTY_COUNT=256
# Joysticks
#
# CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
# CONFIG_QIC02_TAPE is not set
#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
# CONFIG_NVRAM is not set
# CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -281,9 +297,13 @@ CONFIG_UNIX98_PTY_COUNT=256
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
#
# File systems
@@ -301,6 +321,7 @@ CONFIG_UNIX98_PTY_COUNT=256
# CONFIG_UMSDOS_FS is not set
# CONFIG_VFAT_FS is not set
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_RAMFS is not set
# CONFIG_ISO9660_FS is not set
@@ -360,6 +381,7 @@ CONFIG_PARTITION_ADVANCED=y
# CONFIG_MAC_PARTITION is not set
# CONFIG_MSDOS_PARTITION is not set
# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
# CONFIG_NLS is not set
@@ -374,7 +396,9 @@ CONFIG_PARTITION_ADVANCED=y
CONFIG_SCC_ENET=y
CONFIG_SCC1_ENET=y
CONFIG_FEC_ENET=y
+CONFIG_ENET_BIG_BUFFERS=y
CONFIG_8xxSMC2=y
+# CONFIG_8xx_ALTSMC2 is not set
CONFIG_8xxSCC=y
#
diff --git a/arch/ppc/defconfig b/arch/ppc/defconfig
index e1854fad6..9b3d88212 100644
--- a/arch/ppc/defconfig
+++ b/arch/ppc/defconfig
@@ -1,5 +1,5 @@
#
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
#
# CONFIG_UID16 is not set
@@ -9,12 +9,20 @@
CONFIG_EXPERIMENTAL=y
#
+# Loadable module support
+#
+CONFIG_MODULES=y
+CONFIG_MODVERSIONS=y
+CONFIG_KMOD=y
+
+#
# Platform support
#
CONFIG_PPC=y
CONFIG_6xx=y
# CONFIG_4xx is not set
-# CONFIG_PPC64BRIDGE is not set
+# CONFIG_POWER3 is not set
+# CONFIG_POWER4 is not set
# CONFIG_8260 is not set
# CONFIG_8xx is not set
CONFIG_ALL_PPC=y
@@ -25,15 +33,9 @@ CONFIG_ALL_PPC=y
CONFIG_ALTIVEC=y
#
-# Loadable module support
-#
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_KMOD=y
-
-#
# General setup
#
+# CONFIG_HIGHMEM is not set
# CONFIG_ISA is not set
# CONFIG_SBUS is not set
CONFIG_PCI=y
@@ -44,8 +46,8 @@ CONFIG_SYSVIPC=y
CONFIG_KCORE_ELF=y
CONFIG_BINFMT_ELF=y
CONFIG_KERNEL_ELF=y
-# CONFIG_BINFMT_MISC is not set
-# CONFIG_PCI_NAMES is not set
+CONFIG_BINFMT_MISC=m
+CONFIG_PCI_NAMES=y
# CONFIG_HOTPLUG is not set
# CONFIG_PCMCIA is not set
@@ -57,21 +59,18 @@ CONFIG_VGA_CONSOLE=y
CONFIG_FB=y
CONFIG_FB_COMPAT_XPMAC=y
CONFIG_PMAC_PBOOK=y
-CONFIG_MAC_FLOPPY=y
-CONFIG_MAC_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
-CONFIG_ADB=y
-CONFIG_ADB_CUDA=y
-CONFIG_ADB_MACIO=y
-CONFIG_ADB_PMU=y
-CONFIG_ADB_KEYBOARD=y
-CONFIG_ADBMOUSE=y
+CONFIG_PPC_RTC=y
CONFIG_PROC_DEVICETREE=y
CONFIG_BOOTX_TEXT=y
# CONFIG_MOTOROLA_HOTSWAP is not set
# CONFIG_CMDLINE_BOOL is not set
#
+# Memory Technology Devices (MTD)
+#
+# CONFIG_MTD is not set
+
+#
# Plug and Play configuration
#
# CONFIG_PNP is not set
@@ -90,8 +89,11 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_BLK_DEV_LVM is not set
# CONFIG_BLK_DEV_MD is not set
# CONFIG_MD_LINEAR is not set
-# CONFIG_MD_STRIPED is not set
+# CONFIG_MD_RAID0 is not set
+# CONFIG_MD_RAID1 is not set
+# CONFIG_MD_RAID5 is not set
CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
CONFIG_BLK_DEV_INITRD=y
#
@@ -109,22 +111,24 @@ CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
# CONFIG_IP_PNP is not set
-# 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_INET_ECN is not set
CONFIG_SYN_COOKIES=y
-CONFIG_SKB_LARGE=y
# CONFIG_IPV6 is not set
# CONFIG_KHTTPD is not set
# CONFIG_ATM is not set
+
+#
+#
+#
# CONFIG_IPX is not set
CONFIG_ATALK=m
# CONFIG_DECNET is not set
+# CONFIG_BRIDGE is not set
# CONFIG_X25 is not set
# CONFIG_LAPB is not set
-# CONFIG_BRIDGE is not set
# CONFIG_LLC is not set
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
@@ -145,26 +149,42 @@ CONFIG_IDE=y
# IDE, ATA and ATAPI Block devices
#
CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
# CONFIG_BLK_DEV_HD_IDE is not set
# CONFIG_BLK_DEV_HD is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
+# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set
+# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set
+# CONFIG_BLK_DEV_IDEDISK_IBM is not set
+# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set
+# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set
+# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set
+# CONFIG_BLK_DEV_IDEDISK_WD is not set
+# CONFIG_BLK_DEV_COMMERIAL is not set
+# CONFIG_BLK_DEV_TIVO is not set
# CONFIG_BLK_DEV_IDECS is not set
CONFIG_BLK_DEV_IDECD=y
# CONFIG_BLK_DEV_IDETAPE is not set
-# CONFIG_BLK_DEV_IDEFLOPPY is not set
+CONFIG_BLK_DEV_IDEFLOPPY=y
CONFIG_BLK_DEV_IDESCSI=y
+
+#
+# IDE chipset support/bugfixes
+#
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_CMD640_ENHANCED is not set
# CONFIG_BLK_DEV_ISAPNP is not set
# CONFIG_BLK_DEV_RZ1000 is not set
CONFIG_BLK_DEV_IDEPCI=y
-# CONFIG_IDEPCI_SHARE_IRQ is not set
+CONFIG_IDEPCI_SHARE_IRQ=y
CONFIG_BLK_DEV_IDEDMA_PCI=y
# CONFIG_BLK_DEV_OFFBOARD is not set
CONFIG_IDEDMA_PCI_AUTO=y
CONFIG_BLK_DEV_IDEDMA=y
-CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
# CONFIG_IDEDMA_PCI_WIP is not set
# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set
# CONFIG_BLK_DEV_AEC62XX is not set
@@ -173,37 +193,40 @@ CONFIG_IDEDMA_PCI_EXPERIMENTAL=y
# CONFIG_WDC_ALI15X3 is not set
# CONFIG_BLK_DEV_AMD7409 is not set
# CONFIG_AMD7409_OVERRIDE is not set
-# CONFIG_BLK_DEV_CMD64X is not set
-# CONFIG_CMD64X_RAID is not set
+CONFIG_BLK_DEV_CMD64X=y
# CONFIG_BLK_DEV_CY82C693 is not set
# CONFIG_BLK_DEV_CS5530 is not set
# CONFIG_BLK_DEV_HPT34X is not set
# CONFIG_HPT34X_AUTODMA is not set
# CONFIG_BLK_DEV_HPT366 is not set
-# CONFIG_HPT366_FIP is not set
-# CONFIG_HPT366_MODE3 is not set
# CONFIG_BLK_DEV_NS87415 is not set
# CONFIG_BLK_DEV_OPTI621 is not set
# CONFIG_BLK_DEV_PDC202XX is not set
# CONFIG_PDC202XX_BURST is not set
-# CONFIG_PDC202XX_MASTER is not set
# CONFIG_BLK_DEV_SIS5513 is not set
# CONFIG_BLK_DEV_TRM290 is not set
# CONFIG_BLK_DEV_VIA82CXXX is not set
# CONFIG_VIA82CXXX_TUNING is not set
-# CONFIG_BLK_DEV_SL82C105 is not set
+CONFIG_BLK_DEV_SL82C105=y
CONFIG_BLK_DEV_IDE_PMAC=y
CONFIG_BLK_DEV_IDEDMA_PMAC=y
-CONFIG_IDEDMA_PMAC_AUTO=y
+CONFIG_BLK_DEV_IDEDMA_PMAC_AUTO=y
CONFIG_BLK_DEV_IDEDMA=y
+CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDE_CHIPSETS is not set
CONFIG_IDEDMA_AUTO=y
+# CONFIG_IDEDMA_IVB is not set
+# CONFIG_DMA_NONPCI is not set
CONFIG_BLK_DEV_IDE_MODES=y
#
# SCSI support
#
CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
CONFIG_BLK_DEV_SD=y
CONFIG_SD_EXTRA_DEVS=40
CONFIG_CHR_DEV_ST=y
@@ -211,6 +234,10 @@ CONFIG_BLK_DEV_SR=y
CONFIG_BLK_DEV_SR_VENDOR=y
CONFIG_SR_EXTRA_DEVS=2
CONFIG_CHR_DEV_SG=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
# CONFIG_SCSI_DEBUG_QUEUES is not set
# CONFIG_SCSI_MULTI_LUN is not set
CONFIG_SCSI_CONSTANTS=y
@@ -296,6 +323,7 @@ CONFIG_NETDEVICES=y
# CONFIG_DUMMY is not set
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
# CONFIG_ETHERTAP is not set
# CONFIG_NET_SB1000 is not set
@@ -327,8 +355,9 @@ CONFIG_DE4X5=y
# CONFIG_DM9102 is not set
# CONFIG_EEPRO100 is not set
# CONFIG_LNE390 is not set
-# CONFIG_NE3210 is not set
+# CONFIG_NATSEMI is not set
# CONFIG_NE2K_PCI is not set
+# CONFIG_NE3210 is not set
# CONFIG_RTL8129 is not set
# CONFIG_8139TOO is not set
# CONFIG_SIS900 is not set
@@ -347,11 +376,13 @@ CONFIG_DE4X5=y
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
CONFIG_PPP=y
-# CONFIG_PPP_MULTILINK is not set
-# CONFIG_PPP_ASYNC is not set
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_ASYNC=y
# CONFIG_PPP_SYNC_TTY is not set
-# CONFIG_PPP_DEFLATE is not set
+CONFIG_PPP_DEFLATE=y
# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPPOE is not set
# CONFIG_SLIP is not set
#
@@ -404,12 +435,13 @@ CONFIG_DUMMY_CONSOLE=y
# CONFIG_FB_RIVA is not set
# CONFIG_FB_CLGEN is not set
# CONFIG_FB_PM2 is not set
+# CONFIG_FB_CYBER2000 is not set
CONFIG_FB_OF=y
CONFIG_FB_CONTROL=y
CONFIG_FB_PLATINUM=y
CONFIG_FB_VALKYRIE=y
-CONFIG_FB_IMSTT=y
CONFIG_FB_CT65550=y
+CONFIG_FB_IMSTT=y
# CONFIG_FB_S3TRIO is not set
# CONFIG_FB_VGA16 is not set
CONFIG_FB_MATROX=y
@@ -420,6 +452,7 @@ CONFIG_FB_MATROX_G100=y
CONFIG_FB_ATY=y
CONFIG_FB_ATY128=y
CONFIG_FB_3DFX=y
+# CONFIG_FB_SIS is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FBCON_ADVANCED is not set
CONFIG_FBCON_CFB8=y
@@ -437,6 +470,32 @@ CONFIG_FONT_SUN12x22=y
# CONFIG_FONT_ACORN_8x8 is not set
#
+# Input core support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_KEYBDEV=y
+CONFIG_INPUT_MOUSEDEV=y
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+
+#
+# Macintosh device drivers
+#
+CONFIG_MAC_FLOPPY=y
+CONFIG_MAC_SERIAL=y
+# CONFIG_SERIAL_CONSOLE is not set
+CONFIG_ADB=y
+CONFIG_ADB_CUDA=y
+CONFIG_ADB_MACIO=y
+CONFIG_ADB_PMU=y
+CONFIG_INPUT_ADBHID=y
+CONFIG_MAC_HID=y
+CONFIG_MAC_ADBKEYCODES=y
+CONFIG_MAC_EMUMOUSEBTN=y
+
+#
# Character devices
#
CONFIG_VT=y
@@ -459,7 +518,6 @@ CONFIG_BUSMOUSE=y
# CONFIG_ATIXL_BUSMOUSE is not set
# CONFIG_LOGIBUSMOUSE is not set
# CONFIG_MS_BUSMOUSE is not set
-CONFIG_ADBMOUSE=y
CONFIG_MOUSE=y
CONFIG_PSMOUSE=y
# CONFIG_82C710_MOUSE is not set
@@ -469,19 +527,19 @@ CONFIG_PSMOUSE=y
# Joysticks
#
# CONFIG_JOYSTICK is not set
+
+#
+# Input core support is needed for joysticks
+#
# CONFIG_QIC02_TAPE is not set
#
# Watchdog Cards
#
# CONFIG_WATCHDOG is not set
+# CONFIG_INTEL_RNG is not set
CONFIG_NVRAM=y
# CONFIG_RTC is not set
-
-#
-# Video For Linux
-#
-# CONFIG_VIDEO_DEV is not set
# CONFIG_DTLK is not set
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
@@ -490,26 +548,31 @@ CONFIG_NVRAM=y
# Ftape, the floppy tape device driver
#
# CONFIG_FTAPE is not set
-# CONFIG_DRM is not set
-# CONFIG_DRM_TDFX is not set
# CONFIG_AGP is not set
+# CONFIG_DRM is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
#
# File systems
#
# CONFIG_QUOTA is not set
CONFIG_AUTOFS_FS=y
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=y
# CONFIG_ADFS_FS is not set
# CONFIG_ADFS_FS_RW is not set
# CONFIG_AFFS_FS is not set
-CONFIG_HFS_FS=y
+# CONFIG_HFS_FS is not set
# CONFIG_BFS_FS is not set
CONFIG_FAT_FS=y
CONFIG_MSDOS_FS=y
# CONFIG_UMSDOS_FS is not set
CONFIG_VFAT_FS=y
# CONFIG_EFS_FS is not set
+# CONFIG_JFFS_FS is not set
# CONFIG_CRAMFS is not set
# CONFIG_RAMFS is not set
CONFIG_ISO9660_FS=y
@@ -519,7 +582,7 @@ CONFIG_ISO9660_FS=y
# CONFIG_NTFS_RW is not set
# CONFIG_HPFS_FS is not set
CONFIG_PROC_FS=y
-# CONFIG_DEVFS_FS is not set
+CONFIG_DEVFS_FS=y
# CONFIG_DEVFS_MOUNT is not set
# CONFIG_DEVFS_DEBUG is not set
CONFIG_DEVPTS_FS=y
@@ -572,12 +635,14 @@ CONFIG_MSDOS_PARTITION=y
# CONFIG_SOLARIS_X86_PARTITION is not set
# CONFIG_UNIXWARE_DISKLABEL is not set
# CONFIG_SGI_PARTITION is not set
+# CONFIG_ULTRIX_PARTITION is not set
# CONFIG_SUN_PARTITION is not set
CONFIG_NLS=y
#
# Native Language Support
#
+CONFIG_NLS_DEFAULT="iso8859-1"
# CONFIG_NLS_CODEPAGE_437 is not set
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
@@ -594,6 +659,10 @@ CONFIG_NLS=y
# CONFIG_NLS_CODEPAGE_866 is not set
# CONFIG_NLS_CODEPAGE_869 is not set
# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
# CONFIG_NLS_ISO8859_1 is not set
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
@@ -606,6 +675,7 @@ CONFIG_NLS=y
# CONFIG_NLS_ISO8859_14 is not set
# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_UTF8 is not set
#
# Sound
@@ -615,6 +685,7 @@ CONFIG_DMASOUND_AWACS=y
CONFIG_DMASOUND=y
# CONFIG_SOUND_CMPCI is not set
# CONFIG_SOUND_EMU10K1 is not set
+# CONFIG_SOUND_FUSION is not set
# CONFIG_SOUND_ES1370 is not set
# CONFIG_SOUND_ES1371 is not set
# CONFIG_SOUND_ESSSOLO1 is not set
@@ -623,6 +694,7 @@ CONFIG_DMASOUND=y
# CONFIG_SOUND_TRIDENT is not set
# CONFIG_SOUND_MSNDCLAS is not set
# CONFIG_SOUND_MSNDPIN is not set
+# CONFIG_SOUND_VIA82CXXX is not set
CONFIG_SOUND_OSS=y
# CONFIG_SOUND_TRACEINIT is not set
# CONFIG_SOUND_DMAP is not set
@@ -648,24 +720,39 @@ CONFIG_SOUND_CS4232=m
# CONFIG_SOUND_AWE32_SYNTH is not set
# CONFIG_SOUND_WAVEFRONT is not set
# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_VIA82CXXX is not set
# CONFIG_SOUND_YM3812 is not set
# CONFIG_SOUND_OPL3SA1 is not set
# CONFIG_SOUND_OPL3SA2 is not set
+# CONFIG_SOUND_YMPCI is not set
# CONFIG_SOUND_UART6850 is not set
# CONFIG_SOUND_AEDSP16 is not set
+# CONFIG_SOUND_TVMIXER is not set
#
# USB support
#
CONFIG_USB=y
CONFIG_USB_DEBUG=y
-# CONFIG_USB_DEVICEFS is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_BANDWIDTH is not set
+
+#
+# USB Controllers
+#
# CONFIG_USB_UHCI is not set
# CONFIG_USB_UHCI_ALT is not set
CONFIG_USB_OHCI=y
+
+#
+# USB Devices
+#
# CONFIG_USB_PRINTER is not set
# CONFIG_USB_SCANNER is not set
+# CONFIG_USB_MICROTEK is not set
# CONFIG_USB_AUDIO is not set
# CONFIG_USB_ACM is not set
# CONFIG_USB_SERIAL is not set
@@ -680,15 +767,18 @@ CONFIG_USB_OHCI=y
# CONFIG_USB_PEGASUS is not set
# CONFIG_USB_RIO500 is not set
# CONFIG_USB_DSBR is not set
+# CONFIG_USB_BLUETOOTH is not set
+
+#
+# USB Human Interface Devices (HID)
+#
CONFIG_USB_HID=y
# CONFIG_USB_WACOM is not set
-# CONFIG_USB_WMFORCE is not set
-CONFIG_INPUT_KEYBDEV=y
-CONFIG_INPUT_MOUSEDEV=y
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
-# CONFIG_INPUT_JOYDEV is not set
-# CONFIG_INPUT_EVDEV is not set
+
+#
+# Mac-on-Linux (MOL) support
+#
+# CONFIG_MOL is not set
#
# Kernel hacking
diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile
index 0369ad800..a539083bd 100644
--- a/arch/ppc/kernel/Makefile
+++ b/arch/ppc/kernel/Makefile
@@ -99,8 +99,10 @@ endif
ifeq ($(CONFIG_ALL_PPC),y)
O_OBJS += pmac_pic.o pmac_setup.o pmac_time.o feature.o pmac_pci.o prom.o \
chrp_setup.o chrp_time.o chrp_pci.o open_pic.o indirect_pci.o \
- prep_pci.o i8259.o prep_nvram.o prep_time.o residual.o \
- pmac_backlight.o
+ prep_pci.o i8259.o prep_nvram.o prep_time.o residual.o
+ ifeq ($(CONFIG_PMAC_BACKLIGHT),y)
+ O_OBJS += pmac_backlight.o
+ endif
OX_OBJS += prep_setup.o
endif
ifeq ($(CONFIG_GEMINI),y)
diff --git a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c
index b93bd8193..d75663be5 100644
--- a/arch/ppc/kernel/apus_setup.c
+++ b/arch/ppc/kernel/apus_setup.c
@@ -304,7 +304,7 @@ __apus
void apus_calibrate_decr(void)
{
#ifdef CONFIG_APUS
- int freq, divisor;
+ unsigned long freq;
/* This algorithm for determining the bus speed was
contributed by Ralph Schmidt. */
@@ -335,8 +335,8 @@ void apus_calibrate_decr(void)
bus_speed = 60;
freq = 15000000;
} else if ((bus_speed >= 63) && (bus_speed < 69)) {
- bus_speed = 66;
- freq = 16500000;
+ bus_speed = 67;
+ freq = 16666667;
} else {
printk ("APUS: Unable to determine bus speed (%d). "
"Defaulting to 50MHz", bus_speed);
@@ -375,12 +375,10 @@ void apus_calibrate_decr(void)
}
- freq *= 60; /* try to make freq/1e6 an integer */
- divisor = 60;
- printk("time_init: decrementer frequency = %d/%d\n", freq, divisor);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
+ printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
+ freq/1000000, freq%1000000);
+ tb_ticks_per_jiffy = freq / HZ;
+ tb_to_us = mulhwu_scale_factor(freq, 1000000);
__bus_speed = bus_speed;
__speed_test_failed = speed_test_failed;
diff --git a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c
index c43296c42..43b678861 100644
--- a/arch/ppc/kernel/chrp_pci.c
+++ b/arch/ppc/kernel/chrp_pci.c
@@ -284,13 +284,38 @@ hydra_init(void)
return 1;
}
+#ifdef CONFIG_POWER4
+static void
+power4_fixup_dev(struct pci_dev *dev)
+{
+ int i;
+ unsigned long offset;
+
+ for (i = 0; i < 6; ++i) {
+ if (dev->resource[i].start == 0)
+ continue;
+ offset = pci_address_offset(dev->bus->number,
+ dev->resource[i].flags);
+ if (offset) {
+ dev->resource[i].start += offset;
+ dev->resource[i].end += offset;
+ printk("device %x.%x[%d] now [%lx..%lx]\n",
+ dev->bus->number, dev->devfn, i,
+ dev->resource[i].start,
+ dev->resource[i].end);
+ }
+ /* zap the 2nd function of the winbond chip */
+ if (dev->resource[i].flags & IORESOURCE_IO
+ && dev->bus->number == 0 && dev->devfn == 0x81)
+ dev->resource[i].flags &= ~IORESOURCE_IO;
+ }
+}
+#endif /* CONFIG_POWER4 */
+
void __init
chrp_pcibios_fixup(void)
{
struct pci_dev *dev;
-#ifdef CONFIG_POWER4
- int i;
-#endif
int *brp;
struct device_node *np;
extern struct pci_ops generic_pci_ops;
@@ -316,10 +341,8 @@ chrp_pcibios_fixup(void)
/* PCI interrupts are controlled by the OpenPIC */
pci_for_each_dev(dev) {
np = find_pci_device_OFnode(dev->bus->number, dev->devfn);
- if ( (np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
+ if ((np != 0) && (np->n_intrs > 0) && (np->intrs[0].line != 0))
dev->irq = np->intrs[0].line;
- if ( dev->irq )
- dev->irq = openpic_to_irq( dev->irq );
/* these need to be absolute addrs for OF and Matrox FB -- Cort */
if ( dev->vendor == PCI_VENDOR_ID_MATROX )
{
@@ -337,25 +360,7 @@ chrp_pcibios_fixup(void)
dev->devfn, PCI_VENDOR_ID, PCI_VENDOR_ID_AMD);
}
#ifdef CONFIG_POWER4
- for (i = 0; i < 6; ++i) {
- unsigned long offset;
- if (dev->resource[i].start == 0)
- continue;
- offset = pci_address_offset(dev->bus->number,
- dev->resource[i].flags);
- if (offset) {
- dev->resource[i].start += offset;
- dev->resource[i].end += offset;
- printk("device %x.%x[%d] now [%lx..%lx]\n",
- dev->bus->number, dev->devfn, i,
- dev->resource[i].start,
- dev->resource[i].end);
- }
- /* zap the 2nd function of the winbond chip */
- if (dev->resource[i].flags & IORESOURCE_IO
- && dev->bus->number == 0 && dev->devfn == 0x81)
- dev->resource[i].flags &= ~IORESOURCE_IO;
- }
+ power4_fixup_dev(dev);
#else
if (dev->bus->number > 0 && python_busnr > 0)
dev->resource[0].start += dev->bus->number*0x01000000;
@@ -363,6 +368,40 @@ chrp_pcibios_fixup(void)
}
}
+static struct {
+ /* parent is iomem */
+ struct resource ram, pci_mem, isa_mem, pci_io, pci_cfg, rom_exp, flash;
+ /* parent is isa_mem */
+ struct resource nvram;
+} gg2_resources = {
+ ram: { "RAM", 0x00000000, 0xbfffffff, IORESOURCE_MEM },
+ pci_mem: { "GG2 PCI mem", 0xc0000000, 0xf6ffffff, IORESOURCE_MEM },
+ isa_mem: { "GG2 ISA mem", 0xf7000000, 0xf7ffffff },
+ pci_io: { "GG2 PCI I/O", 0xf8000000, 0xf8ffffff },
+ pci_cfg: { "GG2 PCI cfg", 0xfec00000, 0xfec7ffff },
+ rom_exp: { "ROM exp", 0xff000000, 0xff7fffff, },
+ flash: { "Flash ROM", 0xfff80000, 0xffffffff },
+ nvram: { "NVRAM", 0xf70e0000, 0xf70e7fff },
+};
+
+static void __init gg2_pcibios_fixup(void)
+{
+ int i;
+ extern unsigned long *end_of_DRAM;
+
+ chrp_pcibios_fixup();
+ gg2_resources.ram.end = (unsigned long)end_of_DRAM-PAGE_OFFSET;
+ for (i = 0; i < 7; i++)
+ request_resource(&iomem_resource,
+ &((struct resource *)&gg2_resources)[i]);
+ request_resource(&gg2_resources.isa_mem, &gg2_resources.nvram);
+}
+
+static void __init gg2_pcibios_fixup_bus(struct pci_bus *bus)
+{
+ bus->resource[1] = &gg2_resources.pci_mem;
+}
+
decl_config_access_method(grackle);
decl_config_access_method(indirect);
decl_config_access_method(rtas);
@@ -372,6 +411,7 @@ chrp_setup_pci_ptrs(void)
{
struct device_node *py;
+ ppc_md.pcibios_fixup = chrp_pcibios_fixup;
#ifdef CONFIG_POWER4
set_config_access_method(rtas);
pci_dram_offset = 0;
@@ -428,16 +468,17 @@ chrp_setup_pci_ptrs(void)
}
else
{
+ /* LongTrail */
pci_dram_offset = 0;
isa_mem_base = 0xf7000000;
isa_io_base = 0xf8000000;
set_config_access_method(gg2);
+ ppc_md.pcibios_fixup = gg2_pcibios_fixup;
+ ppc_md.pcibios_fixup_bus = gg2_pcibios_fixup_bus;
}
}
}
#endif /* CONFIG_POWER4 */
-
- ppc_md.pcibios_fixup = chrp_pcibios_fixup;
}
#ifdef CONFIG_PPC64BRIDGE
diff --git a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c
index 8d6649231..ccc6621de 100644
--- a/arch/ppc/kernel/chrp_setup.c
+++ b/arch/ppc/kernel/chrp_setup.c
@@ -62,11 +62,13 @@ extern volatile unsigned char *chrp_int_ack_special;
unsigned long chrp_get_rtc_time(void);
int chrp_set_rtc_time(unsigned long nowtime);
void chrp_calibrate_decr(void);
-void chrp_time_init(void);
+long chrp_time_init(void);
void chrp_setup_pci_ptrs(void);
-extern void chrp_progress(char *, unsigned short);
void chrp_event_scan(void);
+void rtas_display_progress(char *, unsigned short);
+void rtas_indicator_progress(char *, unsigned short);
+void bootx_text_progress(char *, unsigned short);
extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
extern int pckbd_getkeycode(unsigned int scancode);
@@ -91,6 +93,8 @@ extern PTE *Hash, *Hash_end;
extern unsigned long Hash_size, Hash_mask;
extern int probingmem;
extern unsigned long loops_per_sec;
+extern int bootx_text_mapped;
+static int max_width;
unsigned long empty_zero_page[1024];
@@ -252,13 +256,6 @@ chrp_setup_arch(void)
#endif
ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */
printk("Boot arguments: %s\n", cmd_line);
-
- request_region(0x20,0x20,"pic1");
- request_region(0xa0,0x20,"pic2");
- request_region(0x00,0x20,"dma1");
- request_region(0x40,0x20,"timer");
- request_region(0x80,0x10,"dma page reg");
- request_region(0xc0,0x20,"dma2");
#ifndef CONFIG_PPC64BRIDGE
/* PCI bridge config space access area -
@@ -446,11 +443,43 @@ void __init chrp_init_IRQ(void)
void __init
chrp_init2(void)
{
+#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD)
+ struct device_node *kbd;
+#endif
#ifdef CONFIG_NVRAM
pmac_nvram_init();
#endif
+
+ request_region(0x20,0x20,"pic1");
+ request_region(0xa0,0x20,"pic2");
+ request_region(0x00,0x20,"dma1");
+ request_region(0x40,0x20,"timer");
+ request_region(0x80,0x10,"dma page reg");
+ request_region(0xc0,0x20,"dma2");
+
if (ppc_md.progress)
ppc_md.progress(" Have fun! ", 0x7777);
+
+#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD)
+ /* see if there is a keyboard in the device tree
+ with a parent of type "adb" */
+ for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next)
+ if (kbd->parent && kbd->parent->type
+ && strcmp(kbd->parent->type, "adb") == 0)
+ break;
+ if (kbd) {
+ ppc_md.kbd_setkeycode = mackbd_setkeycode;
+ ppc_md.kbd_getkeycode = mackbd_getkeycode;
+ ppc_md.kbd_translate = mackbd_translate;
+ ppc_md.kbd_unexpected_up = mackbd_unexpected_up;
+ ppc_md.kbd_leds = mackbd_leds;
+ ppc_md.kbd_init_hw = mackbd_init_hw;
+#ifdef CONFIG_MAGIC_SYSRQ
+ ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate;
+ SYSRQ_KEY = 0x69;
+#endif /* CONFIG_MAGIC_SYSRQ */
+ }
+#endif /* CONFIG_VT && CONFIG_ADB_KEYBOARD */
}
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
@@ -598,40 +627,40 @@ void __init
ppc_md.calibrate_decr = chrp_calibrate_decr;
#ifdef CONFIG_VT
-#ifdef CONFIG_MAC_KEYBOARD
- if (adb_driver == NULL)
- {
-#endif /* CONFIG_MAC_KEYBOAD */
- ppc_md.kbd_setkeycode = pckbd_setkeycode;
- ppc_md.kbd_getkeycode = pckbd_getkeycode;
- ppc_md.kbd_translate = pckbd_translate;
- ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
- ppc_md.kbd_leds = pckbd_leds;
- ppc_md.kbd_init_hw = pckbd_init_hw;
-#ifdef CONFIG_MAGIC_SYSRQ
- ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
- SYSRQ_KEY = 0x54;
-#endif /* CONFIG_MAGIC_SYSRQ */
-#ifdef CONFIG_MAC_KEYBOARD
- }
- else
- {
- ppc_md.kbd_setkeycode = mackbd_setkeycode;
- ppc_md.kbd_getkeycode = mackbd_getkeycode;
- ppc_md.kbd_translate = mackbd_translate;
- ppc_md.kbd_unexpected_up = mackbd_unexpected_up;
- ppc_md.kbd_leds = mackbd_leds;
- ppc_md.kbd_init_hw = mackbd_init_hw;
+ /* these are adjusted in chrp_init2 if we have an ADB keyboard */
+ ppc_md.kbd_setkeycode = pckbd_setkeycode;
+ ppc_md.kbd_getkeycode = pckbd_getkeycode;
+ ppc_md.kbd_translate = pckbd_translate;
+ ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
+ ppc_md.kbd_leds = pckbd_leds;
+ ppc_md.kbd_init_hw = pckbd_init_hw;
#ifdef CONFIG_MAGIC_SYSRQ
- ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate;
- SYSRQ_KEY = 0x69;
+ ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
+ SYSRQ_KEY = 0x54;
#endif /* CONFIG_MAGIC_SYSRQ */
- }
-#endif /* CONFIG_MAC_KEYBOARD */
#endif /* CONFIG_VT */
- if ( rtas_data )
- ppc_md.progress = chrp_progress;
-
+
+ if (rtas_data) {
+ struct device_node *rtas;
+ unsigned int *p;
+
+ rtas = find_devices("rtas");
+ if (rtas != NULL) {
+ if (get_property(rtas, "display-character", NULL)) {
+ ppc_md.progress = rtas_display_progress;
+ p = (unsigned int *) get_property
+ (rtas, "ibm,display-line-length", NULL);
+ if (p)
+ max_width = *p;
+ } else if (get_property(rtas, "set-indicator", NULL))
+ ppc_md.progress = rtas_indicator_progress;
+ }
+ }
+#ifdef CONFIG_BOOTX_TEXT
+ if (ppc_md.progress == NULL && bootx_text_mapped)
+ ppc_md.progress = bootx_text_progress;
+#endif
+
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
ppc_ide_md.insw = chrp_ide_insw;
ppc_ide_md.outsw = chrp_ide_outsw;
@@ -653,30 +682,13 @@ void __init
}
void __chrp
-chrp_progress(char *s, unsigned short hex)
+rtas_display_progress(char *s, unsigned short hex)
{
- extern unsigned int rtas_data;
- int max_width, width;
- struct device_node *root;
+ int width;
char *os = s;
- unsigned long *p;
- if ( (root = find_path_device("/rtas")) &&
- (p = (unsigned long *)get_property(root,
- "ibm,display-line-length",
- NULL)) )
- max_width = *p;
- else
- max_width = 0x10;
-
- if ( (_machine != _MACH_chrp) || !rtas_data )
- return;
if ( call_rtas( "display-character", 1, 1, NULL, '\r' ) )
- {
- /* assume no display-character RTAS method - use hex display */
- call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex);
return;
- }
width = max_width;
while ( *os )
@@ -696,3 +708,17 @@ chrp_progress(char *s, unsigned short hex)
call_rtas( "display-character", 1, 1, NULL, ' ' );
}
+void __chrp
+rtas_indicator_progress(char *s, unsigned short hex)
+{
+ call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex);
+}
+
+#ifdef CONFIG_BOOTX_TEXT
+void
+bootx_text_progress(char *s, unsigned short hex)
+{
+ prom_print(s);
+ prom_print("\n");
+}
+#endif /* CONFIG_BOOTX_TEXT */
diff --git a/arch/ppc/kernel/chrp_time.c b/arch/ppc/kernel/chrp_time.c
index 54b4a76bb..67325c685 100644
--- a/arch/ppc/kernel/chrp_time.c
+++ b/arch/ppc/kernel/chrp_time.c
@@ -15,6 +15,7 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
+#include <linux/time.h>
#include <linux/timex.h>
#include <linux/kernel_stat.h>
#include <linux/mc146818rtc.h>
@@ -32,18 +33,20 @@ static int nvram_as1 = NVRAM_AS1;
static int nvram_as0 = NVRAM_AS0;
static int nvram_data = NVRAM_DATA;
-void __init chrp_time_init(void)
+long __init chrp_time_init(void)
{
struct device_node *rtcs;
int base;
rtcs = find_compatible_devices("rtc", "pnpPNP,b00");
if (rtcs == NULL || rtcs->addrs == NULL)
- return;
+ return 0;
base = rtcs->addrs[0].address;
nvram_as1 = 0;
nvram_as0 = base;
nvram_data = base + 1;
+
+ return 0;
}
int __chrp chrp_cmos_clock_read(int addr)
@@ -115,28 +118,34 @@ int __chrp chrp_set_rtc_time(unsigned long nowtime)
unsigned long __chrp chrp_get_rtc_time(void)
{
unsigned int year, mon, day, hour, min, sec;
- int i;
+ int uip, i;
/* The Linux interpretation of the CMOS clock register contents:
* When the Update-In-Progress (UIP) flag goes from 1 to 0, the
* RTC registers show the second which has precisely just started.
* Let's hope other operating systems interpret the RTC the same way.
*/
- /* read RTC exactly on falling edge of update flag */
- for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
- if (chrp_cmos_clock_read(RTC_FREQ_SELECT) & RTC_UIP)
- break;
- for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
- if (!(chrp_cmos_clock_read(RTC_FREQ_SELECT) & RTC_UIP))
- break;
- do { /* Isn't this overkill ? UIP above should guarantee consistency */
+
+ /* Since the UIP flag is set for about 2.2 ms and the clock
+ * is typically written with a precision of 1 jiffy, trying
+ * to obtain a precision better than a few milliseconds is
+ * an illusion. Only consistency is interesting, this also
+ * allows to use the routine for /dev/rtc without a potential
+ * 1 second kernel busy loop triggered by any reader of /dev/rtc.
+ */
+
+ for ( i = 0; i<1000000; i++) {
+ uip = chrp_cmos_clock_read(RTC_FREQ_SELECT);
sec = chrp_cmos_clock_read(RTC_SECONDS);
min = chrp_cmos_clock_read(RTC_MINUTES);
hour = chrp_cmos_clock_read(RTC_HOURS);
day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH);
mon = chrp_cmos_clock_read(RTC_MONTH);
year = chrp_cmos_clock_read(RTC_YEAR);
- } while (sec != chrp_cmos_clock_read(RTC_SECONDS));
+ uip |= chrp_cmos_clock_read(RTC_FREQ_SELECT);
+ if ((uip & RTC_UIP)==0) break;
+ }
+
if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
{
BCD_TO_BIN(sec);
@@ -155,8 +164,7 @@ unsigned long __chrp chrp_get_rtc_time(void)
void __init chrp_calibrate_decr(void)
{
struct device_node *cpu;
- int *fp, divisor;
- unsigned long freq;
+ unsigned int freq, *fp;
if (via_calibrate_decr())
return;
@@ -168,15 +176,13 @@ void __init chrp_calibrate_decr(void)
freq = 16666000; /* hardcoded default */
cpu = find_type_devices("cpu");
if (cpu != 0) {
- fp = (int *) get_property(cpu, "timebase-frequency", NULL);
+ fp = (unsigned int *)
+ get_property(cpu, "timebase-frequency", NULL);
if (fp != 0)
freq = *fp;
}
- freq *= 30;
- divisor = 30;
- printk("time_init: decrementer frequency = %lu/%d (%ld MHz)\n", freq,
- divisor, (freq/divisor)>>20);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
+ printk("time_init: decrementer frequency = %u.%.6u MHz\n",
+ freq/1000000, freq%1000000);
+ tb_ticks_per_jiffy = freq / HZ;
+ tb_to_us = mulhwu_scale_factor(freq, 1000000);
}
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S
index d40a54cf1..627cd7a2a 100644
--- a/arch/ppc/kernel/entry.S
+++ b/arch/ppc/kernel/entry.S
@@ -30,6 +30,7 @@
#include <linux/errno.h>
#include <linux/sys.h>
#include <linux/config.h>
+#include "mol.h"
#undef SHOW_SYSCALLS
#undef SHOW_SYSCALLS_TASK
@@ -85,7 +86,7 @@ _GLOBAL(DoSyscall)
beq- 10f
cmpi 0,r0,0x6666 /* Special case for 'sys_rt_sigreturn' */
beq- 16f
- lwz r10,TASK_FLAGS(r2)
+ lwz r10,TASK_PTRACE(r2)
andi. r10,r10,PT_TRACESYS
bne- 50f
cmpli 0,r0,NR_syscalls
@@ -241,6 +242,13 @@ _GLOBAL(_switch)
/* XXX it would be nice to find a SPRGx for this on 6xx,7xx too */
lwz r9,PGDIR(r4) /* cache the page table root */
tophys(r9,r9) /* convert to phys addr */
+#ifdef CONFIG_8xx_CPU6
+ lis r6, cpu6_errata_word@h
+ ori r6, r6, cpu6_errata_word@l
+ li r5, 0x3980
+ stw r5, 8(r6)
+ lwz r5, 8(r6)
+#endif
mtspr M_TWB,r9 /* Update MMU base address */
tlbia
SYNC
@@ -349,21 +357,18 @@ ret_to_user_hook:
beq+ restore
li r3,0
addi r4,r1,STACK_FRAME_OVERHEAD
+ MOL_HOOK_MMU(8,r8)
bl do_signal
.globl do_signal_ret
do_signal_ret:
-restore:
- lwz r3,_CTR(r1)
- lwz r0,_LINK(r1)
- mtctr r3
- mtlr r0
+restore:
lwz r3,_XER(r1)
mtspr XER,r3
- REST_10GPRS(3, r1)
- REST_10GPRS(13, r1)
- REST_8GPRS(23, r1)
- REST_GPR(31, r1)
-
+ REST_10GPRS(9,r1)
+ REST_10GPRS(19,r1)
+ REST_2GPRS(29,r1)
+ REST_GPR(31,r1)
+
/* make sure we hard disable here, even if rtl is active, to protect
* SRR[01] and SPRG2 -- Cort
*/
@@ -376,12 +381,28 @@ restore:
lwz r0,_MSR(r1)
andi. r0,r0,MSR_PR
beq+ 1f
+#ifdef CONFIG_ALTIVEC
+ mfpvr r8 /* check if we are on a G4 */
+ srwi r8,r8,16
+ cmpwi r8,PVR_7400@h
+ bne 2f
+ lwz r0,THREAD+THREAD_VRSAVE(r2)
+ mtspr SPRN_VRSAVE,r0 /* if so, restore VRSAVE reg */
+2:
+#endif /* CONFIG_ALTIVEC */
addi r0,r1,INT_FRAME_SIZE /* size of frame */
stw r0,THREAD+KSP(r2) /* save kernel stack pointer */
- tophys(r2,r1)
- CLR_TOP32(r2)
- mtspr SPRG2,r2 /* phys exception stack pointer */
+ tophys(r8,r1)
+ CLR_TOP32(r8)
+ MOL_HOOK_MMU(9, r4) /* mod. r0,r2-r7, lr, ctr */
+ mtspr SPRG2,r8 /* phys exception stack pointer */
1:
+ lwz r3,_CTR(r1)
+ lwz r0,_LINK(r1)
+ mtctr r3
+ mtlr r0
+ REST_4GPRS(3, r1)
+ REST_2GPRS(7, r1)
lwz r0,_MSR(r1)
FIX_SRR1(r0,r2)
mtspr SRR1,r0
diff --git a/arch/ppc/kernel/feature.c b/arch/ppc/kernel/feature.c
index 4b63d5dc0..57599917a 100644
--- a/arch/ppc/kernel/feature.c
+++ b/arch/ppc/kernel/feature.c
@@ -24,6 +24,8 @@
#include <asm/errno.h>
#include <asm/ohare.h>
#include <asm/heathrow.h>
+#include <asm/keylargo.h>
+#include <asm/uninorth.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/feature.h>
@@ -34,6 +36,20 @@
#define MAX_FEATURE_OFFSET 0x100
#define FREG(c,r) (&(((c)->reg)[(r)>>2]))
+/* Keylargo reg. access. */
+#define KL_FCR(r) (keylargo_base + ((r) >> 2))
+#define KL_IN(r) (in_le32(KL_FCR(r)))
+#define KL_OUT(r,v) (out_le32(KL_FCR(r), (v)))
+#define KL_BIS(r,v) (KL_OUT((r), KL_IN(r) | (v)))
+#define KL_BIC(r,v) (KL_OUT((r), KL_IN(r) & ~(v)))
+
+/* Uni-N reg. access. Note that Uni-N regs are big endian */
+#define UN_REG(r) (uninorth_base + ((r) >> 2))
+#define UN_IN(r) (in_be32(UN_REG(r)))
+#define UN_OUT(r,v) (out_be32(UN_REG(r), (v)))
+#define UN_BIS(r,v) (UN_OUT((r), UN_IN(r) | (v)))
+#define UN_BIC(r,v) (UN_OUT((r), UN_IN(r) & ~(v)))
+
typedef struct feature_bit {
int reg; /* reg. offset from mac-io base */
unsigned int polarity; /* 0 = normal, 1 = inverse */
@@ -74,11 +90,45 @@ static fbit feature_bits_ohare_pbook[] = {
{0x38,0,0}, /* FEATURE_Airport_reset */
};
-/* Those bits are from a PowerBook. It's possible that desktop machines
- * based on heathrow need a different definition or some bits removed
+/* Those bits concern heathrow-based desktop machines (Beige G3s). We have removed
+ * the SCC related bits and init them once. They have proven to occasionally cause
+ * problems with the desktop units.
*/
static fbit feature_bits_heathrow[] = {
{0x38,0,0}, /* FEATURE_null */
+ {0x38,0,0}, /* FEATURE_Serial_reset */
+ {0x38,0,0}, /* FEATURE_Serial_enable */
+ {0x38,0,0}, /* FEATURE_Serial_IO_A */
+ {0x38,0,0}, /* FEATURE_Serial_IO_B */
+ {0x38,0,HRW_SWIM_ENABLE}, /* FEATURE_SWIM3_enable */
+ {0x38,0,HRW_MESH_ENABLE}, /* FEATURE_MESH_enable */
+ {0x38,0,HRW_IDE0_ENABLE}, /* FEATURE_IDE0_enable */
+ {0x38,1,HRW_IDE0_RESET_N}, /* FEATURE_IDE0_reset */
+ {0x38,0,HRW_IOBUS_ENABLE}, /* FEATURE_IOBUS_enable */
+ {0x38,1,0}, /* FEATURE_Mediabay_reset */
+ {0x38,1,0}, /* FEATURE_Mediabay_power */
+ {0x38,0,0}, /* FEATURE_Mediabay_PCI_enable */
+ {0x38,0,HRW_BAY_IDE_ENABLE}, /* FEATURE_IDE1_enable */
+ {0x38,1,HRW_IDE1_RESET_N}, /* FEATURE_IDE1_reset */
+ {0x38,0,0}, /* FEATURE_Mediabay_floppy_enable */
+ {0x38,0,HRW_BMAC_RESET}, /* FEATURE_BMac_reset */
+ {0x38,0,HRW_BMAC_IO_ENABLE}, /* FEATURE_BMac_IO_enable */
+ {0x38,1,0}, /* FEATURE_Modem_power */
+ {0x38,0,HRW_SLOW_SCC_PCLK}, /* FEATURE_Slow_SCC_PCLK */
+ {0x38,1,0}, /* FEATURE_Sound_Power */
+ {0x38,0,0}, /* FEATURE_Sound_CLK_Enable */
+ {0x38,0,0}, /* FEATURE_IDE2_enable */
+ {0x38,0,0}, /* FEATURE_IDE2_reset */
+ {0x38,0,0}, /* FEATURE_Mediabay_IDE_switch */
+ {0x38,0,0}, /* FEATURE_Mediabay_content */
+ {0x38,0,0}, /* FEATURE_Airport_reset */
+};
+
+/* Those bits concern heathrow-based PowerBooks (wallstreet/mainstreet).
+ * Heathrow-based desktop macs (Beige G3s) are _not_ handled here
+ */
+static fbit feature_bits_wallstreet[] = {
+ {0x38,0,0}, /* FEATURE_null */
{0x38,0,HRW_RESET_SCC}, /* FEATURE_Serial_reset */
{0x38,0,HRW_SCC_ENABLE}, /* FEATURE_Serial_enable */
{0x38,0,HRW_SCCA_IO}, /* FEATURE_Serial_IO_A */
@@ -145,32 +195,32 @@ static fbit feature_bits_paddington[] = {
*/
static fbit feature_bits_keylargo[] = {
{0x38,0,0}, /* FEATURE_null */
- {0x38,0,0}, /* FEATURE_Serial_reset */
- {0x38,0,0x00000054}, /* FEATURE_Serial_enable */
- {0x38,0,0}, /* FEATURE_Serial_IO_A */
- {0x38,0,0}, /* FEATURE_Serial_IO_B */
+ {0x38,0,KL0_SCC_RESET}, /* FEATURE_Serial_reset */
+ {0x38,0,KL0_SERIAL_ENABLE}, /* FEATURE_Serial_enable */
+ {0x38,0,KL0_SCC_A_INTF_ENABLE}, /* FEATURE_Serial_IO_A */
+ {0x38,0,KL0_SCC_B_INTF_ENABLE}, /* FEATURE_Serial_IO_B */
{0x38,0,0}, /* FEATURE_SWIM3_enable */
{0x38,0,0}, /* FEATURE_MESH_enable */
{0x3c,0,0}, /* FEATURE_IDE0_enable */
- {0x3c,1,0x01000000}, /* FEATURE_IDE0_reset */
+ {0x3c,1,KL1_EIDE0_RESET_N}, /* FEATURE_IDE0_reset */
{0x38,0,0}, /* FEATURE_IOBUS_enable */
{0x34,1,0x00000200}, /* FEATURE_Mediabay_reset */
{0x34,1,0x00000400}, /* FEATURE_Mediabay_power */
{0x38,0,0}, /* FEATURE_Mediabay_PCI_enable */
{0x3c,0,0x0}, /* FEATURE_IDE1_enable */
- {0x3c,1,0x08000000}, /* FEATURE_IDE1_reset */
+ {0x3c,1,KL1_EIDE1_RESET_N}, /* FEATURE_IDE1_reset */
{0x38,0,0}, /* FEATURE_Mediabay_floppy_enable */
{0x38,0,0}, /* FEATURE_BMac_reset */
{0x38,0,0}, /* FEATURE_BMac_IO_enable */
- {0x40,1,0x02000000}, /* FEATURE_Modem_power */
+ {0x40,1,KL2_MODEM_POWER_N}, /* FEATURE_Modem_power */
{0x38,0,0}, /* FEATURE_Slow_SCC_PCLK */
{0x38,0,0}, /* FEATURE_Sound_Power */
{0x38,0,0}, /* FEATURE_Sound_CLK_Enable */
{0x38,0,0}, /* FEATURE_IDE2_enable */
- {0x3c,1,0x40000000}, /* FEATURE_IDE2_reset */
- {0x34,0,0x00001000}, /* FEATURE_Mediabay_IDE_switch */
+ {0x3c,1,KL1_UIDE_RESET_N}, /* FEATURE_IDE2_reset */
+ {0x34,0,KL_MBCR_MBDEV_ENABLE}, /* FEATURE_Mediabay_IDE_switch */
{0x34,0,0x00000100}, /* FEATURE_Mediabay_content */
- {0x40,1,0x08000000}, /* FEATURE_Airport_reset */
+ {0x40,1,KL2_AIRPORT_RESET_N}, /* FEATURE_Airport_reset */
};
/* definition of a feature controller object */
@@ -190,6 +240,8 @@ feature_lookup_controller(struct device_node *device);
static void heathrow_prepare_for_sleep(struct feature_controller* ctrler);
static void heathrow_wakeup(struct feature_controller* ctrler);
+static void keylargo_init(void);
+static void uninorth_init(void);
static void core99_prepare_for_sleep(struct feature_controller* ctrler);
static void core99_wake_up(struct feature_controller* ctrler);
@@ -228,8 +280,15 @@ feature_init(void)
}
} else if (device_is_compatible(np, "paddington")) {
feature_add_controller(np, feature_bits_paddington);
+ } else if (machine_is_compatible("AAPL,PowerBook1998")) {
+ feature_add_controller(np, feature_bits_wallstreet);
} else {
- feature_add_controller(np, feature_bits_heathrow);
+ struct feature_controller* ctrler =
+ feature_add_controller(np, feature_bits_heathrow);
+ if (ctrler)
+ out_le32(FREG(ctrler,HEATHROW_FEATURE_REG),
+ in_le32(FREG(ctrler,HEATHROW_FEATURE_REG)) | HRW_DEFAULTS);
+
}
np = np->next;
}
@@ -249,14 +308,17 @@ feature_init(void)
np = find_devices("uni-n");
if (np && np->n_addrs > 0) {
uninorth_base = ioremap(np->addrs[0].address, 0x1000);
- rev = (u32 *)get_property(np, "device-rev", NULL);
- if (rev)
- uninorth_rev = *rev;
+ uninorth_rev = in_be32(UN_REG(UNI_N_VERSION));
}
if (uninorth_base && keylargo_base)
printk("Uni-N revision: %d, KeyLargo revision: %d\n",
uninorth_rev, keylargo_rev);
+ if (uninorth_base)
+ uninorth_init();
+ if (keylargo_base)
+ keylargo_init();
+
if (controller_count)
printk(KERN_INFO "Registered %d feature controller(s)\n", controller_count);
@@ -440,14 +502,21 @@ feature_set_gmac_power(struct device_node* device, int power)
if (!uninorth_base)
return;
if (power)
- out_le32(uninorth_base + 0x20/4,
- in_le32(uninorth_base + 0x20/4) | 0x02000000);
+ UN_BIS(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
else
- out_le32(uninorth_base + 0x20/4,
- in_le32(uninorth_base + 0x20/4) & ~0x02000000);
+ UN_BIC(UNI_N_CLOCK_CNTL, UNI_N_CLOCK_CNTL_GMAC);
udelay(20);
}
+void
+feature_set_gmac_phy_reset(struct device_node* device, int reset)
+{
+ if (!keylargo_base)
+ return;
+ out_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET), reset);
+ (void)in_8((volatile u8 *)KL_FCR(KL_GPIO_ETH_PHY_RESET));
+}
+
/* Pass the node of the correct controller, please */
void
feature_set_usb_power(struct device_node* device, int power)
@@ -460,6 +529,53 @@ feature_set_firewire_power(struct device_node* device, int power)
{
}
+/* Initialize the Core99 UniNorth host bridge and memory controller
+ */
+static void
+uninorth_init(void)
+{
+ struct device_node* gmac;
+ unsigned long actrl;
+
+ /* Set the arbitrer QAck delay according to what Apple does
+ */
+ actrl = in_be32(UN_REG(UNI_N_ARB_CTRL)) & ~UNI_N_ARB_CTRL_QACK_DELAY_MASK;
+ actrl |= ((uninorth_rev < 3) ? UNI_N_ARB_CTRL_QACK_DELAY105 : UNI_N_ARB_CTRL_QACK_DELAY)
+ << UNI_N_ARB_CTRL_QACK_DELAY_SHIFT;
+ UN_OUT(UNI_N_ARB_CTRL, actrl);
+
+ /*
+ * Turns OFF the gmac clock. The gmac driver will turn
+ * it back ON when the interface is enabled. This save
+ * power on portables.
+ *
+ * Note: We could also try to turn OFF the PHY. Since this
+ * has to be done by both the gmac driver and this code,
+ * I'll probably end-up moving some of this out of the
+ * modular gmac driver into a non-modular stub containing
+ * some basic PHY management and power management stuffs
+ */
+ gmac = find_devices("ethernet");
+
+ while(gmac) {
+ if (device_is_compatible(gmac, "gmac"))
+ break;
+ gmac = gmac->next;
+ }
+ if (gmac)
+ feature_set_gmac_power(gmac, 0);
+}
+
+/* Initialize the Core99 KeyLargo ASIC. Currently, we just make sure
+ * OpenPIC is enabled
+ */
+static void
+keylargo_init(void)
+{
+ KL_BIS(KEYLARGO_FCR2, KL2_MPIC_ENABLE);
+}
+
+#ifdef CONFIG_PMAC_PBOOK
void
feature_prepare_for_sleep(void)
{
@@ -506,27 +622,28 @@ feature_wake_up(void)
}
}
-static u32 save_fcr0;
-//static u32 save_fcr1;
-//static u32 save_fcr2;
+static u32 save_fcr[5];
static u32 save_mbcr;
static void
heathrow_prepare_for_sleep(struct feature_controller* ctrler)
{
save_mbcr = in_le32(FREG(ctrler, 0x34));
- save_fcr0 = in_le32(FREG(ctrler, 0x38));
+ save_fcr[0] = in_le32(FREG(ctrler, 0x38));
+ save_fcr[1] = in_le32(FREG(ctrler, 0x3c));
- out_le32(FREG(ctrler, 0x38), save_fcr0 & ~HRW_IOBUS_ENABLE);
+ out_le32(FREG(ctrler, 0x38), save_fcr[0] & ~HRW_IOBUS_ENABLE);
}
static void
heathrow_wakeup(struct feature_controller* ctrler)
{
- out_le32(FREG(ctrler, 0x38), save_fcr0);
+ out_le32(FREG(ctrler, 0x38), save_fcr[0]);
+ out_le32(FREG(ctrler, 0x3c), save_fcr[1]);
out_le32(FREG(ctrler, 0x34), save_mbcr);
-
- out_le32(FREG(ctrler, 0x38), save_fcr0 | HRW_IOBUS_ENABLE);
+ mdelay(1);
+ out_le32(FREG(ctrler, 0x38), save_fcr[0] | HRW_IOBUS_ENABLE);
+ mdelay(1);
}
static void
@@ -540,4 +657,4 @@ core99_wake_up(struct feature_controller* ctrler)
{
/* Not yet implemented */
}
-
+#endif /* CONFIG_PMAC_PBOOK */
diff --git a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c
index 7be4675c2..a01ff9eca 100644
--- a/arch/ppc/kernel/gemini_setup.c
+++ b/arch/ppc/kernel/gemini_setup.c
@@ -15,6 +15,7 @@
#include <linux/errno.h>
#include <linux/reboot.h>
#include <linux/pci.h>
+#include <linux/time.h>
#include <linux/kdev_t.h>
#include <linux/types.h>
#include <linux/major.h>
@@ -335,7 +336,7 @@ void __init gemini_init_IRQ(void)
#define gemini_rtc_write(val,x) (writeb((val),(GEMINI_RTC+(x))))
/* ensure that the RTC is up and running */
-void __init gemini_time_init(void)
+long __init gemini_time_init(void)
{
unsigned char reg;
@@ -346,6 +347,7 @@ void __init gemini_time_init(void)
gemini_rtc_write((reg & ~(M48T35_RTC_STOPPED)), M48T35_RTC_CONTROL);
gemini_rtc_write((reg | M48T35_RTC_SET), M48T35_RTC_CONTROL);
}
+ return 0;
}
#undef DEBUG_RTC
diff --git a/arch/ppc/kernel/hashtable.S b/arch/ppc/kernel/hashtable.S
index be86a1503..1129dd40e 100644
--- a/arch/ppc/kernel/hashtable.S
+++ b/arch/ppc/kernel/hashtable.S
@@ -27,6 +27,7 @@
#include <asm/processor.h>
#include <asm/page.h>
#include <linux/config.h>
+#include "mol.h"
/*
* Load a PTE into the hash table, if possible.
@@ -593,6 +594,11 @@ _GLOBAL(flush_hash_segments)
* flush_hash_page(unsigned context, unsigned long va)
*/
_GLOBAL(flush_hash_page)
+#ifdef CONFIG_MOL
+ mflr r10
+ MOL_HOOK_MMU(10, r6)
+ mtlr r10
+#endif
lis r6,Hash@ha
lwz r6,Hash@l(r6) /* hash table base */
cmpwi 0,r6,0 /* hash table in use? */
diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S
index 067581f5d..5d26e2917 100644
--- a/arch/ppc/kernel/head.S
+++ b/arch/ppc/kernel/head.S
@@ -31,6 +31,7 @@
#include <asm/page.h>
#include <linux/config.h>
#include <asm/mmu.h>
+#include "mol.h"
#ifdef CONFIG_APUS
#include <asm/amigappc.h>
@@ -78,7 +79,7 @@ CACHELINE_WORDS = 32
mtspr DBAT##n##L,RB; \
1:
#endif /* CONFIG_PPC64BRIDGE */
-
+
.text
.globl _stext
_stext:
@@ -162,8 +163,8 @@ __start:
/* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains
* the physical address we are running at, returned by prom_init()
*/
-__after_prom_start:
bl mmu_off
+__after_mmu_off:
bl clear_bats
bl flush_tlbs
#endif
@@ -202,15 +203,7 @@ __after_prom_start:
mr r26,r3
addis r4,r3,KERNELBASE@h /* current address of _start */
cmpwi 0,r4,0 /* are we already running at 0? */
- beq 2f /* assume it's OK if so */
- li r3,0
- mfmsr r0
- andi. r0,r0,MSR_DR /* MMU enabled? */
- beq relocate_kernel
- lis r3,KERNELBASE@h /* if so, are we */
- cmpw 0,r4,r3 /* already running at KERNELBASE? */
bne relocate_kernel
-2:
#endif /* CONFIG_APUS */
/*
* we now have the 1st 16M of ram mapped with the bats.
@@ -300,6 +293,17 @@ label: \
.long hdlr; \
.long ret_from_except
+#define STD_MOL_EXCEPTION(n, label, hdlr, hook) \
+ . = n; \
+label: \
+ EXCEPTION_PROLOG; \
+ MOL_HOOK(hook); \
+ addi r3,r1,STACK_FRAME_OVERHEAD; \
+ li r20,MSR_KERNEL; \
+ bl transfer_to_handler; \
+ .long hdlr; \
+ .long ret_from_except
+
/* System reset */
#ifdef CONFIG_SMP /* MVME/MTX and gemini start the secondary here */
#ifdef CONFIG_GEMINI
@@ -324,6 +328,7 @@ DataAccessCont:
DataAccess:
EXCEPTION_PROLOG
#endif /* CONFIG_PPC64BRIDGE */
+ MOL_HOOK(0)
mfspr r20,DSISR
andis. r0,r20,0xa470 /* weird error? */
bne 1f /* if not, try to put a PTE */
@@ -366,6 +371,7 @@ InstructionAccessCont:
InstructionAccess:
EXCEPTION_PROLOG
#endif /* CONFIG_PPC64BRIDGE */
+ MOL_HOOK(1)
andis. r0,r23,0x4000 /* no pte found? */
beq 1f /* if so, try to put a PTE */
mr r3,r22 /* into the hash table */
@@ -430,6 +436,7 @@ Alignment:
. = 0x700
ProgramCheck:
EXCEPTION_PROLOG
+ MOL_HOOK(2)
addi r3,r1,STACK_FRAME_OVERHEAD
li r20,MSR_KERNEL
rlwimi r20,r23,0,16,16 /* copy EE bit from saved MSR */
@@ -441,6 +448,7 @@ ProgramCheck:
. = 0x800
FPUnavailable:
EXCEPTION_PROLOG
+ MOL_HOOK_RESTORE(3)
bne load_up_fpu /* if from user, just load it up */
li r20,MSR_KERNEL
bl transfer_to_handler /* if from kernel, take a trap */
@@ -450,6 +458,7 @@ FPUnavailable:
. = 0x900
Decrementer:
EXCEPTION_PROLOG
+ MOL_HOOK(4)
addi r3,r1,STACK_FRAME_OVERHEAD
li r20,MSR_KERNEL
bl transfer_to_handler
@@ -473,12 +482,9 @@ SystemCall:
.long ret_from_except
/* Single step - not used on 601 */
- STD_EXCEPTION(0xd00, SingleStep, SingleStepException)
-
+ STD_MOL_EXCEPTION(0xd00, SingleStep, SingleStepException, 5)
STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
-#ifndef CONFIG_ALTIVEC
- STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
-#else
+
/*
* The Altivec unavailable trap is at 0x0f20. Foo.
* We effectively remap it to 0x3000.
@@ -493,15 +499,20 @@ trap_0f_cont:
.long ret_from_except
. = 0xf20
+#ifdef CONFIG_ALTIVEC
b AltiVecUnavailable
-#endif /* CONFIG_ALTIVEC */
-
+#endif
+Trap_0f:
+ EXCEPTION_PROLOG
+ b trap_0f_cont
+
/*
* Handle TLB miss for instruction on 603/603e.
* Note: we get an alternate set of r0 - r3 to use automatically.
*/
. = 0x1000
InstructionTLBMiss:
+ MOL_HOOK_TLBMISS( 14 )
/*
* r0: stored ctr
* r1: linux style pte ( later becomes ppc hardware pte )
@@ -568,6 +579,7 @@ InstructionAddressInvalid:
*/
. = 0x1100
DataLoadTLBMiss:
+ MOL_HOOK_TLBMISS( 15 )
/*
* r0: stored ctr
* r1: linux style pte ( later becomes ppc hardware pte )
@@ -633,6 +645,7 @@ DataAddressInvalid:
*/
. = 0x1200
DataStoreTLBMiss:
+ MOL_HOOK_TLBMISS( 16 )
/*
* r0: stored ctr
* r1: linux style pte ( later becomes ppc hardware pte )
@@ -674,7 +687,7 @@ DataStoreTLBMiss:
mtcrf 0x80,r3
rfi
- STD_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint)
+ STD_MOL_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint, 11)
STD_EXCEPTION(0x1400, SMI, SMIException)
STD_EXCEPTION(0x1500, Trap_15, UnknownException)
STD_EXCEPTION(0x1600, Trap_16, UnknownException)
@@ -687,7 +700,7 @@ DataStoreTLBMiss:
STD_EXCEPTION(0x1d00, Trap_1d, UnknownException)
STD_EXCEPTION(0x1e00, Trap_1e, UnknownException)
STD_EXCEPTION(0x1f00, Trap_1f, UnknownException)
- STD_EXCEPTION(0x2000, RunMode, RunModeException)
+ STD_MOL_EXCEPTION(0x2000, RunMode, RunModeException, 5)
STD_EXCEPTION(0x2100, Trap_21, UnknownException)
STD_EXCEPTION(0x2200, Trap_22, UnknownException)
STD_EXCEPTION(0x2300, Trap_23, UnknownException)
@@ -709,16 +722,12 @@ DataStoreTLBMiss:
#ifdef CONFIG_ALTIVEC
AltiVecUnavailable:
EXCEPTION_PROLOG
+ MOL_HOOK_RESTORE(12)
bne load_up_altivec /* if from user, just load it up */
li r20,MSR_KERNEL
bl transfer_to_handler /* if from kernel, take a trap */
.long KernelAltiVec
.long ret_from_except
-
-/* here are the bits of trap 0xf00 which got displaced */
-Trap_0f:
- EXCEPTION_PROLOG
- b trap_0f_cont
#endif /* CONFIG_ALTIVEC */
#ifdef CONFIG_PPC64BRIDGE
@@ -753,6 +762,14 @@ transfer_to_handler:
beq 2f
addi r24,r1,STACK_FRAME_OVERHEAD
stw r24,PT_REGS(r23)
+#ifdef CONFIG_ALTIVEC
+ mfpvr r24 /* check if we are on a G4 */
+ srwi r24,r24,16
+ cmpwi r24,PVR_7400@h
+ bne 2f
+ mfspr r22,SPRN_VRSAVE /* if so, save vrsave register value */
+ stw r22,THREAD_VRSAVE(r23)
+#endif /* CONFIG_ALTIVEC */
2: addi r2,r23,-THREAD /* set r2 to current */
tovirt(r2,r2)
mflr r23
@@ -771,6 +788,7 @@ transfer_to_handler:
lwz r24,0(r23) /* virtual address of handler */
lwz r23,4(r23) /* where to go when done */
FIX_SRR1(r20,r22)
+ MOL_HOOK(6)
mtspr SRR0,r24
mtspr SRR1,r20
mtlr r23
@@ -981,6 +999,11 @@ KernelAltiVec:
.globl giveup_altivec
giveup_altivec:
+#ifdef CONFIG_MOL
+ mflr r4
+ MOL_HOOK_MMU(13, r5)
+ mtlr r4
+#endif
mfmsr r5
oris r5,r5,MSR_VEC@h
SYNC
@@ -1017,6 +1040,11 @@ giveup_altivec:
*/
.globl giveup_fpu
giveup_fpu:
+#ifdef CONFIG_MOL
+ mflr r4
+ MOL_HOOK_MMU(7, r5)
+ mtlr r4
+#endif
mfmsr r5
ori r5,r5,MSR_FP
SYNC
@@ -1048,19 +1076,10 @@ giveup_fpu:
* the kernel image to physical address 0.
*/
relocate_kernel:
-#if 0 /* Is this still needed ? I don't think so. It breaks new
- * boot-with-mmu-off stuff
- */
- 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 */
-#endif
-7: addis r9,r26,klimit@ha /* fetch klimit */
+ addis r9,r26,klimit@ha /* fetch klimit */
lwz r25,klimit@l(r9)
addis r25,r25,-KERNELBASE@h
+ li r3,0 /* Destination base address */
li r6,0 /* Destination offset */
li r5,0x4000 /* # bytes of memory to copy */
bl copy_and_flush /* copy the first 0x4000 bytes */
@@ -1307,7 +1326,7 @@ enable_caches:
mfspr r9,PVR
rlwinm r9,r9,16,16,31
cmpi 0,r9,1
- beq 4f /* not needed for 601 */
+ beq 6f /* not needed for 601 */
mfspr r11,HID0
andi. r0,r11,HID0_DCE
ori r11,r11,HID0_ICE|HID0_DCE
@@ -1323,26 +1342,33 @@ enable_caches:
isync
cmpi 0,r9,4 /* check for 604 */
cmpi 1,r9,9 /* or 604e */
- cmpi 2,r9,10 /* or mach5 */
+ cmpi 2,r9,10 /* or mach5 / 604r */
cmpi 3,r9,8 /* check for 750 (G3) */
cmpi 4,r9,12 /* or 7400 (G4) */
cror 2,2,6
cror 2,2,10
bne 4f
- ori r11,r11,HID0_SIED|HID0_BHTE /* for 604[e], enable */
+ ori r11,r11,HID0_SIED|HID0_BHTE /* for 604[e|r], enable */
bne 2,5f
- ori r11,r11,HID0_BTCD
+ ori r11,r11,HID0_BTCD /* superscalar exec & br history tbl */
b 5f
4:
cror 14,14,18
bne 3,6f
- /* We should add ABE here if we want to use Store Gathering
- * and other nifty bridge features
+ /* for G3/G4:
+ * enable Store Gathering (SGE), Address Brodcast (ABE),
+ * Branch History Table (BHTE), Branch Target ICache (BTIC)
*/
- ori r11,r11,HID0_SGE|HID0_BHTE|HID0_BTIC /* for g3/g4, enable */
+ ori r11,r11,HID0_SGE | HID0_ABE | HID0_BHTE | HID0_BTIC
+ oris r11,r11,HID0_DPM@h /* enable dynamic power mgmt */
+ li r3,HID0_SPD
+ andc r11,r11,r3 /* clear SPD: enable speculative */
li r3,0
- mtspr ICTC,r3
-5: mtspr HID0,r11 /* superscalar exec & br history tbl */
+ mtspr ICTC,r3 /* Instruction Cache Throttling off */
+5: isync
+ mtspr HID0,r11
+ sync
+ isync
6: blr
/*
@@ -1548,12 +1574,11 @@ flush_tlbs:
blr
mmu_off:
- addi r4, r3, __after_prom_start - _start
+ addi r4, r3, __after_mmu_off - _start
mfmsr r3
andi. r0,r3,MSR_DR|MSR_IR /* MMU enabled? */
beqlr
- ori r3,r3,MSR_DR|MSR_IR
- xori r3,r3,MSR_DR|MSR_IR
+ andc r3,r3,r0
mtspr SRR0,r4
mtspr SRR1,r3
sync
@@ -1617,23 +1642,19 @@ setup_disp_bat:
mflr r8
bl reloc_offset
mtlr r8
- lis r8, disp_BATL@h
- ori r8, r8, disp_BATL@l
- add r8, r3, r8
- lwz r8, 0(r8)
- lis r11, disp_BATU@h
- ori r11, r11, disp_BATU@l
- add r11, r3, r11
- lwz r11, 0(r11)
- mtspr IBAT3L,r8
- mtspr IBAT3U,r11
+ addis r8,r3,disp_BAT@ha
+ addi r8,r8,disp_BAT@l
+ lwz r11,0(r8)
+ lwz r8,4(r8)
mfspr r9,PVR
rlwinm r9,r9,16,16,31 /* r9 = 1 for 601, 4 for 604 */
cmpi 0,r9,1
beq 1f
mtspr DBAT3L,r8
mtspr DBAT3U,r11
-1:
+ blr
+1: mtspr IBAT3L,r8
+ mtspr IBAT3U,r11
blr
#endif /* !defined(CONFIG_APUS) && defined(CONFIG_BOOTX_TEXT) */
@@ -1649,18 +1670,43 @@ setup_disp_bat:
*/
.globl m8260_gorom
m8260_gorom:
- li r5,MSR_KERNEL & ~(MSR_IR|MSR_DR)
- lis r6,2f@h
- addis r6,r6,-KERNELBASE@h
- ori r6,r6,2f@l
- mtspr SRR0,r6
- mtspr SRR1,r5
- rfi
+ mfmsr r0
+ rlwinm r0,r0,0,17,15 /* clear MSR_EE in r0 */
+ sync
+ mtmsr r0
+ sync
+ mfspr r11, HID0
+ lis r10, 0
+ ori r10,r10,HID0_ICE|HID0_DCE
+ andc r11, r11, r10
+ mtspr HID0, r11
+ isync
+ li r5, MSR_
+ lis r6,2f@h
+ addis r6,r6,-KERNELBASE@h
+ ori r6,r6,2f@l
+ mtspr SRR0,r6
+ mtspr SRR1,r5
+ isync
+ sync
+ rfi
2:
- mtlr r4
- blr
+ mtlr r4
+ blr
+#endif
+
+#ifdef CONFIG_MOL
+/*
+ * Mac-on-linux hook_table. Don't put this in the data section -
+ * the base address must be within the first 32KB of RAM.
+ */
+ .globl mol_interface
+mol_interface:
+ .long MOL_INTERFACE_VERSION
+ .fill 24,4,0 /* space for 24 hooks */
#endif
+
/*
* We put a few things here that have to be page-aligned.
* This stuff goes at the beginning of the data segment,
diff --git a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S
index a35f6e2a1..40579ce63 100644
--- a/arch/ppc/kernel/head_8xx.S
+++ b/arch/ppc/kernel/head_8xx.S
@@ -874,6 +874,13 @@ start_here:
lis r6, swapper_pg_dir@h
tophys(r6,r6)
ori r6, r6, swapper_pg_dir@l
+#ifdef CONFIG_8xx_CPU6
+ lis r4, cpu6_errata_word@h
+ ori r4, r4, cpu6_errata_word@l
+ li r3, 0x3980
+ stw r3, 12(r4)
+ lwz r3, 12(r4)
+#endif
mtspr M_TWB, r6
lis r4,2f@h
ori r4,r4,2f@l
@@ -940,9 +947,23 @@ start_here:
* ASID compare register with the new "context".
*/
_GLOBAL(set_context)
+#ifdef CONFIG_8xx_CPU6
+ lis r6, cpu6_errata_word@h
+ ori r6, r6, cpu6_errata_word@l
+ tophys (r4, r4)
+ li r7, 0x3980
+ stw r7, 12(r6)
+ lwz r7, 12(r6)
+ mtspr M_TWB, r4 /* Update MMU base address */
+ li r7, 0x3380
+ stw r7, 12(r6)
+ lwz r7, 12(r6)
+ mtspr M_CASID, r3 /* Update context */
+#else
mtspr M_CASID,r3 /* Update context */
tophys (r4, r4)
mtspr M_TWB, r4 /* and pgd */
+#endif
tlbia
SYNC
blr
@@ -966,6 +987,24 @@ m8xx_gorom:
2:
mtlr r4
blr
+
+#ifdef CONFIG_8xx_CPU6
+/* It's here because it is unique to the 8xx.
+ * It is important we get called with interrupts disabled. I used to
+ * do that, but it appears that all code that calls this already had
+ * interrupt disabled.
+ */
+ .globl set_dec_cpu6
+set_dec_cpu6:
+ lis r7, cpu6_errata_word@h
+ ori r7, r7, cpu6_errata_word@l
+ li r4, 0x2c00
+ stw r4, 8(r7)
+ lwz r4, 8(r7)
+ mtspr 22, r3 /* Update Decrementer */
+ SYNC
+ blr
+#endif
/*
* We put a few things here that have to be page-aligned.
@@ -991,3 +1030,9 @@ swapper_pg_dir:
cmd_line:
.space 512
+#ifdef CONFIG_8xx_CPU6
+ .globl cpu6_errata_word
+cpu6_errata_word:
+ .space 16
+#endif
+
diff --git a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c
index d29f7bd20..a363a0e34 100644
--- a/arch/ppc/kernel/idle.c
+++ b/arch/ppc/kernel/idle.c
@@ -286,6 +286,7 @@ void power_save(void)
case 6: /* 603e */
case 7: /* 603ev */
case 8: /* 750 */
+ case 12: /* 7400 */
save_flags(msr);
__cli();
if (!current->need_resched) {
diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c
index 64ef4b4dc..eef89f352 100644
--- a/arch/ppc/kernel/irq.c
+++ b/arch/ppc/kernel/irq.c
@@ -137,17 +137,21 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *)
if (!handler)
{
/* Free */
- for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next)
- {
- /* Found it - now free it */
- save_flags(flags);
- cli();
- *p = action->next;
- restore_flags(flags);
- irq_kfree(action);
- return 0;
- }
- return -ENOENT;
+ p = &irq_desc[irq].action;
+ while ((action = *p) != NULL && action->dev_id != dev_id)
+ p = &action->next;
+ if (action == NULL)
+ return -ENOENT;
+
+ /* Found it - now free it */
+ save_flags(flags);
+ cli();
+ *p = action->next;
+ if (irq_desc[irq].action == NULL)
+ disable_irq(irq);
+ restore_flags(flags);
+ irq_kfree(action);
+ return 0;
}
action = (struct irqaction *)
@@ -300,7 +304,7 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
}
}
-asmlinkage int do_IRQ(struct pt_regs *regs, int isfake)
+int do_IRQ(struct pt_regs *regs, int isfake)
{
int cpu = smp_processor_id();
int irq;
diff --git a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c
index 891b0ca44..6e006a867 100644
--- a/arch/ppc/kernel/m8260_setup.c
+++ b/arch/ppc/kernel/m8260_setup.c
@@ -112,11 +112,10 @@ void __init m8260_calibrate_decr(void)
bd_t *binfo = (bd_t *)__res;
int freq, divisor;
- freq = (binfo->bi_intfreq * 1000000);
- divisor = 16;
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
+ freq = (binfo->bi_busfreq * 1000000);
+ divisor = 4;
+ tb_ticks_per_jiffy = freq / HZ / divisor;
+ tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000);
}
/* The 8260 has an internal 1-second timer update register that
@@ -143,8 +142,20 @@ void
m8260_restart(char *cmd)
{
extern void m8260_gorom(bd_t *bi, uint addr);
+ uint startaddr;
- m8260_gorom(NULL, 0xff000100);
+ /* Most boot roms have a warmstart as the second instruction
+ * of the reset vector. If that doesn't work for you, change this
+ * or the reboot program to send a proper address.
+ */
+ startaddr = 0xff000104;
+
+ if (cmd != NULL) {
+ if (!strncmp(cmd, "startaddr=", 10))
+ startaddr = simple_strtoul(&cmd[10], NULL, 0);
+ }
+
+ m8260_gorom((uint)__pa(__res), startaddr);
}
void
diff --git a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c
index a00a8c452..7dc408a13 100644
--- a/arch/ppc/kernel/m8xx_setup.c
+++ b/arch/ppc/kernel/m8xx_setup.c
@@ -135,6 +135,13 @@ abort(void)
machine_restart(NULL);
}
+/* A place holder for time base interrupts, if they are ever enabled.
+*/
+void timebase_interrupt(int irq, void * dev, struct pt_regs * regs)
+{
+ printk("timebase_interrupt()\n");
+}
+
/* The decrementer counts at the system (internal) clock frequency divided by
* sixteen, or external oscillator divided by four. We force the processor
* to use system clock divided by sixteen.
@@ -160,35 +167,14 @@ void __init m8xx_calibrate_decr(void)
freq = fp*60; /* try to make freq/1e6 an integer */
divisor = 60;
printk("time_init: decrementer frequency = %d/%d\n", freq, divisor);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
-}
-
-/* A place holder for time base interrupts, if they are ever enabled.
-*/
-void timebase_interrupt(int irq, void * dev, struct pt_regs * regs)
-{
- printk("timebase_interrupt()\n");
-}
-
-/* The RTC on the MPC8xx is an internal register.
- * We want to protect this during power down, so we need to unlock,
- * modify, and re-lock.
- */
-static int
-m8xx_set_rtc_time(unsigned long time)
-{
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY;
- ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtc = time;
- ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY;
- return(0);
-}
-
-unsigned long __init
-m8xx_get_rtc_time(void)
-{
- /* First, unlock all of the registers we are going to modify.
+ tb_ticks_per_jiffy = freq / HZ / divisor;
+ tb_to_us = mulhwu_scale_factor(freq / divisor, 1000000);
+
+ /* Perform some more timer/timebase initialization. This used
+ * to be done elsewhere, but other changes caused it to get
+ * called more than once....that is a bad thing.
+ *
+ * First, unlock all of the registers we are going to modify.
* To protect them from corruption during power down, registers
* that are maintained by keep alive power are "locked". To
* modify these registers we have to write the key value to
@@ -219,9 +205,27 @@ m8xx_get_rtc_time(void)
((volatile immap_t *)IMAP_ADDR)->im_sit.sit_tbscr =
((mk_int_int_mask(DEC_INTERRUPT) << 8) |
(TBSCR_TBF | TBSCR_TBE));
+
if (request_8xxirq(DEC_INTERRUPT, timebase_interrupt, 0, "tbint", NULL) != 0)
panic("Could not allocate timer IRQ!");
+}
+/* The RTC on the MPC8xx is an internal register.
+ * We want to protect this during power down, so we need to unlock,
+ * modify, and re-lock.
+ */
+static int
+m8xx_set_rtc_time(unsigned long time)
+{
+ ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = KAPWR_KEY;
+ ((volatile immap_t *)IMAP_ADDR)->im_sit.sit_rtc = time;
+ ((volatile immap_t *)IMAP_ADDR)->im_sitk.sitk_rtck = ~KAPWR_KEY;
+ return(0);
+}
+
+unsigned long __init
+m8xx_get_rtc_time(void)
+{
/* Get time from the RTC.
*/
return((unsigned long)(((immap_t *)IMAP_ADDR)->im_sit.sit_rtc));
diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S
index 081dda7f3..e3826293b 100644
--- a/arch/ppc/kernel/misc.S
+++ b/arch/ppc/kernel/misc.S
@@ -24,12 +24,15 @@
#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
#define CACHE_LINE_SIZE 16
#define LG_CACHE_LINE_SIZE 4
+#define MAX_COPY_PREFETCH 1
#elif !defined(CONFIG_PPC64BRIDGE)
#define CACHE_LINE_SIZE 32
#define LG_CACHE_LINE_SIZE 5
+#define MAX_COPY_PREFETCH 4
#else
#define CACHE_LINE_SIZE 128
#define LG_CACHE_LINE_SIZE 7
+#define MAX_COPY_PREFETCH 1
#endif /* CONFIG_4xx || CONFIG_8xx */
.text
@@ -339,7 +342,15 @@ _GLOBAL(__flush_icache_page)
_GLOBAL(clear_page)
li r0,4096/CACHE_LINE_SIZE
mtctr r0
+#ifdef CONFIG_8xx
+ li r4, 0
+1: stw r4, 0(r3)
+ stw r4, 4(r3)
+ stw r4, 8(r3)
+ stw r4, 12(r3)
+#else
1: dcbz 0,r3
+#endif
addi r3,r3,CACHE_LINE_SIZE
bdnz 1b
blr
@@ -361,12 +372,31 @@ _GLOBAL(clear_page)
stwu r9,16(r3)
_GLOBAL(copy_page)
- li r0,4096/CACHE_LINE_SIZE
- mtctr r0
addi r3,r3,-4
addi r4,r4,-4
li r5,4
-1: dcbz r5,r3
+
+#ifndef CONFIG_8xx
+#if MAX_COPY_PREFETCH > 1
+ li r0,MAX_COPY_PREFETCH
+ li r11,4
+ mtctr r0
+11: dcbt r11,r4
+ addi r11,r11,CACHE_LINE_SIZE
+ bdnz 11b
+#else /* MAX_COPY_PREFETCH == 1 */
+ dcbt r5,r4
+ li r11,CACHE_LINE_SIZE+4
+#endif /* MAX_COPY_PREFETCH */
+#endif /* CONFIG_8xx */
+
+ li r0,4096/CACHE_LINE_SIZE
+ mtctr r0
+1:
+#ifndef CONFIG_8xx
+ dcbt r11,r4
+ dcbz r5,r3
+#endif
COPY_16_BYTES
#if CACHE_LINE_SIZE >= 32
COPY_16_BYTES
@@ -484,7 +514,7 @@ _GLOBAL(atomic_dec_and_test)
stwcx. r5,0,r3 /* Update with new value */
bne- 10b /* Retry if "reservation" (i.e. lock) lost */
cntlzw r3,r5
- srwi r3,r3,5
+ srwi r3,r3,5
blr
#endif /* 0 */
_GLOBAL(atomic_clear_mask)
@@ -629,48 +659,59 @@ _GLOBAL(_outsl_ns)
blr
/*
- * Extended precision shifts
+ * Extended precision shifts.
+ *
+ * Updated to be valid for shift counts from 0 to 63 inclusive.
+ * -- Gabriel
*
* R3/R4 has 64 bit value
* R5 has shift count
* result in R3/R4
*
- * ashrdi3: XXXYYY/ZZZAAA -> SSSXXX/YYYZZZ
- * ashldi3: XXXYYY/ZZZAAA -> YYYZZZ/AAA000
- * lshrdi3: XXXYYY/ZZZAAA -> 000XXX/YYYZZZ
+ * ashrdi3: arithmetic right shift (sign propagation)
+ * lshrdi3: logical right shift
+ * ashldi3: left shift
*/
_GLOBAL(__ashrdi3)
- li r6,32
- sub r6,r6,r5
- slw r7,r3,r6 /* isolate YYY */
- srw r4,r4,r5 /* isolate ZZZ */
- or r4,r4,r7 /* YYYZZZ */
- sraw r3,r3,r5 /* SSSXXX */
+ subfic r6,r5,32
+ srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count
+ addi r7,r5,32 # could be xori, or addi with -32
+ slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count)
+ rlwinm r8,r7,0,32 # t3 = (count < 32) ? 32 : 0
+ sraw r7,r3,r7 # t2 = MSW >> (count-32)
+ or r4,r4,r6 # LSW |= t1
+ slw r7,r7,r8 # t2 = (count < 32) ? 0 : t2
+ sraw r3,r3,r5 # MSW = MSW >> count
+ or r4,r4,r7 # LSW |= t2
blr
_GLOBAL(__ashldi3)
- li r6,32
- sub r6,r6,r5
- srw r7,r4,r6 /* isolate ZZZ */
- slw r4,r4,r5 /* AAA000 */
- slw r3,r3,r5 /* YYY--- */
- or r3,r3,r7 /* YYYZZZ */
+ subfic r6,r5,32
+ slw r3,r3,r5 # MSW = count > 31 ? 0 : MSW << count
+ addi r7,r5,32 # could be xori, or addi with -32
+ srw r6,r4,r6 # t1 = count > 31 ? 0 : LSW >> (32-count)
+ slw r7,r4,r7 # t2 = count < 32 ? 0 : LSW << (count-32)
+ or r3,r3,r6 # MSW |= t1
+ slw r4,r4,r5 # LSW = LSW << count
+ or r3,r3,r7 # MSW |= t2
blr
_GLOBAL(__lshrdi3)
- li r6,32
- sub r6,r6,r5
- slw r7,r3,r6 /* isolate YYY */
- srw r4,r4,r5 /* isolate ZZZ */
- or r4,r4,r7 /* YYYZZZ */
- srw r3,r3,r5 /* 000XXX */
+ subfic r6,r5,32
+ srw r4,r4,r5 # LSW = count > 31 ? 0 : LSW >> count
+ addi r7,r5,32 # could be xori, or addi with -32
+ slw r6,r3,r6 # t1 = count > 31 ? 0 : MSW << (32-count)
+ srw r7,r3,r7 # t2 = count < 32 ? 0 : MSW >> (count-32)
+ or r4,r4,r6 # LSW |= t1
+ srw r3,r3,r5 # MSW = MSW >> count
+ or r4,r4,r7 # LSW |= t2
blr
_GLOBAL(abs)
- cmpi 0,r3,0
- bge 10f
- neg r3,r3
-10: blr
+ srawi r4,r3,31
+ xor r3,r3,r4
+ sub r3,r3,r4
+ blr
_GLOBAL(_get_SP)
mr r3,r1 /* Close enough */
@@ -1217,6 +1258,6 @@ _GLOBAL(sys_call_table)
.long sys_pciconfig_iobase /* 200 */
.long sys_ni_syscall /* 201 - reserved - MacOnLinux - new */
.long sys_getdents64 /* 202 */
- .rept NR_syscalls-201
+ .rept NR_syscalls-(.-sys_call_table)/4
.long sys_ni_syscall
.endr
diff --git a/arch/ppc/kernel/mol.h b/arch/ppc/kernel/mol.h
new file mode 100644
index 000000000..6105867e1
--- /dev/null
+++ b/arch/ppc/kernel/mol.h
@@ -0,0 +1,68 @@
+/*
+ * arch/ppc/kernel/mol.h
+ *
+ * <mol.h>
+ *
+ * Mac-on-Linux hook macros
+ * <http://www.maconlinux.org>
+ *
+ * Copyright (C) 2000 Samuel Rydh (samuel@ibrium.se)
+ *
+ * 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
+ *
+ */
+
+#ifndef _PPC_KERNEL_MOL
+#define _PPC_KERNEL_MOL
+
+#include <linux/config.h>
+
+#ifdef CONFIG_MOL
+#define MOL_INTERFACE_VERSION 3
+
+#define MOL_HOOK(hook_num) \
+ lwz r0,(mol_interface + 4 * hook_num + 4)@l(0); \
+ cmpwi cr1,r0,0; \
+ beq+ cr1,777f; \
+ mtctr r0; \
+ bctrl; \
+777: lwz r0,GPR0(r21)
+
+#define MOL_HOOK_RESTORE(hook_num) \
+ mfcr r2; \
+ MOL_HOOK(hook_num); \
+ mtcrf 0x80,r2; \
+ lwz r2,_CTR(r21); \
+ mtctr r2; \
+ lwz r2,GPR2(r21)
+
+#define MOL_HOOK_MMU(hook_num, scr) \
+ lis scr,(mol_interface + 4 * hook_num + 4)@ha; \
+ lwz scr,(mol_interface + 4 * hook_num + 4)@l(scr); \
+ cmpwi cr1,scr,0; \
+ beq+ cr1,778f; \
+ mtctr scr; \
+ bctrl; \
+778:
+
+#define MOL_HOOK_TLBMISS(hook_num) \
+ lwz r0,(mol_interface + 4 * hook_num + 4)@l(0); \
+ cmpwi r0,0; \
+ beq+ 779f; \
+ mflr r3; \
+ mtlr r0; \
+ blrl; \
+ mtlr r3; \
+779:
+
+#else
+#define MOL_HOOK(num)
+#define MOL_HOOK_RESTORE(num)
+#define MOL_HOOK_MMU(num, scr)
+#define MOL_HOOK_TLBMISS(num)
+#endif
+
+
+#endif /* _PPC_KERNEL_MOL */
diff --git a/arch/ppc/kernel/oak_setup.c b/arch/ppc/kernel/oak_setup.c
index 09e6e6e6f..ef5a7a0fe 100644
--- a/arch/ppc/kernel/oak_setup.c
+++ b/arch/ppc/kernel/oak_setup.c
@@ -231,10 +231,11 @@ oak_halt(void)
/*
* Document me.
*/
-void __init
+long __init
oak_time_init(void)
{
/* XXX - Implement me */
+ return 0;
}
/*
diff --git a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c
index 416137934..5ca365b1c 100644
--- a/arch/ppc/kernel/open_pic.c
+++ b/arch/ppc/kernel/open_pic.c
@@ -100,7 +100,7 @@ struct hw_interrupt_type open_pic = {
#ifdef CONFIG_SMP
void openpic_ipi_action(int cpl, void *dev_id, struct pt_regs *regs)
{
- smp_message_recv(cpl-OPENPIC_VEC_IPI);
+ smp_message_recv(cpl-OPENPIC_VEC_IPI, regs);
}
#endif /* CONFIG_SMP */
@@ -262,11 +262,11 @@ void __init openpic_init(int main_pic)
int j, pri;
pri = strcmp(np->name, "programmer-switch") ? 2 : 7;
for (j=0;j<np->n_intrs;j++) {
- openpic_initirq( np->intrs[j].line,
- pri,
- np->intrs[j].line,
- 0,
- np->intrs[j].sense);
+ openpic_initirq(np->intrs[j].line,
+ pri,
+ np->intrs[j].line,
+ 0,
+ np->intrs[j].sense);
if (np->intrs[j].sense)
irq_desc[np->intrs[j].line].status = IRQ_LEVEL;
}
diff --git a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c
index 6233e5f9b..84faa0e1d 100644
--- a/arch/ppc/kernel/pci.c
+++ b/arch/ppc/kernel/pci.c
@@ -25,7 +25,13 @@
#include "pci.h"
-static void __init pcibios_claim_resources(struct list_head *);
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
unsigned long isa_io_base = 0;
unsigned long isa_mem_base = 0;
@@ -70,59 +76,280 @@ struct pci_ops generic_pci_ops =
generic_pcibios_write_dword
};
-void __init pcibios_init(void)
-{
- printk("PCI: Probing PCI hardware\n");
- pci_scan_bus(0, &generic_pci_ops, NULL);
- if (ppc_md.pcibios_fixup)
- ppc_md.pcibios_fixup();
- pcibios_claim_resources(&pci_root_buses);
-}
-void __init
-pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
+
+void pcibios_update_resource(struct pci_dev *dev, struct resource *root,
+ struct resource *res, int resource)
{
- 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;
+ u32 new, check;
+ int reg;
+
+ new = res->start | (res->flags & PCI_REGION_FLAG_MASK);
+ if (resource < 6) {
+ reg = PCI_BASE_ADDRESS_0 + 4*resource;
+ } else if (resource == PCI_ROM_RESOURCE) {
+ res->flags |= PCI_ROM_ADDRESS_ENABLE;
+ reg = dev->rom_base_reg;
+ } else {
+ /* Somebody might have asked allocation of a non-standard resource */
+ return;
+ }
+
+ pci_write_config_dword(dev, reg, new);
+ pci_read_config_dword(dev, reg, &check);
+ if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) {
+ printk(KERN_ERR "PCI: Error while updating region "
+ "%s/%d (%08x != %08x)\n", dev->slot_name, resource,
+ new, check);
+ }
}
-unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
- unsigned long start, unsigned long size)
+/*
+ * We need to avoid collisions with `mirrored' VGA ports
+ * and other strange ISA hardware, so we always want the
+ * addresses to be allocated in the 0x000-0x0ff region
+ * modulo 0x400.
+ *
+ * Why? Because some silly external IO cards only decode
+ * the low 10 bits of the IO address. The 0x00-0xff region
+ * is reserved for motherboard devices that decode all 16
+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
+ * but we want to try to avoid allocating at 0x2900-0x2bff
+ * which might have be mirrored at 0x0100-0x03ff..
+ */
+void
+pcibios_align_resource(void *data, struct resource *res, unsigned long size)
{
- return start;
+ struct pci_dev *dev = data;
+
+ if (res->flags & IORESOURCE_IO) {
+ unsigned long start = res->start;
+
+ if (size > 0x100) {
+ printk(KERN_ERR "PCI: I/O Region %s/%d too large"
+ " (%ld bytes)\n", dev->slot_name,
+ dev->resource - res, size);
+ }
+
+ if (start & 0x300) {
+ start = (start + 0x3ff) & ~0x3ff;
+ res->start = start;
+ }
+ }
}
-static void __init pcibios_claim_resources(struct list_head *bus_list)
+
+/*
+ * Handle resources of PCI devices. If the world were perfect, we could
+ * just allocate all the resource regions and do nothing more. It isn't.
+ * On the other hand, we cannot just re-allocate all devices, as it would
+ * require us to know lots of host bridge internals. So we attempt to
+ * keep as much of the original configuration as possible, but tweak it
+ * when it's found to be wrong.
+ *
+ * Known BIOS problems we have to work around:
+ * - I/O or memory regions not configured
+ * - regions configured, but not enabled in the command register
+ * - bogus I/O addresses above 64K used
+ * - expansion ROMs left enabled (this may sound harmless, but given
+ * the fact the PCI specs explicitly allow address decoders to be
+ * shared between expansion ROMs and other resource regions, it's
+ * at least dangerous)
+ *
+ * Our solution:
+ * (1) Allocate resources for all buses behind PCI-to-PCI bridges.
+ * This gives us fixed barriers on where we can allocate.
+ * (2) Allocate resources for all enabled devices. If there is
+ * a collision, just mark the resource as unallocated. Also
+ * disable expansion ROMs during this step.
+ * (3) Try to allocate resources for disabled devices. If the
+ * resources were assigned correctly, everything goes well,
+ * if they weren't, they won't disturb allocation of other
+ * resources.
+ * (4) Assign new addresses to resources which were either
+ * not configured at all or misconfigured. If explicitly
+ * requested by the user, configure expansion ROM address
+ * as well.
+ */
+
+static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
{
- struct list_head *ln, *dn;
+ struct list_head *ln;
struct pci_bus *bus;
struct pci_dev *dev;
int idx;
+ struct resource *r, *pr;
+ /* Depth-First Search on bus tree */
for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
bus = pci_bus_b(ln);
- for (dn=bus->devices.next; dn != &bus->devices; dn=dn->next) {
- dev = pci_dev_b(dn);
- for (idx = 0; idx < PCI_NUM_RESOURCES; idx++)
- {
- struct resource *r = &dev->resource[idx];
- struct resource *pr;
+ if ((dev = bus->self)) {
+ for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
+ r = &dev->resource[idx];
if (!r->start)
continue;
pr = pci_find_parent_resource(dev, r);
if (!pr || request_resource(pr, r) < 0)
- {
- printk(KERN_ERR "PCI: Address space collision on region %d of device %s\n", idx, dev->name);
- /* We probably should disable the region, shouldn't we? */
+ printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name);
+ }
+ }
+ pcibios_allocate_bus_resources(&bus->children);
+ }
+}
+
+static void __init pcibios_allocate_resources(int pass)
+{
+ struct pci_dev *dev;
+ int idx, disabled;
+ u16 command;
+ struct resource *r, *pr;
+
+ pci_for_each_dev(dev) {
+ pci_read_config_word(dev, PCI_COMMAND, &command);
+ for(idx = 0; idx < 6; idx++) {
+ r = &dev->resource[idx];
+ if (r->parent) /* Already allocated */
+ continue;
+ if (!r->start) /* Address not assigned at all */
+ continue;
+ if (r->end == 0xffffffff) {
+ /* LongTrail OF quirk: unassigned */
+ DBG("PCI: Resource %08lx-%08lx was unassigned\n", r->start, r->end);
+ r->end -= r->start;
+ r->start = 0;
+ continue;
+ }
+
+ if (r->flags & IORESOURCE_IO)
+ disabled = !(command & PCI_COMMAND_IO);
+ else
+ disabled = !(command & PCI_COMMAND_MEMORY);
+ if (pass == disabled) {
+ DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
+ r->start, r->end, r->flags, disabled, pass);
+ pr = pci_find_parent_resource(dev, r);
+ if (!pr || request_resource(pr, r) < 0) {
+ printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, dev->slot_name);
+ /* We'll assign a new address later */
+ r->end -= r->start;
+ r->start = 0;
}
}
}
- pcibios_claim_resources(&bus->children);
+ if (!pass) {
+ r = &dev->resource[PCI_ROM_RESOURCE];
+ if (r->flags & PCI_ROM_ADDRESS_ENABLE) {
+ /* Turn the ROM off, leave the resource region, but keep it unregistered. */
+ u32 reg;
+ DBG("PCI: Switching off ROM of %s\n", dev->slot_name);
+ r->flags &= ~PCI_ROM_ADDRESS_ENABLE;
+ pci_read_config_dword(dev, dev->rom_base_reg, &reg);
+ pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
+ }
+ }
+ }
+}
+
+static void __init pcibios_assign_resources(void)
+{
+ struct pci_dev *dev;
+ int idx;
+ struct resource *r;
+
+ pci_for_each_dev(dev) {
+ int class = dev->class >> 8;
+
+ /* Don't touch classless devices and host bridges */
+ if (!class || class == PCI_CLASS_BRIDGE_HOST)
+ continue;
+
+ for(idx=0; idx<6; idx++) {
+ r = &dev->resource[idx];
+
+ /*
+ * Don't touch IDE controllers and I/O ports of video cards!
+ */
+ if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
+ (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
+ continue;
+
+ /*
+ * We shall assign a new address to this resource, either because
+ * the BIOS forgot to do so or because we have decided the old
+ * address was unusable for some reason.
+ */
+ if (!r->start && r->end)
+ pci_assign_resource(dev, idx);
+ }
+
+ if (0) { /* don't assign ROMs */
+ r = &dev->resource[PCI_ROM_RESOURCE];
+ r->end -= r->start;
+ r->start = 0;
+ if (r->end)
+ pci_assign_resource(dev, PCI_ROM_RESOURCE);
+ }
}
}
+
+int pcibios_enable_resources(struct pci_dev *dev)
+{
+ u16 cmd, old_cmd;
+ int idx;
+ struct resource *r;
+
+ pci_read_config_word(dev, PCI_COMMAND, &cmd);
+ old_cmd = cmd;
+ for(idx=0; idx<6; idx++) {
+ r = &dev->resource[idx];
+ if (!r->start && r->end) {
+ printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", dev->slot_name);
+ return -EINVAL;
+ }
+ if (r->flags & IORESOURCE_IO)
+ cmd |= PCI_COMMAND_IO;
+ if (r->flags & IORESOURCE_MEM)
+ cmd |= PCI_COMMAND_MEMORY;
+ }
+ if (dev->resource[PCI_ROM_RESOURCE].start)
+ cmd |= PCI_COMMAND_MEMORY;
+ if (cmd != old_cmd) {
+ printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
+ pci_write_config_word(dev, PCI_COMMAND, cmd);
+ }
+ return 0;
+}
+
+
+
+void __init pcibios_init(void)
+{
+ printk("PCI: Probing PCI hardware\n");
+ pci_scan_bus(0, &generic_pci_ops, NULL);
+ if (ppc_md.pcibios_fixup)
+ ppc_md.pcibios_fixup();
+ pcibios_allocate_bus_resources(&pci_root_buses);
+ pcibios_allocate_resources(0);
+ pcibios_allocate_resources(1);
+ pcibios_assign_resources();
+}
+
+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;
+}
+
void __init pcibios_fixup_bus(struct pci_bus *bus)
{
if ( ppc_md.pcibios_fixup_bus )
@@ -134,21 +361,7 @@ char __init *pcibios_setup(char *str)
return str;
}
-/* the next two are stolen from the alpha port... */
-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);
-}
-
+/* the next one is stolen from the alpha port... */
void __init
pcibios_update_irq(struct pci_dev *dev, int irq)
{
@@ -156,11 +369,6 @@ pcibios_update_irq(struct pci_dev *dev, int irq)
/* XXX FIXME - update OF device tree node interrupt property */
}
-void __init
-pcibios_align_resource(void *data, struct resource *res, unsigned long size)
-{
-}
-
int pcibios_enable_device(struct pci_dev *dev)
{
u16 cmd, old_cmd;
@@ -188,114 +396,26 @@ int pcibios_enable_device(struct pci_dev *dev)
return 0;
}
-/*
- * Those syscalls are derived from the Alpha versions, they
- * allow userland apps to retreive the per-device iobase and
- * mem-base. They also provide wrapper for userland to do
- * config space accesses.
- * The "host_number" returns the number of the Uni-N sub bridge
- */
-
-asmlinkage int
-sys_pciconfig_read(unsigned long bus, unsigned long dfn,
- unsigned long off, unsigned long len,
- unsigned char *buf)
-{
- unsigned char ubyte;
- unsigned short ushort;
- unsigned int uint;
- long err = 0;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (!pcibios_present())
- return -ENOSYS;
-
- switch (len) {
- case 1:
- err = pcibios_read_config_byte(bus, dfn, off, &ubyte);
- put_user(ubyte, buf);
- break;
- case 2:
- err = pcibios_read_config_word(bus, dfn, off, &ushort);
- put_user(ushort, (unsigned short *)buf);
- break;
- case 4:
- err = pcibios_read_config_dword(bus, dfn, off, &uint);
- put_user(uint, (unsigned int *)buf);
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
-}
-
-asmlinkage int
-sys_pciconfig_write(unsigned long bus, unsigned long dfn,
- unsigned long off, unsigned long len,
- unsigned char *buf)
-{
- unsigned char ubyte;
- unsigned short ushort;
- unsigned int uint;
- long err = 0;
-
- if (!capable(CAP_SYS_ADMIN))
- return -EPERM;
- if (!pcibios_present())
- return -ENOSYS;
-
- switch (len) {
- case 1:
- err = get_user(ubyte, buf);
- if (err)
- break;
- err = pcibios_write_config_byte(bus, dfn, off, ubyte);
- if (err != PCIBIOS_SUCCESSFUL) {
- err = -EFAULT;
- }
- break;
- case 2:
- err = get_user(ushort, (unsigned short *)buf);
- if (err)
- break;
- err = pcibios_write_config_word(bus, dfn, off, ushort);
- if (err != PCIBIOS_SUCCESSFUL) {
- err = -EFAULT;
- }
- break;
- case 4:
- err = get_user(uint, (unsigned int *)buf);
- if (err)
- break;
- err = pcibios_write_config_dword(bus, dfn, off, uint);
- if (err != PCIBIOS_SUCCESSFUL) {
- err = -EFAULT;
- }
- break;
- default:
- err = -EINVAL;
- break;
- }
- return err;
-}
-
void *
-pci_dev_io_base(unsigned char bus, unsigned char devfn)
+pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical)
{
- /* Defaults to old way */
- if (!ppc_md.pci_dev_io_base)
- return pci_io_base(bus);
- return ppc_md.pci_dev_io_base(bus, devfn);
+ if (!ppc_md.pci_dev_io_base) {
+ /* Please, someone fix this for non-pmac machines, we
+ * need either the virtual or physical PCI IO base
+ */
+ return 0;
+ }
+ return ppc_md.pci_dev_io_base(bus, devfn, physical);
}
void *
pci_dev_mem_base(unsigned char bus, unsigned char devfn)
{
/* Default memory base is 0 (1:1 mapping) */
- if (!ppc_md.pci_dev_mem_base)
+ if (!ppc_md.pci_dev_mem_base) {
+ /* Please, someone fix this for non-pmac machines.*/
return 0;
+ }
return ppc_md.pci_dev_mem_base(bus, devfn);
}
@@ -318,15 +438,20 @@ pci_dev_root_bridge(unsigned char bus, unsigned char devfn)
asmlinkage long
sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn)
{
+ long result = -EOPNOTSUPP;
+
switch (which) {
case IOBASE_BRIDGE_NUMBER:
return (long)pci_dev_root_bridge(bus, devfn);
case IOBASE_MEMORY:
return (long)pci_dev_mem_base(bus, devfn);
case IOBASE_IO:
- return (long)pci_dev_io_base(bus, devfn);
+ result = (long)pci_dev_io_base(bus, devfn, 1);
+ if (result == 0)
+ result = -EOPNOTSUPP;
+ break;
}
- return -EOPNOTSUPP;
+ return result;
}
diff --git a/arch/ppc/kernel/pmac_backlight.c b/arch/ppc/kernel/pmac_backlight.c
index 8c6244632..30ad5f416 100644
--- a/arch/ppc/kernel/pmac_backlight.c
+++ b/arch/ppc/kernel/pmac_backlight.c
@@ -41,16 +41,16 @@ register_backlight_controller(struct backlight_controller *ctrler, void *data, c
#ifdef CONFIG_ADB_PMU
/* Special case for the old PowerBook since I can't test on it */
- if ((machine_is_compatible("AAPL,3400/2400") || machine_is_compatible("AAPL,3500")
- || machine_is_compatible("AAPL,PowerBook1998")
- || machine_is_compatible("AAPL,PowerBook1999"))
- && !strcmp(type, "pmu"))
+ backlight_autosave = machine_is_compatible("AAPL,3400/2400")
+ || machine_is_compatible("AAPL,3500");
+ if ((backlight_autosave
+ || machine_is_compatible("AAPL,PowerBook1998")
+ || machine_is_compatible("PowerBook1,1"))
+ && !strcmp(type, "pmu"))
valid = 1;
- else
#endif
- {
- if (bk_node)
- prop = get_property(bk_node, "backlight-control", NULL);
+ if (bk_node) {
+ prop = get_property(bk_node, "backlight-control", NULL);
if (prop && !strncmp(prop, type, strlen(type)))
valid = 1;
}
@@ -70,8 +70,6 @@ register_backlight_controller(struct backlight_controller *ctrler, void *data, c
}
#ifdef CONFIG_ADB_PMU
- backlight_autosave = machine_is_compatible("AAPL,3400/2400")
- || machine_is_compatible("AAPL,3500");
if (backlight_autosave) {
struct adb_request req;
pmu_request(&req, NULL, 2, 0xd9, 0);
diff --git a/arch/ppc/kernel/pmac_nvram.c b/arch/ppc/kernel/pmac_nvram.c
index d8de113ec..1c4c1eea1 100644
--- a/arch/ppc/kernel/pmac_nvram.c
+++ b/arch/ppc/kernel/pmac_nvram.c
@@ -312,17 +312,18 @@ pmac_nvram_update(void)
__openfirmware
unsigned char nvram_read_byte(int addr)
{
- struct adb_request req;
-
switch (nvram_naddrs) {
#ifdef CONFIG_ADB_PMU
- case -1:
+ case -1: {
+ struct adb_request req;
+
if (pmu_request(&req, NULL, 3, PMU_READ_NVRAM,
(addr >> 8) & 0xff, addr & 0xff))
break;
while (!req.complete)
pmu_poll();
return req.reply[1];
+ }
#endif
case 1:
if (is_core_99)
@@ -339,17 +340,18 @@ unsigned char nvram_read_byte(int addr)
__openfirmware
void nvram_write_byte(unsigned char val, int addr)
{
- struct adb_request req;
-
switch (nvram_naddrs) {
#ifdef CONFIG_ADB_PMU
- case -1:
+ case -1: {
+ struct adb_request req;
+
if (pmu_request(&req, NULL, 4, PMU_WRITE_NVRAM,
(addr >> 8) & 0xff, addr & 0xff, val))
break;
while (!req.complete)
pmu_poll();
break;
+ }
#endif
case 1:
if (is_core_99) {
diff --git a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c
index ced029722..8f7b3d7c2 100644
--- a/arch/ppc/kernel/pmac_pci.c
+++ b/arch/ppc/kernel/pmac_pci.c
@@ -35,6 +35,7 @@ struct uninorth_data {
volatile unsigned int* cfg_addr;
volatile unsigned int* cfg_data;
void* iobase;
+ unsigned long iobase_phys;
};
static struct uninorth_data uninorth_bridges[3];
@@ -133,15 +134,20 @@ pmac_pci_dev_root_bridge(unsigned char bus, unsigned char dev_fn)
__pmac
void *
-pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn)
+pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical)
{
- int bridge;
- if (uninorth_count == 0)
- return pci_io_base(bus);
- bridge = pmac_pci_dev_root_bridge(bus, devfn);
- if (bridge == -1)
- return pci_io_base(bus);
- return uninorth_bridges[bridge].iobase;
+ int bridge = -1;
+ if (uninorth_count != 0)
+ bridge = pmac_pci_dev_root_bridge(bus, devfn);
+ if (bridge == -1) {
+ struct bridge_data *bp;
+
+ if (bus > max_bus || (bp = bridges[bus]) == 0)
+ return 0;
+ return physical ? (void *) bp->io_base_phys : bp->io_base;
+ }
+ return physical ? (void *) uninorth_bridges[bridge].iobase_phys
+ : uninorth_bridges[bridge].iobase;
}
__pmac
@@ -649,7 +655,9 @@ static void __init add_bridges(struct device_node *dev)
uninorth_bridges[i].cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
uninorth_bridges[i].cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
uninorth_bridges[i].node = dev;
- uninorth_bridges[i].iobase = (void *)addr->address;
+ uninorth_bridges[i].iobase_phys = addr->address;
+ /* is 0x10000 enough for io space ? */
+ uninorth_bridges[i].iobase = (void *)ioremap(addr->address, 0x10000);
/* XXX This is the bridge with the PCI expansion bus. This is also the
* address of the bus that will receive type 1 config accesses and io
* accesses. Appears to be correct for iMac DV and G4 Sawtooth too.
@@ -667,14 +675,15 @@ static void __init add_bridges(struct device_node *dev)
if (device_is_compatible(dev, "uni-north")) {
bp->cfg_addr = 0;
bp->cfg_data = 0;
- /* is 0x10000 enough for io space ? */
- bp->io_base = (void *)ioremap(addr->address, 0x10000);
+ bp->io_base = uninorth_bridges[uninorth_count-1].iobase;
+ bp->io_base_phys = uninorth_bridges[uninorth_count-1].iobase_phys;
} else if (strcmp(dev->name, "pci") == 0) {
/* XXX assume this is a mpc106 (grackle) */
bp->cfg_addr = (volatile unsigned int *)
ioremap(0xfec00000, 0x1000);
bp->cfg_data = (volatile unsigned char *)
ioremap(0xfee00000, 0x1000);
+ bp->io_base_phys = 0xfe000000;
bp->io_base = (void *) ioremap(0xfe000000, 0x20000);
if (machine_is_compatible("AAPL,PowerBook1998"))
grackle_set_loop_snoop(bp, 1);
@@ -687,6 +696,7 @@ static void __init add_bridges(struct device_node *dev)
ioremap(addr->address + 0x800000, 0x1000);
bp->cfg_data = (volatile unsigned char *)
ioremap(addr->address + 0xc00000, 0x1000);
+ bp->io_base_phys = addr->address;
bp->io_base = (void *) ioremap(addr->address, 0x10000);
}
if (isa_io_base == 0)
diff --git a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c
index e0e654305..efd767482 100644
--- a/arch/ppc/kernel/pmac_pic.c
+++ b/arch/ppc/kernel/pmac_pic.c
@@ -204,17 +204,12 @@ pmac_get_irq(struct pt_regs *regs)
unsigned long bits = 0;
#ifdef CONFIG_SMP
- void pmac_smp_message_recv(void);
+ void pmac_smp_message_recv(struct pt_regs *);
/* IPI's are a hack on the powersurge -- Cort */
if ( smp_processor_id() != 0 )
{
-#ifdef CONFIG_XMON
- static int xmon_2nd;
- if (xmon_2nd)
- xmon(regs);
-#endif
- pmac_smp_message_recv();
+ pmac_smp_message_recv(regs);
return -2; /* ignore, already handled */
}
#endif /* CONFIG_SMP */
diff --git a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c
index 658d7c226..b5bf03abc 100644
--- a/arch/ppc/kernel/pmac_setup.c
+++ b/arch/ppc/kernel/pmac_setup.c
@@ -68,7 +68,7 @@
#undef SHOW_GATWICK_IRQS
-extern void pmac_time_init(void);
+extern long pmac_time_init(void);
extern unsigned long pmac_get_rtc_time(void);
extern int pmac_set_rtc_time(unsigned long nowtime);
extern void pmac_read_rtc_time(void);
@@ -77,24 +77,29 @@ extern void pmac_setup_pci_ptrs(void);
extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
extern int mackbd_getkeycode(unsigned int scancode);
-extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
- char raw_mode);
-extern char mackbd_unexpected_up(unsigned char keycode);
+extern int mackbd_translate(unsigned char keycode, unsigned char *keycodep,
+ char raw_mode);
+extern int mackbd_unexpected_up(unsigned char keycode);
extern void mackbd_leds(unsigned char leds);
-extern void mackbd_init_hw(void);
+extern void __init mackbd_init_hw(void);
+extern int mac_hid_kbd_translate(unsigned char scancode, unsigned char *keycode,
+ char raw_mode);
+extern char mac_hid_kbd_unexpected_up(unsigned char keycode);
+extern void mac_hid_init_hw(void);
#ifdef CONFIG_MAGIC_SYSRQ
-unsigned char mackbd_sysrq_xlate[128];
+extern unsigned char mac_hid_kbd_sysrq_xlate[128];
+extern unsigned char pckbd_sysrq_xlate[128];
+extern unsigned char mackbd_sysrq_xlate[128];
#endif /* CONFIG_MAGIC_SYSRQ */
extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
extern int pckbd_getkeycode(unsigned int scancode);
extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
char raw_mode);
extern char pckbd_unexpected_up(unsigned char keycode);
-extern void pckbd_leds(unsigned char leds);
-extern void pckbd_init_hw(void);
+extern int keyboard_sends_linux_keycodes;
extern void pmac_nvram_update(void);
-extern void *pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn);
+extern void *pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical);
extern void *pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn);
extern int pmac_pci_dev_root_bridge(unsigned char bus, unsigned char devfn);
@@ -115,7 +120,6 @@ extern int pmac_newworld;
extern void zs_kgdb_hook(int tty_num);
static void ohare_init(void);
static void init_p2pbridge(void);
-static void init_uninorth(void);
#ifdef CONFIG_BOOTX_TEXT
void pmac_progress(char *s, unsigned short hex);
#endif
@@ -276,7 +280,6 @@ pmac_setup_arch(void)
pmac_find_bridges();
init_p2pbridge();
- init_uninorth();
/* Checks "l2cr-value" property in the registry */
if ( (_get_PVR() >> 16) == 8 || (_get_PVR() >> 16) == 12 ) {
@@ -372,31 +375,6 @@ static void __init ohare_init(void)
}
}
-static void __init
-init_uninorth(void)
-{
- /*
- * Turns OFF the gmac clock. The gmac driver will turn
- * it back ON when the interface is enabled. This save
- * power on portables.
- *
- * Note: We could also try to turn OFF the PHY. Since this
- * has to be done by both the gmac driver and this code,
- * I'll probably end-up moving some of this out of the
- * modular gmac driver into a non-modular stub containing
- * some basic PHY management and power management stuffs
- */
- struct device_node* gmac = find_devices("ethernet");
-
- while(gmac) {
- if (device_is_compatible(gmac, "gmac"))
- break;
- gmac = gmac->next;
- }
- if (gmac)
- feature_set_gmac_power(gmac, 0);
-}
-
extern char *bootpath;
extern char *bootdevice;
void *boot_host;
@@ -404,14 +382,15 @@ int boot_target;
int boot_part;
kdev_t boot_dev;
-extern void via_pmu_start(void);
-
void __init
pmac_init2(void)
{
#ifdef CONFIG_ADB_PMU
via_pmu_start();
#endif
+#ifdef CONFIG_ADB_CUDA
+ via_cuda_start();
+#endif
#ifdef CONFIG_PMAC_PBOOK
media_bay_init();
#endif
@@ -683,7 +662,26 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.pci_dev_mem_base = pmac_pci_dev_mem_base;
ppc_md.pci_dev_root_bridge = pmac_pci_dev_root_bridge;
-#if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD)
+#ifdef CONFIG_VT
+#ifdef CONFIG_INPUT_ADBHID
+ ppc_md.kbd_init_hw = mac_hid_init_hw;
+ ppc_md.kbd_translate = mac_hid_kbd_translate;
+ ppc_md.kbd_unexpected_up = mac_hid_kbd_unexpected_up;
+ ppc_md.kbd_setkeycode = 0;
+ ppc_md.kbd_getkeycode = 0;
+#ifdef CONFIG_MAGIC_SYSRQ
+#ifdef CONFIG_MAC_ADBKEYCODES
+ if (!keyboard_sends_linux_keycodes) {
+ ppc_md.ppc_kbd_sysrq_xlate = mac_hid_kbd_sysrq_xlate;
+ SYSRQ_KEY = 0x69;
+ } else
+#endif /* CONFIG_MAC_ADBKEYCODES */
+ {
+ ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
+ SYSRQ_KEY = 0x54;
+ }
+#endif /* CONFIG_MAGIC_SYSRQ */
+#elif defined(CONFIG_ADB_KEYBOARD)
ppc_md.kbd_setkeycode = mackbd_setkeycode;
ppc_md.kbd_getkeycode = mackbd_getkeycode;
ppc_md.kbd_translate = mackbd_translate;
@@ -691,10 +689,11 @@ pmac_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.kbd_leds = mackbd_leds;
ppc_md.kbd_init_hw = mackbd_init_hw;
#ifdef CONFIG_MAGIC_SYSRQ
- ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate;
+ ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate;
SYSRQ_KEY = 0x69;
-#endif
-#endif
+#endif /* CONFIG_MAGIC_SYSRQ */
+#endif /* CONFIG_INPUT_ADBHID/CONFIG_ADB_KEYBOARD */
+#endif /* CONFIG_VT */
#if defined(CONFIG_BLK_DEV_IDE) && defined(CONFIG_BLK_DEV_IDE_PMAC)
ppc_ide_md.insw = pmac_ide_insw;
diff --git a/arch/ppc/kernel/pmac_time.c b/arch/ppc/kernel/pmac_time.c
index 9eb326bf9..00b6302a7 100644
--- a/arch/ppc/kernel/pmac_time.c
+++ b/arch/ppc/kernel/pmac_time.c
@@ -25,7 +25,7 @@
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/machdep.h>
-
+#include <asm/hardirq.h>
#include <asm/time.h>
#include <asm/nvram.h>
@@ -58,7 +58,7 @@ extern rwlock_t xtime_lock;
extern struct timezone sys_tz;
__init
-void pmac_time_init(void)
+long pmac_time_init(void)
{
#ifdef CONFIG_NVRAM
s32 delta = 0;
@@ -72,17 +72,18 @@ void pmac_time_init(void)
dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
dst ? "on" : "off");
- sys_tz.tz_minuteswest = -delta/60;
- /* I _suppose_ this is 0:off, 1:on */
- sys_tz.tz_dsttime = dst;
+ return delta;
+#else
+ return 0;
#endif
}
__pmac
unsigned long pmac_get_rtc_time(void)
{
-#ifdef CONFIG_ADB
+#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
struct adb_request req;
+ unsigned long now;
#endif
/* Get the time from the RTC */
@@ -96,8 +97,9 @@ unsigned long pmac_get_rtc_time(void)
if (req.reply_len != 7)
printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n",
req.reply_len);
- return (req.reply[3] << 24) + (req.reply[4] << 16)
- + (req.reply[5] << 8) + req.reply[6] - RTC_OFFSET;
+ now = (req.reply[3] << 24) + (req.reply[4] << 16)
+ + (req.reply[5] << 8) + req.reply[6];
+ return now - RTC_OFFSET;
#endif /* CONFIG_ADB_CUDA */
#ifdef CONFIG_ADB_PMU
case SYS_CTRLER_PMU:
@@ -108,21 +110,25 @@ unsigned long pmac_get_rtc_time(void)
if (req.reply_len != 5)
printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n",
req.reply_len);
- return (req.reply[1] << 24) + (req.reply[2] << 16)
- + (req.reply[3] << 8) + req.reply[4] - RTC_OFFSET;
+ now = (req.reply[1] << 24) + (req.reply[2] << 16)
+ + (req.reply[3] << 8) + req.reply[4];
+ return now - RTC_OFFSET;
#endif /* CONFIG_ADB_PMU */
default:
- return 0;
}
+ return 0;
}
int pmac_set_rtc_time(unsigned long nowtime)
{
+#if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
struct adb_request req;
+#endif
- nowtime += RTC_OFFSET - sys_tz.tz_minuteswest * 60;
+ nowtime += RTC_OFFSET;
switch (sys_ctrler) {
+#ifdef CONFIG_ADB_CUDA
case SYS_CTRLER_CUDA:
if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
@@ -133,16 +139,19 @@ int pmac_set_rtc_time(unsigned long nowtime)
printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
req.reply_len);
return 1;
+#endif /* CONFIG_ADB_CUDA */
+#ifdef CONFIG_ADB_PMU
case SYS_CTRLER_PMU:
if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
return 0;
while (!req.complete)
pmu_poll();
- if (req.reply_len != 5)
+ if (req.reply_len != 0)
printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
req.reply_len);
return 1;
+#endif /* CONFIG_ADB_PMU */
default:
return 0;
}
@@ -186,12 +195,11 @@ int __init via_calibrate_decr(void)
;
dend = get_dec();
- decrementer_count = (dstart - dend) / 6;
- count_period_num = 60;
- count_period_den = decrementer_count * 6 * HZ / 100000;
+ tb_ticks_per_jiffy = (dstart - dend) / 6;
+ tb_to_us = mulhwu_scale_factor(dstart - dend, 60000);
- printk(KERN_INFO "via_calibrate_decr: decrementer_count = %u (%u ticks)\n",
- decrementer_count, dstart - dend);
+ printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",
+ tb_ticks_per_jiffy, dstart - dend);
return 1;
}
@@ -214,8 +222,11 @@ static int time_sleep_notify(struct pmu_sleep_notifier *self, int when)
case PBOOK_WAKE:
write_lock_irqsave(&xtime_lock, flags);
xtime.tv_sec = pmac_get_rtc_time() + time_diff;
+ set_dec(tb_ticks_per_jiffy);
+ /* No currently-supported powerbook has a 601,
+ so use get_tbl, not native */
+ last_jiffy_stamp(0) = tb_last_stamp = get_tbl();
xtime.tv_usec = 0;
- set_dec(decrementer_count);
last_rtc_update = xtime.tv_sec;
write_unlock_irqrestore(&xtime_lock, flags);
break;
@@ -236,7 +247,7 @@ static struct pmu_sleep_notifier time_sleep_notifier = {
void __init pmac_calibrate_decr(void)
{
struct device_node *cpu;
- int freq, *fp, divisor;
+ unsigned int freq, *fp;
#ifdef CONFIG_PMAC_PBOOK
pmu_register_sleep_notifier(&time_sleep_notifier);
@@ -252,15 +263,13 @@ void __init pmac_calibrate_decr(void)
cpu = find_type_devices("cpu");
if (cpu == 0)
panic("can't find cpu node in time_init");
- fp = (int *) get_property(cpu, "timebase-frequency", NULL);
+ fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL);
if (fp == 0)
panic("can't get cpu timebase frequency");
- freq = *fp * 60; /* try to make freq/1e6 an integer */
- divisor = 60;
- printk("time_init: decrementer frequency = %d/%d\n",
- freq, divisor);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
+ freq = *fp;
+ printk("time_init: decrementer frequency = %u.%.6u MHz\n",
+ freq/1000000, freq%1000000);
+ tb_ticks_per_jiffy = freq / HZ;
+ tb_to_us = mulhwu_scale_factor(freq, 1000000);
}
diff --git a/arch/ppc/kernel/ppc-stub.c b/arch/ppc/kernel/ppc-stub.c
index 7a673fb70..1b865ef96 100644
--- a/arch/ppc/kernel/ppc-stub.c
+++ b/arch/ppc/kernel/ppc-stub.c
@@ -122,9 +122,9 @@ void breakinst(void);
static char remcomInBuffer[BUFMAX];
static char remcomOutBuffer[BUFMAX];
-static int initialized = 0;
-static int kgdb_active = 0;
-static int kgdb_started = 0;
+static int initialized;
+static int kgdb_active;
+static int kgdb_started;
static u_int fault_jmp_buf[100];
static int kdebug;
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c
index 1317359e7..9240431e6 100644
--- a/arch/ppc/kernel/ppc_ksyms.c
+++ b/arch/ppc/kernel/ppc_ksyms.c
@@ -37,6 +37,7 @@
#include <asm/hw_irq.h>
#include <asm/nvram.h>
#include <asm/mmu_context.h>
+#include <asm/backlight.h>
#ifdef CONFIG_SMP
#include <asm/smplock.h>
#endif /* CONFIG_SMP */
@@ -184,6 +185,10 @@ EXPORT_SYMBOL(giveup_fpu);
EXPORT_SYMBOL(enable_kernel_fp);
EXPORT_SYMBOL(flush_icache_range);
EXPORT_SYMBOL(xchg_u32);
+#ifdef CONFIG_ALTIVEC
+EXPORT_SYMBOL(last_task_used_altivec);
+EXPORT_SYMBOL(giveup_altivec);
+#endif /* CONFIG_ALTIVEC */
#ifdef CONFIG_SMP
EXPORT_SYMBOL(__global_cli);
EXPORT_SYMBOL(__global_sti);
@@ -204,26 +209,34 @@ EXPORT_SYMBOL(_machine);
EXPORT_SYMBOL(ppc_md);
#ifdef CONFIG_ADB
-/*
- * This could be more fine-grained, but for now assume if we have
- * ADB we have it all -- Cort
- */
EXPORT_SYMBOL(adb_request);
EXPORT_SYMBOL(adb_register);
+EXPORT_SYMBOL(adb_unregister);
+EXPORT_SYMBOL(adb_poll);
+EXPORT_SYMBOL(adb_try_handler_change);
+#endif /* CONFIG_ADB */
+#ifdef CONFIG_ADB_CUDA
EXPORT_SYMBOL(cuda_request);
EXPORT_SYMBOL(cuda_poll);
+#endif /* CONFIG_ADB_CUDA */
#ifdef CONFIG_ADB_PMU
EXPORT_SYMBOL(pmu_request);
EXPORT_SYMBOL(pmu_poll);
#endif /* CONFIG_ADB_PMU */
-#endif /* CONFIG_ADB */
#ifdef CONFIG_PMAC_PBOOK
EXPORT_SYMBOL(pmu_register_sleep_notifier);
EXPORT_SYMBOL(pmu_unregister_sleep_notifier);
EXPORT_SYMBOL(pmu_enable_irled);
-#endif CONFIG_PMAC_PBOOK
+#endif /* CONFIG_PMAC_PBOOK */
+#ifdef CONFIG_PMAC_BACKLIGHT
+EXPORT_SYMBOL(get_backlight_level);
+EXPORT_SYMBOL(set_backlight_level);
+#endif /* CONFIG_PMAC_BACKLIGHT */
#if defined(CONFIG_ALL_PPC)
EXPORT_SYMBOL_NOVERS(sys_ctrler);
+#ifndef CONFIG_MACH_SPECIFIC
+EXPORT_SYMBOL_NOVERS(have_of);
+#endif /* CONFIG_MACH_SPECIFIC */
EXPORT_SYMBOL(find_devices);
EXPORT_SYMBOL(find_type_devices);
EXPORT_SYMBOL(find_compatible_devices);
@@ -253,10 +266,7 @@ EXPORT_SYMBOL(nvram_write_byte);
EXPORT_SYMBOL(pmac_xpram_read);
EXPORT_SYMBOL(pmac_xpram_write);
#endif /* CONFIG_NVRAM */
-#ifdef CONFIG_PPC_RTC
-EXPORT_SYMBOL(mktime);
EXPORT_SYMBOL(to_tm);
-#endif
EXPORT_SYMBOL_NOVERS(__ashrdi3);
EXPORT_SYMBOL_NOVERS(__ashldi3);
@@ -280,7 +290,7 @@ EXPORT_SYMBOL(do_IRQ_intercept);
EXPORT_SYMBOL(irq_desc);
void ppc_irq_dispatch_handler(struct pt_regs *, int);
EXPORT_SYMBOL(ppc_irq_dispatch_handler);
-EXPORT_SYMBOL(decrementer_count);
+EXPORT_SYMBOL(tb_ticks_per_jiffy);
EXPORT_SYMBOL(get_wchan);
EXPORT_SYMBOL(console_drivers);
EXPORT_SYMBOL(console_lock);
@@ -310,3 +320,17 @@ EXPORT_SYMBOL(do_softirq);
EXPORT_SYMBOL(next_mmu_context);
EXPORT_SYMBOL(set_context);
EXPORT_SYMBOL(mmu_context_overflow);
+
+#ifdef CONFIG_MOL
+extern ulong mol_interface[];
+extern PTE *Hash;
+extern unsigned long Hash_mask;
+extern void (*ret_from_except)(void);
+extern struct task_struct *last_task_used_altivec;
+EXPORT_SYMBOL_NOVERS(mol_interface);
+EXPORT_SYMBOL(Hash);
+EXPORT_SYMBOL(Hash_mask);
+EXPORT_SYMBOL(handle_mm_fault);
+EXPORT_SYMBOL(last_task_used_math);
+EXPORT_SYMBOL(ret_from_except);
+#endif /* CONFIG_MOL */
diff --git a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c
index a09b4cf81..d72e74735 100644
--- a/arch/ppc/kernel/prep_setup.c
+++ b/arch/ppc/kernel/prep_setup.c
@@ -365,14 +365,13 @@ prep_setup_arch(void)
*/
void __init prep_res_calibrate_decr(void)
{
- int freq, divisor;
+ unsigned long freq, divisor=4;
freq = res->VitalProductData.ProcessorBusHz;
- divisor = 4;
- printk("time_init: decrementer frequency = %d/%d\n", freq, divisor);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
+ printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
+ (freq/divisor)/1000000, (freq/divisor)%1000000);
+ tb_ticks_per_jiffy = freq / HZ / divisor;
+ tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);
}
/*
@@ -381,32 +380,30 @@ void __init prep_res_calibrate_decr(void)
* but on prep we have to figure it out.
* -- Cort
*/
-int calibrate_done = 0;
-volatile int *done_ptr = &calibrate_done;
+/* Done with 3 interrupts: the first one primes the cache and the
+ * 2 following ones measure the interval. The precision of the method
+ * is still doubtful due to the short interval sampled.
+ */
+static __initdata volatile int calibrate_steps = 3;
+static __initdata unsigned tbstamp;
void __init
prep_calibrate_decr_handler(int irq,
void *dev,
struct pt_regs *regs)
{
- unsigned long freq, divisor;
- static unsigned long t1 = 0, t2 = 0;
-
- if ( !t1 )
- t1 = get_dec();
- else if (!t2)
- {
- t2 = get_dec();
- t2 = t1-t2; /* decr's in 1/HZ */
- t2 = t2*HZ; /* # decrs in 1s - thus in Hz */
- freq = t2 * 60; /* try to make freq/1e6 an integer */
- divisor = 60;
- printk("time_init: decrementer frequency = %lu/%lu (%luMHz)\n",
- freq, divisor,t2>>20);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
- *done_ptr = 1;
+ unsigned long t, freq;
+ int step=--calibrate_steps;
+
+ t = get_tbl();
+ if (step > 0) {
+ tbstamp = t;
+ } else {
+ freq = (t - tbstamp)*HZ;
+ printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
+ freq/1000000, freq%1000000);
+ tb_ticks_per_jiffy = freq / HZ;
+ tb_to_us = mulhwu_scale_factor(freq, 1000000);
}
}
@@ -428,17 +425,43 @@ void __init prep_calibrate_decr(void)
if (request_irq(0, prep_calibrate_decr_handler, 0, "timer", NULL) != 0)
panic("Could not allocate timer IRQ!");
__sti();
- while ( ! *done_ptr ) /* nothing */; /* wait for calibrate */
+ while ( calibrate_steps ) /* nothing */; /* wait for calibrate */
restore_flags(flags);
free_irq( 0, NULL);
}
-/* We use the NVRAM RTC to time a second to calibrate the decrementer. */
+static long __init mk48t59_init(void) {
+ unsigned char tmp;
+
+ tmp = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB);
+ if (tmp & MK48T59_RTC_CB_STOP) {
+ printk("Warning: RTC was stopped, date will be wrong.\n");
+ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLB,
+ tmp & ~MK48T59_RTC_CB_STOP);
+ /* Low frequency crystal oscillators may take a very long
+ * time to startup and stabilize. For now just ignore the
+ * the issue, but attempting to calibrate the decrementer
+ * from the RTC just after this wakeup is likely to be very
+ * inaccurate. Firmware should not allow to load
+ * the OS with the clock stopped anyway...
+ */
+ }
+ /* Ensure that the clock registers are updated */
+ tmp = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA);
+ tmp &= ~(MK48T59_RTC_CA_READ | MK48T59_RTC_CA_WRITE);
+ ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, tmp);
+ return 0;
+}
+
+/* We use the NVRAM RTC to time a second to calibrate the decrementer,
+ * the RTC registers have just been set up in the right state by the
+ * preceding routine.
+ */
void __init mk48t59_calibrate_decr(void)
{
- unsigned long freq, divisor;
- unsigned long t1, t2;
+ unsigned long freq;
+ unsigned long t1;
unsigned char save_control;
long i;
unsigned char sec;
@@ -458,29 +481,31 @@ void __init mk48t59_calibrate_decr(void)
/* Read the seconds value to see when it changes. */
sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);
+ /* Actually this is bad for precision, we should have a loop in
+ * which we only read the seconds counter. nvram_read_val writes
+ * the address bytes on every call and this takes a lot of time.
+ * Perhaps an nvram_wait_change method returning a time
+ * stamp with a loop count as parameter would be the solution.
+ */
for (i = 0 ; i < 1000000 ; i++) { /* may take up to 1 second... */
+ t1 = get_tbl();
if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) {
break;
}
}
- t1 = get_dec();
sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);
for (i = 0 ; i < 1000000 ; i++) { /* Should take up 1 second... */
+ freq = get_tbl()-t1;
if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) {
break;
}
}
- t2 = t1 - get_dec();
-
- freq = t2 * 60; /* try to make freq/1e6 an integer */
- divisor = 60;
- printk("time_init: decrementer frequency = %lu/%lu (%luMHz)\n",
- freq, divisor,t2>>20);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
+ printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
+ freq/1000000, freq%1000000);
+ tb_ticks_per_jiffy = freq / HZ;
+ tb_to_us = mulhwu_scale_factor(freq, 1000000);
}
void __prep
@@ -788,6 +813,7 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
{
ppc_md.set_rtc_time = mk48t59_set_rtc_time;
ppc_md.get_rtc_time = mk48t59_get_rtc_time;
+ ppc_md.time_init = mk48t59_init;
}
else
{
@@ -808,6 +834,7 @@ prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
ppc_md.set_rtc_time = mk48t59_set_rtc_time;
ppc_md.get_rtc_time = mk48t59_get_rtc_time;
ppc_md.calibrate_decr = mk48t59_calibrate_decr;
+ ppc_md.time_init = mk48t59_init;
}
#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
diff --git a/arch/ppc/kernel/prep_time.c b/arch/ppc/kernel/prep_time.c
index 7274dfd0b..78634c6e2 100644
--- a/arch/ppc/kernel/prep_time.c
+++ b/arch/ppc/kernel/prep_time.c
@@ -15,6 +15,7 @@
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
+#include <linux/time.h>
#include <linux/timex.h>
#include <linux/kernel_stat.h>
#include <linux/init.h>
@@ -99,28 +100,34 @@ __prep
unsigned long mc146818_get_rtc_time(void)
{
unsigned int year, mon, day, hour, min, sec;
- int i;
+ int uip, i;
/* The Linux interpretation of the CMOS clock register contents:
* When the Update-In-Progress (UIP) flag goes from 1 to 0, the
* RTC registers show the second which has precisely just started.
* Let's hope other operating systems interpret the RTC the same way.
*/
- /* read RTC exactly on falling edge of update flag */
- for (i = 0 ; i < 1000000 ; i++) /* may take up to 1 second... */
- if (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)
- break;
- for (i = 0 ; i < 1000000 ; i++) /* must try at least 2.228 ms */
- if (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP))
- break;
- do { /* Isn't this overkill ? UIP above should guarantee consistency */
+
+ /* Since the UIP flag is set for about 2.2 ms and the clock
+ * is typically written with a precision of 1 jiffy, trying
+ * to obtain a precision better than a few milliseconds is
+ * an illusion. Only consistency is interesting, this also
+ * allows to use the routine for /dev/rtc without a potential
+ * 1 second kernel busy loop triggered by any reader of /dev/rtc.
+ */
+
+ for ( i = 0; i<1000000; i++) {
+ uip = CMOS_READ(RTC_FREQ_SELECT);
sec = CMOS_READ(RTC_SECONDS);
min = CMOS_READ(RTC_MINUTES);
hour = CMOS_READ(RTC_HOURS);
day = CMOS_READ(RTC_DAY_OF_MONTH);
mon = CMOS_READ(RTC_MONTH);
year = CMOS_READ(RTC_YEAR);
- } while (sec != CMOS_READ(RTC_SECONDS));
+ uip |= CMOS_READ(RTC_FREQ_SELECT);
+ if ((uip & RTC_UIP)==0) break;
+ }
+
if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
|| RTC_ALWAYS_BCD)
{
@@ -177,29 +184,12 @@ unsigned long mk48t59_get_rtc_time(void)
{
unsigned char save_control;
unsigned int year, mon, day, hour, min, sec;
- int i;
- /* Make sure the time is not stopped. */
- save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB);
-
- ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,
- (save_control & (~MK48T59_RTC_CB_STOP)));
-
- /* Now make sure the read bit is off so the value will change. */
+ /* Simple: freeze the clock, read it and allow updates again */
save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA);
save_control &= ~MK48T59_RTC_CA_READ;
ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control);
- /* Read the seconds value to see when it changes. */
- sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);
-
- /* Wait until the seconds value changes, then read the value. */
- for (i = 0 ; i < 1000000 ; i++) { /* may take up to 1 second... */
- if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) {
- break;
- }
- }
-
/* Set the register to read the value. */
ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,
(save_control | MK48T59_RTC_CA_READ));
diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c
index 7bc5cb82f..27adc9958 100644
--- a/arch/ppc/kernel/process.c
+++ b/arch/ppc/kernel/process.c
@@ -234,7 +234,6 @@ _switch_to(struct task_struct *prev, struct task_struct *new,
prev->thread.vrsave )
giveup_altivec(prev);
#endif /* CONFIG_ALTIVEC */
- prev->last_processor = prev->processor;
current_set[smp_processor_id()] = new;
#endif /* CONFIG_SMP */
/* Avoid the trap. On smp this this never happens since
@@ -266,7 +265,7 @@ void show_regs(struct pt_regs * regs)
last_task_used_altivec);
#ifdef CONFIG_SMP
- printk(" CPU: %d last CPU: %d", current->processor,current->last_processor);
+ printk(" CPU: %d", current->processor);
#endif /* CONFIG_SMP */
printk("\n");
@@ -315,6 +314,7 @@ release_thread(struct task_struct *t)
*/
int
copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
unsigned long msr;
@@ -378,9 +378,6 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
childregs->msr &= ~MSR_VEC;
#endif /* CONFIG_ALTIVEC */
-#ifdef CONFIG_SMP
- p->last_processor = NO_PROC_ID;
-#endif /* CONFIG_SMP */
return 0;
}
@@ -440,13 +437,13 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
current->thread.fpscr = 0;
}
-asmlinkage int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6,
- struct pt_regs *regs)
+int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6,
+ struct pt_regs *regs)
{
unsigned long clone_flags = p1;
int res;
lock_kernel();
- res = do_fork(clone_flags, regs->gpr[1], regs);
+ res = do_fork(clone_flags, regs->gpr[1], regs, 0);
#ifdef CONFIG_SMP
/* When we clone the idle task we keep the same pid but
* the return value of 0 for both causes problems.
@@ -459,13 +456,13 @@ asmlinkage int sys_clone(int p1, int p2, int p3, int p4, int p5, int p6,
return res;
}
-asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
- struct pt_regs *regs)
+int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
+ struct pt_regs *regs)
{
int res;
- res = do_fork(SIGCHLD, regs->gpr[1], regs);
+ res = do_fork(SIGCHLD, regs->gpr[1], regs, 0);
#ifdef CONFIG_SMP
/* When we clone the idle task we keep the same pid but
* the return value of 0 for both causes problems.
@@ -477,15 +474,15 @@ asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6,
return res;
}
-asmlinkage int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
- struct pt_regs *regs)
+int sys_vfork(int p1, int p2, int p3, int p4, int p5, int p6,
+ struct pt_regs *regs)
{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs);
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1], regs, 0);
}
-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)
+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)
{
int error;
char * filename;
diff --git a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c
index 1d661fa71..5494f2f52 100644
--- a/arch/ppc/kernel/prom.c
+++ b/arch/ppc/kernel/prom.c
@@ -140,8 +140,7 @@ static long g_loc_Y = 0;
static long g_max_loc_X = 0;
static long g_max_loc_Y = 0;
-unsigned long disp_BATL = 0;
-unsigned long disp_BATU = 0;
+unsigned long disp_BAT[2] = {0, 0};
#define cmapsz (16*256)
@@ -276,8 +275,7 @@ prom_print(const char *msg)
prom_drawstring(msg);
#endif
return;
- }
-
+ }
for (p = msg; *p != 0; p = q) {
for (q = p; *q != 0 && *q != '\n'; ++q)
@@ -362,7 +360,7 @@ prom_hold_cpus(unsigned long mem)
/* copy the holding pattern code to someplace safe (0) */
/* the holding pattern is now within the first 0x100
bytes of the kernel image -- paulus */
- memcpy((void *)0, KERNELBASE + offset, 0x100);
+ memcpy((void *)0, (void *)(KERNELBASE + offset), 0x100);
flush_icache_range(0, 0x100);
/* look for cpus */
@@ -556,6 +554,54 @@ prom_alloc_htab(void)
}
#endif /* CONFIG_PPC64BRIDGE */
+static __init void
+prom_instantiate_rtas(void)
+{
+ ihandle prom_rtas;
+ unsigned int i;
+ struct prom_args prom_args;
+ unsigned long offset = reloc_offset();
+
+ prom_rtas = call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
+ if (prom_rtas == (void *) -1)
+ return;
+
+ RELOC(rtas_size) = 0;
+ call_prom(RELOC("getprop"), 4, 1, prom_rtas,
+ RELOC("rtas-size"), &RELOC(rtas_size), sizeof(rtas_size));
+ prom_print(RELOC("instantiating rtas"));
+ if (RELOC(rtas_size) == 0) {
+ RELOC(rtas_data) = 0;
+ } else {
+ /*
+ * Ask OF for some space for RTAS.
+ * Actually OF has bugs so we just arbitrarily
+ * use memory at the 6MB point.
+ */
+ RELOC(rtas_data) = 6 << 20;
+ prom_print(RELOC(" at "));
+ prom_print_hex(RELOC(rtas_data));
+ }
+
+ prom_rtas = call_prom(RELOC("open"), 1, 1, RELOC("/rtas"));
+ prom_print(RELOC("..."));
+ prom_args.service = RELOC("call-method");
+ prom_args.nargs = 3;
+ prom_args.nret = 2;
+ prom_args.args[0] = RELOC("instantiate-rtas");
+ prom_args.args[1] = prom_rtas;
+ prom_args.args[2] = (void *) RELOC(rtas_data);
+ RELOC(prom)(&prom_args);
+ i = 0;
+ if (prom_args.args[3] == 0)
+ i = (unsigned int)prom_args.args[4];
+ RELOC(rtas_entry) = i;
+ if ((RELOC(rtas_entry) == -1) || (RELOC(rtas_entry) == 0))
+ prom_print(RELOC(" failed\n"));
+ else
+ prom_print(RELOC(" done\n"));
+}
+
/*
* We enter here early on, when the Open Firmware prom is still
* handling exceptions and the MMU hash table for us.
@@ -566,7 +612,7 @@ prom_init(int r3, int r4, prom_entry pp)
{
int chrp = 0;
unsigned long mem;
- ihandle prom_rtas, prom_mmu, prom_op;
+ ihandle prom_mmu, prom_op;
unsigned long offset = reloc_offset();
int l;
char *p, *d;
@@ -650,47 +696,7 @@ prom_init(int r3, int r4, prom_entry pp)
mem = ALIGN(mem + strlen(d) + 1);
}
- prom_rtas = call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
- if (prom_rtas != (void *) -1) {
- int i, nargs;
- struct prom_args prom_args;
-
- RELOC(rtas_size) = 0;
- call_prom(RELOC("getprop"), 4, 1, prom_rtas,
- RELOC("rtas-size"), &RELOC(rtas_size), sizeof(rtas_size));
- prom_print(RELOC("instantiating rtas"));
- if (RELOC(rtas_size) == 0) {
- RELOC(rtas_data) = 0;
- } else {
- /*
- * Ask OF for some space for RTAS.
- * Actually OF has bugs so we just arbitrarily
- * use memory at the 6MB point.
- */
- RELOC(rtas_data) = 6 << 20;
- prom_print(RELOC(" at "));
- prom_print_hex(RELOC(rtas_data));
- }
- prom_rtas = call_prom(RELOC("open"), 1, 1, RELOC("/rtas"));
- prom_print(RELOC("..."));
- nargs = 3;
- prom_args.service = RELOC("call-method");
- prom_args.nargs = nargs;
- prom_args.nret = 2;
- prom_args.args[0] = RELOC("instantiate-rtas");
- prom_args.args[1] = prom_rtas;
- prom_args.args[2] = (void *) RELOC(rtas_data);
- RELOC(prom)(&prom_args);
- if (prom_args.args[nargs] != 0)
- i = 0;
- else
- i = (int)prom_args.args[nargs+1];
- RELOC(rtas_entry) = i;
- if ((RELOC(rtas_entry) == -1) || (RELOC(rtas_entry) == 0))
- prom_print(RELOC(" failed\n"));
- else
- prom_print(RELOC(" done\n"));
- }
+ prom_instantiate_rtas();
#ifdef CONFIG_PPC64BRIDGE
/*
@@ -737,7 +743,7 @@ prom_init(int r3, int r4, prom_entry pp)
/* We assume the phys. address size is 3 cells */
if (prom_args.args[nargs] != 0)
- prom_print(RELOC(" (translate failed) "));
+ prom_print(RELOC(" (translate failed)\n"));
else
phys = (unsigned long)prom_args.args[nargs+3];
}
@@ -752,8 +758,6 @@ prom_init(int r3, int r4, prom_entry pp)
if (prom_version >= 3) {
prom_print(RELOC("Calling quiesce ...\n"));
call_prom(RELOC("quiesce"), 0, 0);
- offset = reloc_offset();
- phys = offset + KERNELBASE;
}
#ifdef CONFIG_BOOTX_TEXT
@@ -769,7 +773,9 @@ prom_init(int r3, int r4, prom_entry pp)
}
#endif
- prom_print(RELOC("returning from prom_init\n"));
+ prom_print(RELOC("returning "));
+ prom_print_hex(phys);
+ prom_print(RELOC(" from prom_init\n"));
RELOC(prom_stdout) = 0;
return phys;
}
@@ -836,9 +842,8 @@ prom_welcome(boot_infos_t* bi, unsigned long phys)
}
/* Calc BAT values for mapping the display and store them
- * in disp_BATH and disp_BATL. Those values are then used
- * from head.S to map the display during identify_machine()
- * and MMU_Init()
+ * in disp_BAT. Those values are then used from head.S to map
+ * the display during identify_machine() and MMU_Init()
*
* For now, the display is mapped in place (1:1). This should
* be changed if the display physical address overlaps
@@ -862,13 +867,13 @@ prepare_disp_BAT(void)
if ((_get_PVR() >> 16) != 1) {
/* 603, 604, G3, G4, ... */
addr &= 0xFF000000UL;
- RELOC(disp_BATU) = addr | (BL_16M<<2) | 2;
- RELOC(disp_BATL) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
+ RELOC(disp_BAT[0]) = addr | (BL_16M<<2) | 2;
+ RELOC(disp_BAT[1]) = addr | (_PAGE_NO_CACHE | _PAGE_GUARDED | BPP_RW);
} else {
/* 601 */
addr &= 0xFF800000UL;
- RELOC(disp_BATU) = addr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
- RELOC(disp_BATL) = addr | BL_8M | 0x40;
+ RELOC(disp_BAT[0]) = addr | (_PAGE_NO_CACHE | PP_RWXX) | 4;
+ RELOC(disp_BAT[1]) = addr | BL_8M | 0x40;
}
bi->logicalDisplayBase = bi->dispDeviceBase;
}
@@ -1003,34 +1008,52 @@ setup_disp_fake_bi(ihandle dp)
unsigned address;
boot_infos_t* bi;
unsigned long offset = reloc_offset();
-
- prom_print(RELOC("Initializing fake screen\n"));
-
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("width"),
- &width, sizeof(width));
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("height"),
- &height, sizeof(height));
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("depth"),
- &depth, sizeof(depth));
+ struct pci_reg_property addrs[8];
+ int i, naddrs;
+ char name[32];
+ char *getprop = RELOC("getprop");
+
+ prom_print(RELOC("Initializing fake screen: "));
+
+ memset(name, 0, sizeof(name));
+ call_prom(getprop, 4, 1, dp, RELOC("name"), name, sizeof(name));
+ name[sizeof(name)-1] = 0;
+ prom_print(name);
+ prom_print(RELOC("\n"));
+ call_prom(getprop, 4, 1, dp, RELOC("width"), &width, sizeof(width));
+ call_prom(getprop, 4, 1, dp, RELOC("height"), &height, sizeof(height));
+ call_prom(getprop, 4, 1, dp, RELOC("depth"), &depth, sizeof(depth));
pitch = width * ((depth + 7) / 8);
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("linebytes"),
+ call_prom(getprop, 4, 1, dp, RELOC("linebytes"),
&pitch, sizeof(pitch));
- address = 0;
- if (pitch == 1) {
- address = 0xfa000000;
+ if (pitch == 1)
pitch = 0x1000; /* for strange IBM display */
- }
- call_prom(RELOC("getprop"), 4, 1, dp, RELOC("address"),
+ address = 0;
+ call_prom(getprop, 4, 1, dp, RELOC("address"),
&address, sizeof(address));
if (address == 0) {
- prom_print(RELOC("Failed to get address\n"));
- return;
+ /* look for an assigned address with a size of >= 1MB */
+ naddrs = (int) call_prom(getprop, 4, 1, dp,
+ RELOC("assigned-addresses"),
+ addrs, sizeof(addrs));
+ naddrs /= sizeof(struct pci_reg_property);
+ for (i = 0; i < naddrs; ++i) {
+ if (addrs[i].size_lo >= (1 << 20)) {
+ address = addrs[i].addr.a_lo;
+ /* use the BE aperture if possible */
+ if (addrs[i].size_lo >= (16 << 20))
+ address += (8 << 20);
+ break;
+ }
+ }
+ if (address == 0) {
+ prom_print(RELOC("Failed to get address\n"));
+ return;
+ }
}
-#if 0
/* kludge for valkyrie */
- if (strcmp(dp->name, "valkyrie") == 0)
- address += 0x1000;
-#endif
+ if (strcmp(name, RELOC("valkyrie")) == 0)
+ address += 0x1000;
RELOC(disp_bi) = &fake_bi;
bi = PTRRELOC((&fake_bi));
@@ -1334,11 +1357,19 @@ finish_node_interrupts(struct device_node *np, unsigned long mem_start)
*/
if (get_property(node, "interrupt-controller", &l)) {
int i,j;
+ int cvt_irq;
+
+ /* XXX on chrp, offset interrupt numbers for the
+ 8259 by 0, those for the openpic by 16 */
+ cvt_irq = _machine == _MACH_chrp
+ && get_property(node, "interrupt-parent", NULL) == 0;
np->intrs = (struct interrupt_info *) mem_start;
np->n_intrs = ipsize / isize;
mem_start += np->n_intrs * sizeof(struct interrupt_info);
for (i = 0; i < np->n_intrs; ++i) {
np->intrs[i].line = *interrupts++;
+ if (cvt_irq)
+ np->intrs[i].line = openpic_to_irq(np->intrs[i].line);
np->intrs[i].sense = 0;
if (isize > 1)
np->intrs[i].sense = *interrupts++;
@@ -2072,7 +2103,6 @@ abort()
* changes.
*/
-__init
void
map_bootx_text(void)
{
@@ -2083,7 +2113,10 @@ map_bootx_text(void)
offset = ((unsigned long) disp_bi->dispDeviceBase) - base;
size = disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3] + offset
+ disp_bi->dispDeviceRect[0];
- disp_bi->logicalDisplayBase = ioremap(base, size) + offset;
+ disp_bi->logicalDisplayBase = ioremap(base, size);
+ if (disp_bi->logicalDisplayBase == 0)
+ return;
+ disp_bi->logicalDisplayBase += offset;
bootx_text_mapped = 1;
}
@@ -2102,6 +2135,35 @@ calc_base(boot_infos_t *bi, int x, int y)
return base;
}
+/* Adjust the display to a new resolution */
+void
+bootx_update_display(unsigned long phys, int width, int height,
+ int depth, int pitch)
+{
+ if (disp_bi == 0)
+ return;
+ /* check it's the same frame buffer (within 16MB) */
+ if ((phys ^ (unsigned long)disp_bi->dispDeviceBase) & 0xff000000)
+ return;
+
+ disp_bi->dispDeviceBase = (__u8 *) phys;
+ disp_bi->dispDeviceRect[0] = 0;
+ disp_bi->dispDeviceRect[1] = 0;
+ disp_bi->dispDeviceRect[2] = width;
+ disp_bi->dispDeviceRect[3] = height;
+ disp_bi->dispDeviceDepth = depth;
+ disp_bi->dispDeviceRowBytes = pitch;
+ if (bootx_text_mapped) {
+ iounmap(disp_bi->logicalDisplayBase);
+ bootx_text_mapped = 0;
+ }
+ map_bootx_text();
+ g_loc_X = 0;
+ g_loc_Y = 0;
+ g_max_loc_X = width / 8;
+ g_max_loc_Y = height / 16;
+}
+
__pmac
static void
clearscreen(void)
@@ -2162,6 +2224,9 @@ scrollscreen(void)
(bi->dispDeviceDepth >> 3)) >> 2;
int i,j;
+#ifdef CONFIG_ADB_PMU
+ pmu_suspend(); /* PMU will not shut us down ! */
+#endif
for (i=0; i<(bi->dispDeviceRect[3] - bi->dispDeviceRect[1] - 16); i++)
{
unsigned long *src_ptr = src;
@@ -2178,6 +2243,9 @@ scrollscreen(void)
*(dst_ptr++) = 0;
dst += (bi->dispDeviceRowBytes >> 2);
}
+#ifdef CONFIG_ADB_PMU
+ pmu_resume(); /* PMU will not shut us down ! */
+#endif
}
#endif /* ndef NO_SCROLL */
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 67387cca0..6bafa57c1 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -35,6 +35,8 @@
#include <asm/bootx.h>
#include <asm/machdep.h>
#include <asm/feature.h>
+#include <asm/uaccess.h>
+
#ifdef CONFIG_OAK
#include "oak_setup.h"
#endif /* CONFIG_OAK */
@@ -655,16 +657,18 @@ int parse_bootinfo(void)
}
/* Checks "l2cr=xxxx" command-line option */
-void ppc_setup_l2cr(char *str, int *ints)
+int ppc_setup_l2cr(char *str)
{
if ( ((_get_PVR() >> 16) == 8) || ((_get_PVR() >> 16) == 12) )
{
unsigned long val = simple_strtoul(str, NULL, 0);
printk(KERN_INFO "l2cr set to %lx\n", val);
- _set_L2CR(0);
- _set_L2CR(val);
+ _set_L2CR(0); /* force invalidate by disable cache */
+ _set_L2CR(val); /* and enable it */
}
+ return 1;
}
+__setup("l2cr=", ppc_setup_l2cr);
void __init ppc_init(void)
{
@@ -683,6 +687,9 @@ void __init setup_arch(char **cmdline_p)
extern char *klimit;
extern void do_init_bootmem(void);
+ /* so udelay does something sensible, assume <= 1000 bogomips */
+ loops_per_sec = 500000000;
+
#ifdef CONFIG_ALL_PPC
feature_init();
#endif
@@ -737,6 +744,7 @@ void __init setup_arch(char **cmdline_p)
if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab);
paging_init();
+ sort_exception_table();
}
void ppc_generic_ide_fix_driveid(struct hd_driveid *id)
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c
index 79847fa0d..dd3d1ae1b 100644
--- a/arch/ppc/kernel/signal.c
+++ b/arch/ppc/kernel/signal.c
@@ -154,7 +154,7 @@ sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize, int p3, int p4, int p6,
}
-asmlinkage int
+int
sys_sigaltstack(const stack_t *uss, stack_t *uoss)
{
struct pt_regs *regs = (struct pt_regs *) &uss;
@@ -232,7 +232,7 @@ struct rt_sigframe
* Each of these things must be a multiple of 16 bytes in size.
*
*/
-asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
+int sys_rt_sigreturn(struct pt_regs *regs)
{
struct rt_sigframe *rt_sf;
struct sigcontext_struct sigctx;
@@ -301,7 +301,6 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
return ret;
badframe:
- lock_kernel();
do_exit(SIGSEGV);
}
@@ -351,7 +350,6 @@ badframe:
printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
#endif
- lock_kernel();
do_exit(SIGSEGV);
}
@@ -418,7 +416,6 @@ int sys_sigreturn(struct pt_regs *regs)
return ret;
badframe:
- lock_kernel();
do_exit(SIGSEGV);
}
@@ -460,7 +457,6 @@ badframe:
printk("badframe in setup_frame, regs=%p frame=%p newsp=%lx\n",
regs, frame, newsp);
#endif
- lock_kernel();
do_exit(SIGSEGV);
}
@@ -541,7 +537,6 @@ badframe:
regs, frame, *newspp);
printk("sc=%p sig=%d ka=%p info=%p oldset=%p\n", sc, sig, ka, info, oldset);
#endif
- lock_kernel();
do_exit(SIGSEGV);
}
@@ -645,8 +640,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */
default:
- lock_kernel();
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
@@ -663,6 +657,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
/* Whee! Actually deliver the signal. */
handle_signal(signr, ka, &info, oldset, regs, &newsp, frame);
+ break;
}
if (regs->trap == 0x0C00 /* System Call! */ &&
diff --git a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c
index 8cb68c6b2..0a66d6c6b 100644
--- a/arch/ppc/kernel/smp.c
+++ b/arch/ppc/kernel/smp.c
@@ -62,72 +62,62 @@ volatile unsigned long cpu_callin_map[NR_CPUS] = {0,};
int start_secondary(void *);
extern int cpu_idle(void *unused);
u_int openpic_read(volatile u_int *addr);
+void smp_call_function_interrupt(void);
+void smp_message_pass(int target, int msg, unsigned long data, int wait);
+/* register for interrupting the primary processor on the powersurge */
+/* N.B. this is actually the ethernet ROM! */
+#define PSURGE_PRI_INTR 0xf3019000
/* register for interrupting the secondary processor on the powersurge */
-#define PSURGE_INTR ((volatile unsigned *)0xf80000c0)
+#define PSURGE_SEC_INTR 0xf80000c0
+/* register for storing the start address for the secondary processor */
+#define PSURGE_START 0xf2800000
+/* virtual addresses for the above */
+volatile u32 *psurge_pri_intr;
+volatile u32 *psurge_sec_intr;
+volatile u32 *psurge_start;
+
+/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. */
+#define PPC_MSG_CALL_FUNCTION 0
+#define PPC_MSG_RESCHEDULE 1
+#define PPC_MSG_INVALIDATE_TLB 2
+#define PPC_MSG_XMON_BREAK 3
+
+static inline void set_tb(unsigned int upper, unsigned int lower)
+{
+ mtspr(SPRN_TBWU, upper);
+ mtspr(SPRN_TBWL, lower);
+}
void smp_local_timer_interrupt(struct pt_regs * regs)
{
int cpu = smp_processor_id();
- extern void update_one_process(struct task_struct *,unsigned long,
- unsigned long,unsigned long,int);
- if (!--prof_counter[cpu]) {
- int user=0,system=0;
- struct task_struct * p = current;
-
- /*
- * After doing the above, we need to make like
- * a normal interrupt - otherwise timer interrupts
- * ignore the global interrupt lock, which is the
- * WrongThing (tm) to do.
- */
-
- if (user_mode(regs))
- user=1;
- else
- system=1;
-
- if (p->pid) {
- update_one_process(p, 1, user, system, cpu);
-
- p->counter -= 1;
- if (p->counter <= 0) {
- p->counter = 0;
- current->need_resched = 1;
- }
- if (p->nice > 0) {
- kstat.cpu_nice += user;
- kstat.per_cpu_nice[cpu] += user;
- } else {
- kstat.cpu_user += user;
- kstat.per_cpu_user[cpu] += user;
- }
- kstat.cpu_system += system;
- kstat.per_cpu_system[cpu] += system;
-
- }
+ if (!--prof_counter[cpu]) {
+ update_process_times(user_mode(regs));
prof_counter[cpu]=prof_multiplier[cpu];
}
}
-void smp_message_recv(int msg)
+void smp_message_recv(int msg, struct pt_regs *regs)
{
ipi_count++;
- switch( msg )
- {
- case MSG_STOP_CPU:
- __cli();
- while (1) ;
+ switch( msg ) {
+ case PPC_MSG_CALL_FUNCTION:
+ smp_call_function_interrupt();
break;
- case MSG_RESCHEDULE:
+ case PPC_MSG_RESCHEDULE:
current->need_resched = 1;
break;
- case MSG_INVALIDATE_TLB:
+ case PPC_MSG_INVALIDATE_TLB:
_tlbia();
- case 0xf0f0: /* pmac syncing time bases - just return */
break;
+#ifdef CONFIG_XMON
+ case PPC_MSG_XMON_BREAK:
+ xmon(regs);
+ break;
+#endif /* CONFIG_XMON */
default:
printk("SMP %d: smp_message_recv(): unknown msg %d\n",
smp_processor_id(), msg);
@@ -142,25 +132,38 @@ void smp_message_recv(int msg)
* smp_message[].
*
* This is because don't have several IPI's on the PowerSurge even though
- * we do on the chrp. It would be nice to use actual IPI's such as with openpic
- * rather than this.
+ * we do on the chrp. It would be nice to use actual IPI's such as with
+ * openpic rather than this.
* -- Cort
*/
int pmac_smp_message[NR_CPUS];
-void pmac_smp_message_recv(void)
+void pmac_smp_message_recv(struct pt_regs *regs)
{
- int msg = pmac_smp_message[smp_processor_id()];
-
+ int cpu = smp_processor_id();
+ int msg;
+
/* clear interrupt */
- out_be32(PSURGE_INTR, ~0);
-
- /* make sure msg is for us */
- if ( msg == -1 ) return;
+ if (cpu == 1)
+ out_be32(psurge_sec_intr, ~0);
+
+ if (smp_num_cpus < 2)
+ return;
+
+ /* make sure there is a message there */
+ msg = pmac_smp_message[cpu];
+ if (msg == 0)
+ return;
- smp_message_recv(msg);
-
/* reset message */
- pmac_smp_message[smp_processor_id()] = -1;
+ pmac_smp_message[cpu] = 0;
+
+ smp_message_recv(msg - 1, regs);
+}
+
+void
+pmac_primary_intr(int irq, void *d, struct pt_regs *regs)
+{
+ pmac_smp_message_recv(regs);
}
/*
@@ -171,7 +174,7 @@ void pmac_smp_message_recv(void)
void smp_send_tlb_invalidate(int cpu)
{
if ( (_get_PVR()>>16) == 8 )
- smp_message_pass(MSG_ALL_BUT_SELF, MSG_INVALIDATE_TLB, 0, 0);
+ smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_INVALIDATE_TLB, 0, 0);
}
void smp_send_reschedule(int cpu)
@@ -187,18 +190,135 @@ void smp_send_reschedule(int cpu)
*/
/* 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, PPC_MSG_RESCHEDULE, 0, 0);
+}
+
+#ifdef CONFIG_XMON
+void smp_send_xmon_break(int cpu)
+{
+ smp_message_pass(cpu, PPC_MSG_XMON_BREAK, 0, 0);
+}
+#endif /* CONFIG_XMON */
+
+static void stop_this_cpu(void *dummy)
+{
+ __cli();
+ while (1)
+ ;
}
void smp_send_stop(void)
{
- smp_message_pass(MSG_ALL_BUT_SELF, MSG_STOP_CPU, 0, 0);
+ smp_call_function(stop_this_cpu, NULL, 1, 0);
+ smp_num_cpus = 1;
+}
+
+/*
+ * Structure and data for smp_call_function(). This is designed to minimise
+ * static memory requirements. It also looks cleaner.
+ * Stolen from the i386 version.
+ */
+static spinlock_t call_lock = SPIN_LOCK_UNLOCKED;
+
+static volatile struct call_data_struct {
+ void (*func) (void *info);
+ void *info;
+ atomic_t started;
+ atomic_t finished;
+ int wait;
+} *call_data = NULL;
+
+/*
+ * this function sends a 'generic call function' IPI to all other CPUs
+ * in the system.
+ */
+
+int smp_call_function (void (*func) (void *info), void *info, int nonatomic,
+ int wait)
+/*
+ * [SUMMARY] Run a function on all other CPUs.
+ * <func> The function to run. This must be fast and non-blocking.
+ * <info> An arbitrary pointer to pass to the function.
+ * <nonatomic> currently unused.
+ * <wait> If true, wait (atomically) until function has completed on other CPUs.
+ * [RETURNS] 0 on success, else a negative status code. Does not return until
+ * remote CPUs are nearly ready to execute <<func>> or are or have executed.
+ *
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler, you may call it from a bottom half handler.
+ */
+{
+ struct call_data_struct data;
+ int ret = -1, cpus = smp_num_cpus-1;
+ int timeout;
+
+ if (!cpus)
+ return 0;
+
+ data.func = func;
+ data.info = info;
+ atomic_set(&data.started, 0);
+ data.wait = wait;
+ if (wait)
+ atomic_set(&data.finished, 0);
+
+ spin_lock_bh(&call_lock);
+ call_data = &data;
+ /* Send a message to all other CPUs and wait for them to respond */
+ smp_message_pass(MSG_ALL_BUT_SELF, PPC_MSG_CALL_FUNCTION, 0, 0);
+
+ /* Wait for response */
+ timeout = 1000000;
+ while (atomic_read(&data.started) != cpus) {
+ if (--timeout == 0) {
+ printk("smp_call_function on cpu %d: other cpus not responding (%d)\n",
+ smp_processor_id(), atomic_read(&data.started));
+ goto out;
+ }
+ barrier();
+ udelay(1);
+ }
+
+ if (wait) {
+ timeout = 1000000;
+ while (atomic_read(&data.finished) != cpus) {
+ if (--timeout == 0) {
+ printk("smp_call_function on cpu %d: other cpus not finishing (%d/%d)\n",
+ smp_processor_id(), atomic_read(&data.finished), atomic_read(&data.started));
+ goto out;
+ }
+ barrier();
+ udelay(1);
+ }
+ }
+ ret = 0;
+
+ out:
+ spin_unlock_bh(&call_lock);
+ return ret;
+}
+
+void smp_call_function_interrupt(void)
+{
+ void (*func) (void *info) = call_data->func;
+ void *info = call_data->info;
+ int wait = call_data->wait;
+
+ /*
+ * Notify initiating CPU that I've grabbed the data and am
+ * about to execute the function
+ */
+ atomic_inc(&call_data->started);
+ /*
+ * At this point the info structure may be out of scope unless wait==1
+ */
+ (*func)(info);
+ if (wait)
+ atomic_inc(&call_data->finished);
}
void smp_message_pass(int target, int msg, unsigned long data, int wait)
{
- int i;
-
if ( !(_machine & (_MACH_Pmac|_MACH_chrp|_MACH_prep|_MACH_gemini)) )
return;
@@ -212,31 +332,29 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait)
* the recipient won't know the message was destined
* for it. -- Cort
*/
- for ( i = 0; i <= smp_num_cpus ; i++ )
- pmac_smp_message[i] = -1;
- switch( target )
- {
- case MSG_ALL:
- pmac_smp_message[smp_processor_id()] = msg;
- /* fall through */
- case MSG_ALL_BUT_SELF:
- for ( i = 0 ; i < smp_num_cpus ; i++ )
- if ( i != smp_processor_id () )
- pmac_smp_message[i] = msg;
- break;
- default:
- pmac_smp_message[target] = msg;
- break;
+ if (smp_processor_id() == 0) {
+ /* primary cpu */
+ if (target == 1 || target == MSG_ALL_BUT_SELF
+ || target == MSG_ALL) {
+ pmac_smp_message[1] = msg + 1;
+ /* interrupt secondary processor */
+ out_be32(psurge_sec_intr, ~0);
+ out_be32(psurge_sec_intr, 0);
+ }
+ } else {
+ /* secondary cpu */
+ if (target == 0 || target == MSG_ALL_BUT_SELF
+ || target == MSG_ALL) {
+ pmac_smp_message[0] = msg + 1;
+ /* interrupt primary processor */
+ in_be32(psurge_pri_intr);
+ }
+ }
+ if (target == smp_processor_id() || target == MSG_ALL) {
+ /* sending a message to ourself */
+ /* XXX maybe we shouldn't do this if ints are off */
+ smp_message_recv(msg, NULL);
}
- /* interrupt secondary processor */
- out_be32(PSURGE_INTR, ~0);
- out_be32(PSURGE_INTR, 0);
- /*
- * Assume for now that the secondary doesn't send
- * IPI's -- Cort
- */
- /* interrupt primary */
- /**(volatile unsigned long *)(0xf3019000);*/
break;
case _MACH_chrp:
case _MACH_prep:
@@ -261,7 +379,7 @@ void smp_message_pass(int target, int msg, unsigned long data, int wait)
#else /* CONFIG_POWER4 */
/* for now, only do reschedule messages
since we only have one IPI */
- if (msg != MSG_RESCHEDULE)
+ if (msg != PPC_MSG_RESCHEDULE)
break;
for (i = 0; i < smp_num_cpus; ++i) {
if (target == MSG_ALL || target == i
@@ -319,7 +437,10 @@ void __init smp_boot_cpus(void)
{
case _MACH_Pmac:
/* assume powersurge board - 2 processors -- Cort */
- cpu_nr = 2;
+ cpu_nr = 2;
+ psurge_pri_intr = ioremap(PSURGE_PRI_INTR, 4);
+ psurge_sec_intr = ioremap(PSURGE_SEC_INTR, 4);
+ psurge_start = ioremap(PSURGE_START, 4);
break;
case _MACH_chrp:
if (OpenPIC)
@@ -347,7 +468,7 @@ void __init smp_boot_cpus(void)
/* create a process for the processor */
/* we don't care about the values in regs since we'll
never reschedule the forked task. */
- if (do_fork(CLONE_VM|CLONE_PID, 0, &regs) < 0)
+ if (do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0) < 0)
panic("failed fork for CPU %d", i);
p = init_task.prev_task;
if (!p)
@@ -370,13 +491,11 @@ void __init smp_boot_cpus(void)
{
case _MACH_Pmac:
/* setup entry point of secondary processor */
- *(volatile unsigned long *)(0xf2800000) =
- (unsigned long)__secondary_start_psurge-KERNELBASE;
- eieio();
+ out_be32(psurge_start, __pa(__secondary_start_psurge));
/* interrupt secondary to begin executing code */
- out_be32(PSURGE_INTR, ~0);
+ out_be32(psurge_sec_intr, ~0);
udelay(1);
- out_be32(PSURGE_INTR, 0);
+ out_be32(psurge_sec_intr, 0);
break;
case _MACH_chrp:
*(unsigned long *)KERNELBASE = i;
@@ -399,9 +518,6 @@ void __init smp_boot_cpus(void)
if ( cpu_callin_map[i] )
{
printk("Processor %d found.\n", i);
- /* this sync's the decr's -- Cort */
- if ( _machine == _MACH_Pmac )
- set_dec(decrementer_count);
smp_num_cpus++;
} else {
printk("Processor %d is stuck.\n", i);
@@ -415,9 +531,25 @@ void __init smp_boot_cpus(void)
{
/* reset the entry point so if we get another intr we won't
* try to startup again */
- *(volatile unsigned long *)(0xf2800000) = 0x100;
- /* send interrupt to other processors to start decr's on all cpus */
- smp_message_pass(1,0xf0f0, 0, 0);
+ out_be32(psurge_start, 0x100);
+ if (request_irq(30, pmac_primary_intr, 0, "primary IPI", 0))
+ printk(KERN_ERR "Couldn't get primary IPI interrupt");
+ /*
+ * The decrementers of both cpus are frozen at this point
+ * until we give the secondary cpu another interrupt.
+ * We set them both to decrementer_count and then send
+ * the interrupt. This should get the decrementers
+ * synchronized.
+ * -- paulus.
+ */
+ set_dec(tb_ticks_per_jiffy);
+ if ((_get_PVR() >> 16) != 1) {
+ set_tb(0, 0); /* set timebase if not 601 */
+ last_jiffy_stamp(0) = 0;
+ }
+ out_be32(psurge_sec_intr, ~0);
+ udelay(1);
+ out_be32(psurge_sec_intr, 0);
}
}
@@ -447,8 +579,11 @@ int __init start_secondary(void *unused)
void __init smp_callin(void)
{
smp_store_cpu_info(current->processor);
- set_dec(decrementer_count);
-
+ set_dec(tb_ticks_per_jiffy);
+ if (_machine == _MACH_Pmac && (_get_PVR() >> 16) != 1) {
+ set_tb(0, 0); /* set timebase if not 601 */
+ last_jiffy_stamp(current->processor) = 0;
+ }
init_idle();
cpu_callin_map[current->processor] = 1;
diff --git a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c
index 314c1240c..d0fee4344 100644
--- a/arch/ppc/kernel/syscalls.c
+++ b/arch/ppc/kernel/syscalls.c
@@ -45,7 +45,7 @@ check_bugs(void)
{
}
-asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
+int sys_ioperm(unsigned long from, unsigned long num, int on)
{
printk(KERN_ERR "sys_ioperm()\n");
return -EIO;
@@ -74,7 +74,7 @@ int sys_modify_ldt(int a1, int a2, int a3, int a4)
*
* This is really horribly ugly.
*/
-asmlinkage int
+int
sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
{
int version, ret;
@@ -172,7 +172,7 @@ sys_ipc (uint call, int first, int second, int third, void *ptr, long fifth)
* sys_pipe() is the normal C calling standard for creating
* a pipe. It's not the way unix traditionally does this, though.
*/
-asmlinkage int sys_pipe(int *fildes)
+int sys_pipe(int *fildes)
{
int fd[2];
int error;
@@ -185,19 +185,19 @@ asmlinkage int sys_pipe(int *fildes)
return error;
}
-asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len,
- unsigned long prot, unsigned long flags,
- unsigned long fd, off_t offset)
+unsigned long sys_mmap(unsigned long addr, size_t len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, off_t offset)
{
struct file * file = NULL;
int ret = -EBADF;
+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
if (!(flags & MAP_ANONYMOUS)) {
if (!(file = fget(fd)))
goto out;
}
- flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
down(&current->mm->mmap_sem);
ret = do_mmap(file, addr, len, prot, flags, offset);
up(&current->mm->mmap_sem);
@@ -207,7 +207,7 @@ out:
return ret;
}
-extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+extern int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
/*
* Due to some executables calling the wrong select we sometimes
@@ -215,7 +215,7 @@ extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timev
* (a single ptr to them all args passed) then calls
* sys_select() with the appropriate args. -- Cort
*/
-asmlinkage int
+int
ppc_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)
{
if ( (unsigned long)n >= 4096 )
@@ -232,14 +232,14 @@ ppc_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, struct timeval *tvp)
return sys_select(n, inp, outp, exp, tvp);
}
-asmlinkage int sys_pause(void)
+int sys_pause(void)
{
current->state = TASK_INTERRUPTIBLE;
schedule();
return -ERESTARTNOHAND;
}
-asmlinkage int sys_uname(struct old_utsname * name)
+int sys_uname(struct old_utsname * name)
{
int err = -EFAULT;
@@ -250,7 +250,7 @@ asmlinkage int sys_uname(struct old_utsname * name)
return err;
}
-asmlinkage int sys_olduname(struct oldold_utsname * name)
+int sys_olduname(struct oldold_utsname * name)
{
int error;
diff --git a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c
index aff4838b3..f71c8cbbf 100644
--- a/arch/ppc/kernel/time.c
+++ b/arch/ppc/kernel/time.c
@@ -6,6 +6,27 @@
* Paul Mackerras' version and mine for PReP and Pmac.
* MPC8xx/MBX changes by Dan Malek (dmalek@jlc.net).
*
+ * First round of bugfixes by Gabriel Paubert (paubert@iram.es)
+ * to make clock more stable (2.4.0-test5). The only thing
+ * that this code assumes is that the timebases have been synchronized
+ * by firmware on SMP and are never stopped (never do sleep
+ * on SMP then, nap and doze are OK).
+ *
+ * TODO (not necessarily in this file):
+ * - improve precision and reproducibility of timebase frequency
+ * measurement at boot time.
+ * - get rid of xtime_lock for gettimeofday (generic kernel problem
+ * to be implemented on all architectures for SMP scalability and
+ * eventually implementing gettimeofday without entering the kernel).
+ * - put all time/clock related variables in a single structure
+ * to minimize number of cache lines touched by gettimeofday()
+ * - for astronomical applications: add a new function to get
+ * non ambiguous timestamps even around leap seconds. This needs
+ * a new timestamp format and a good name.
+ *
+ *
+ * The following comment is partially obsolete (at least the long wait
+ * is no more a valid reason):
* Since the MPC8xx has a programmable interrupt timer, I decided to
* use that rather than the decrementer. Two reasons: 1.) the clock
* frequency is low, causing 2.) a long wait in the timer interrupt
@@ -49,18 +70,32 @@
void smp_local_timer_interrupt(struct pt_regs *);
/* keep track of when we need to update the rtc */
-time_t last_rtc_update = 0;
+time_t last_rtc_update;
extern rwlock_t xtime_lock;
/* The decrementer counts down by 128 every 128ns on a 601. */
#define DECREMENTER_COUNT_601 (1000000000 / HZ)
-#define COUNT_PERIOD_NUM_601 1
-#define COUNT_PERIOD_DEN_601 1000
-unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
-unsigned count_period_num; /* 1 decrementer count equals */
-unsigned count_period_den; /* count_period_num / count_period_den us */
-unsigned long last_tb;
+unsigned tb_ticks_per_jiffy;
+unsigned tb_to_us;
+unsigned tb_last_stamp;
+
+extern unsigned long wall_jiffies;
+
+static long time_offset;
+
+/* Timer interrupt helper function */
+static inline int tb_delta(unsigned *jiffy_stamp) {
+ int delta;
+ if (__USE_RTC()) {
+ delta = get_rtcl();
+ if (delta < *jiffy_stamp) *jiffy_stamp -= 1000000000;
+ delta -= *jiffy_stamp;
+ } else {
+ delta = get_tbl() - *jiffy_stamp;
+ }
+ return delta;
+}
/*
* timer_interrupt - gets called when the decrementer overflows,
@@ -69,88 +104,56 @@ unsigned long last_tb;
*/
int timer_interrupt(struct pt_regs * regs)
{
- int dval, d;
-#if 0
- unsigned long flags;
-#endif
+ int next_dec;
unsigned long cpu = smp_processor_id();
-
+ unsigned jiffy_stamp = last_jiffy_stamp(cpu);
+
hardirq_enter(cpu);
-#ifdef CONFIG_SMP
- {
- unsigned int loops = 100000000;
- while (test_bit(0, &global_irq_lock)) {
- if (smp_processor_id() == global_irq_holder) {
- printk("uh oh, interrupt while we hold global irq lock!\n");
-#ifdef CONFIG_XMON
- xmon(0);
-#endif
- break;
- }
- if (loops-- == 0) {
- printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder);
-#ifdef CONFIG_XMON
- xmon(0);
-#endif
- }
- }
- }
-#endif /* CONFIG_SMP */
- dval = get_dec();
- /*
- * Wait for the decrementer to change, then jump
- * in and add decrementer_count to its value
- * (quickly, before it changes again!)
- */
- while ((d = get_dec()) == dval)
- ;
- asm volatile("mftb %0" : "=r" (last_tb) );
- /*
- * Don't play catchup between the call to time_init()
- * and sti() in init/main.c.
- *
- * This also means if we're delayed for > HZ
- * we lose those ticks. If we're delayed for > HZ
- * then we have something wrong anyway, though.
- *
- * -- Cort
- */
- if ( d < (-1*decrementer_count) )
- d = 0;
- set_dec(d + decrementer_count);
- if ( !smp_processor_id() )
- {
+ do {
+ jiffy_stamp += tb_ticks_per_jiffy;
+ if (smp_processor_id()) continue;
+ /* We are in an interrupt, no need to save/restore flags */
+ write_lock(&xtime_lock);
+ tb_last_stamp = jiffy_stamp;
do_timer(regs);
-#if 0
- /* -- BenH -- I'm removing this for now since it can cause various
- * troubles with local-time RTCs. Now that we have a
- * /dev/rtc that uses ppc_md.set_rtc_time() on mac, it
- * should be possible to program the RTC from userland
- * in all cases.
- */
+
/*
- * update the rtc when needed
+ * update the rtc when needed, this should be performed on the
+ * right fraction of a second. Half or full second ?
+ * Full second works on mk48t59 clocks, others need testing.
+ * Note that this update is basically only used through
+ * the adjtimex system calls. Setting the HW clock in
+ * any other way is a /dev/rtc and userland business.
+ * This is still wrong by -0.5/+1.5 jiffies because of the
+ * timer interrupt resolution and possible delay, but here we
+ * hit a quantization limit which can only be solved by higher
+ * resolution timers and decoupling time management from timer
+ * interrupts. This is also wrong on the clocks
+ * which require being written at the half second boundary.
+ * We should have an rtc call that only sets the minutes and
+ * seconds like on Intel to avoid problems with non UTC clocks.
*/
- read_lock_irqsave(&xtime_lock, flags);
- if ( (time_status & STA_UNSYNC) &&
- ((xtime.tv_sec > last_rtc_update + 60) ||
- (xtime.tv_sec < last_rtc_update)) )
- {
- if (ppc_md.set_rtc_time(xtime.tv_sec) == 0)
- last_rtc_update = xtime.tv_sec;
+ if ( (time_status & STA_UNSYNC) == 0 &&
+ xtime.tv_sec - last_rtc_update >= 659 &&
+ abs(xtime.tv_usec - (1000000-1000000/HZ)) < 500000/HZ &&
+ jiffies - wall_jiffies == 1) {
+ if (ppc_md.set_rtc_time(xtime.tv_sec+1 + time_offset) == 0)
+ last_rtc_update = xtime.tv_sec+1;
else
- /* do it again in 60 s */
- last_rtc_update = xtime.tv_sec;
+ /* Try again one minute later */
+ last_rtc_update += 60;
}
- read_unlock_irqrestore(&xtime_lock, flags);
-#endif
- }
+ write_unlock(&xtime_lock);
+ } while((next_dec = tb_ticks_per_jiffy - tb_delta(&jiffy_stamp)) < 0);
+ set_dec(next_dec);
+ last_jiffy_stamp(cpu) = jiffy_stamp;
+
#ifdef CONFIG_SMP
smp_local_timer_interrupt(regs);
#endif
- if ( ppc_md.heartbeat && !ppc_md.heartbeat_count--)
+ if (ppc_md.heartbeat && !ppc_md.heartbeat_count--)
ppc_md.heartbeat();
hardirq_exit(cpu);
@@ -162,106 +165,138 @@ int timer_interrupt(struct pt_regs * regs)
*/
void do_gettimeofday(struct timeval *tv)
{
- unsigned long flags, diff;
+ unsigned long flags;
+ unsigned delta, lost_ticks, usec, sec;
- save_flags(flags);
- cli();
read_lock_irqsave(&xtime_lock, flags);
- *tv = xtime;
+ sec = xtime.tv_sec;
+ usec = xtime.tv_usec;
+ delta = tb_ticks_since(tb_last_stamp);
+#ifdef CONFIG_SMP
+ /* As long as timebases are not in sync, gettimeofday can only
+ * have jiffy resolution on SMP.
+ */
+ if (_machine != _MACH_Pmac)
+ delta = 0;
+#endif /* CONFIG_SMP */
+ lost_ticks = jiffies - wall_jiffies;
read_unlock_irqrestore(&xtime_lock, flags);
- /* XXX we don't seem to have the decrementers synced properly yet */
-#ifndef CONFIG_SMP
- asm volatile("mftb %0" : "=r" (diff) );
- diff -= last_tb;
- tv->tv_usec += diff * count_period_num / count_period_den;
- tv->tv_sec += tv->tv_usec / 1000000;
- tv->tv_usec = tv->tv_usec % 1000000;
-#endif
-
- restore_flags(flags);
+
+ usec += mulhwu(tb_to_us, tb_ticks_per_jiffy * lost_ticks + delta);
+ while (usec > 1000000) {
+ sec++;
+ usec -= 1000000;
+ }
+ tv->tv_sec = sec;
+ tv->tv_usec = usec;
}
void do_settimeofday(struct timeval *tv)
{
unsigned long flags;
- int frac_tick;
-
- last_rtc_update = 0; /* so the rtc gets updated soon */
-
- frac_tick = tv->tv_usec % (1000000 / HZ);
- save_flags(flags);
- cli();
+ int tb_delta, new_usec, new_sec;
+
write_lock_irqsave(&xtime_lock, flags);
- xtime.tv_sec = tv->tv_sec;
- xtime.tv_usec = tv->tv_usec - frac_tick;
- write_unlock_irqrestore(&xtime_lock, flags);
- set_dec(frac_tick * count_period_den / count_period_num);
+ /* Updating the RTC is not the job of this code. If the time is
+ * stepped under NTP, the RTC will be update after STA_UNSYNC
+ * is cleared. Tool like clock/hwclock either copy the RTC
+ * to the system time, in which case there is no point in writing
+ * to the RTC again, or write to the RTC but then they don't call
+ * settimeofday to perform this operation. Note also that
+ * we don't touch the decrementer since:
+ * a) it would lose timer interrupt synchronization on SMP
+ * (if it is working one day)
+ * b) it could make one jiffy spuriously shorter or longer
+ * which would introduce another source of uncertainty potentially
+ * harmful to relatively short timers.
+ */
+
+ /* This works perfectly on SMP only if the tb are in sync but
+ * guarantees an error < 1 jiffy even if they are off by eons,
+ * still reasonable when gettimeofday resolution is 1 jiffy.
+ */
+ tb_delta = tb_ticks_since(last_jiffy_stamp(smp_processor_id()));
+ tb_delta += (jiffies - wall_jiffies) * tb_ticks_per_jiffy;
+ new_sec = tv->tv_sec;
+ new_usec = tv->tv_usec - mulhwu(tb_to_us, tb_delta);
+ while (new_usec <0) {
+ new_sec--;
+ new_usec += 1000000;
+ }
+ xtime.tv_usec = new_usec;
+ xtime.tv_sec = new_sec;
+
+ /* In case of a large backwards jump in time with NTP, we want the
+ * clock to be updated as soon as the PLL is again in lock.
+ */
+ last_rtc_update = new_sec - 658;
+
time_adjust = 0; /* stop active adjtime() */
time_status |= STA_UNSYNC;
time_state = TIME_ERROR; /* p. 24, (a) */
time_maxerror = NTP_PHASE_LIMIT;
time_esterror = NTP_PHASE_LIMIT;
- restore_flags(flags);
+ write_unlock_irqrestore(&xtime_lock, flags);
}
void __init time_init(void)
{
+ time_t sec, old_sec;
+ unsigned old_stamp, stamp, elapsed;
+ /* This function is only called on the boot processor */
unsigned long flags;
+
if (ppc_md.time_init != NULL)
- {
- ppc_md.time_init();
- }
+ time_offset = ppc_md.time_init();
- if ((_get_PVR() >> 16) == 1) {
+ if (__USE_RTC()) {
/* 601 processor: dec counts down by 128 every 128ns */
- decrementer_count = DECREMENTER_COUNT_601;
- count_period_num = COUNT_PERIOD_NUM_601;
- count_period_den = COUNT_PERIOD_DEN_601;
- } else if (!smp_processor_id()) {
+ tb_ticks_per_jiffy = DECREMENTER_COUNT_601;
+ /* mulhwu_scale_factor(1000000000, 1000000) is 0x418937 */
+ tb_to_us = 0x418937;
+ } else {
ppc_md.calibrate_decr();
}
+ /* Now that the decrementer is calibrated, it can be used in case the
+ * clock is stuck, but the fact that we have to handle the 601
+ * makes things more complex. Repeatedly read the RTC until the
+ * next second boundary to try to achieve some precision...
+ */
+ stamp = get_native_tbl();
+ sec = ppc_md.get_rtc_time();
+ elapsed = 0;
+ do {
+ old_stamp = stamp;
+ old_sec = sec;
+ stamp = get_native_tbl();
+ if (__USE_RTC() && stamp < old_stamp) old_stamp -= 1000000000;
+ elapsed += stamp - old_stamp;
+ sec = ppc_md.get_rtc_time();
+ } while ( sec == old_sec && elapsed < 2*HZ*tb_ticks_per_jiffy);
+ if (sec==old_sec) {
+ printk("Warning: real time clock seems stuck!\n");
+ }
write_lock_irqsave(&xtime_lock, flags);
- xtime.tv_sec = ppc_md.get_rtc_time();
+ xtime.tv_sec = sec;
+ last_jiffy_stamp(0) = tb_last_stamp = stamp;
xtime.tv_usec = 0;
+ /* No update now, we just read the time from the RTC ! */
+ last_rtc_update = xtime.tv_sec;
write_unlock_irqrestore(&xtime_lock, flags);
+ /* Not exact, but the timer interrupt takes care of this */
+ set_dec(tb_ticks_per_jiffy);
- set_dec(decrementer_count);
- /* allow setting the time right away */
- last_rtc_update = 0;
-}
-
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
-
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
+ /* If platform provided a timezone (pmac), we correct the time
+ * using do_sys_settimeofday() which in turn calls warp_clock()
+ */
+ if (time_offset) {
+ struct timezone tz;
+ tz.tz_minuteswest = -time_offset / 60;
+ tz.tz_dsttime = 0;
+ do_sys_settimeofday(NULL, &tz);
+ }
}
#define TICK_SIZE tick
@@ -354,3 +389,31 @@ void to_tm(int tim, struct rtc_time * tm)
*/
GregorianDay(tm);
}
+
+/* Auxiliary function to compute scaling factors */
+/* Actually the choice of a timebase running at 1/4 the of the bus
+ * frequency giving resolution of a few tens of nanoseconds is quite nice.
+ * It makes this computation very precise (27-28 bits typically) which
+ * is optimistic considering the stability of most processor clock
+ * oscillators and the precision with which the timebase frequency
+ * is measured but does not harm.
+ */
+unsigned mulhwu_scale_factor(unsigned inscale, unsigned outscale) {
+ unsigned mlt=0, tmp, err;
+ /* No concern for performance, it's done once: use a stupid
+ * but safe and compact method to find the multiplier.
+ */
+ for (tmp = 1U<<31; tmp != 0; tmp >>= 1) {
+ if (mulhwu(inscale, mlt|tmp) < outscale) mlt|=tmp;
+ }
+ /* We might still be off by 1 for the best approximation.
+ * A side effect of this is that if outscale is too large
+ * the returned value will be zero.
+ * Many corner cases have been checked and seem to work,
+ * some might have been forgotten in the test however.
+ */
+ err = inscale*(mlt+1);
+ if (err <= inscale/2) mlt++;
+ return mlt;
+}
+
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 0701f7118..3b7473dda 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -87,45 +87,76 @@ _exception(int signr, struct pt_regs *regs)
void
MachineCheckException(struct pt_regs *regs)
{
- if ( !user_mode(regs) )
- {
-#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
- /* the qspan pci read routines can cause machine checks -- Cort */
- bad_page_fault(regs, regs->dar);
+#ifdef CONFIG_ALL_PPC
+ unsigned long fixup;
+#endif /* CONFIG_ALL_PPC */
+
+ if (user_mode(regs)) {
+ _exception(SIGSEGV, regs);
return;
+ }
+
+#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
+ /* the qspan pci read routines can cause machine checks -- Cort */
+ bad_page_fault(regs, regs->dar);
+ return;
#endif
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
- if (debugger_fault_handler) {
- debugger_fault_handler(regs);
- return;
- }
+ if (debugger_fault_handler) {
+ debugger_fault_handler(regs);
+ return;
+ }
#endif
- printk("Machine check in kernel mode.\n");
- printk("Caused by (from SRR1=%lx): ", regs->msr);
- switch (regs->msr & 0xF0000) {
- case 0x80000:
- printk("Machine check signal\n");
- break;
- case 0x40000:
- printk("Transfer error ack signal\n");
- break;
- case 0x20000:
- printk("Data parity error signal\n");
- break;
- case 0x10000:
- printk("Address parity error signal\n");
- break;
- default:
- printk("Unknown values in msr\n");
+
+#ifdef CONFIG_ALL_PPC
+ /*
+ * I/O accesses can cause machine checks on powermacs.
+ * Check if the NIP corresponds to the address of a sync
+ * instruction for which there is an entry in the exception
+ * table.
+ */
+ if (regs->msr & (0x80000 | 0x40000)
+ && (fixup = search_exception_table(regs->nip)) != 0) {
+ /*
+ * Check that it's a sync instruction.
+ * As the address is in the exception table
+ * we should be able to read the instr there.
+ */
+ if (*(unsigned int *)regs->nip == 0x7c0004ac) {
+ unsigned int lsi = ((unsigned int *)regs->nip)[-1];
+ int rb = (lsi >> 11) & 0x1f;
+ printk(KERN_DEBUG "%s bad port %lx at %lx\n",
+ (lsi & 0x100)? "OUT to": "IN from",
+ regs->gpr[rb] - _IO_BASE, regs->nip);
+ regs->nip = fixup;
+ return;
}
- show_regs(regs);
+ }
+#endif /* CONFIG_ALL_PPC */
+ printk("Machine check in kernel mode.\n");
+ printk("Caused by (from SRR1=%lx): ", regs->msr);
+ switch (regs->msr & 0xF0000) {
+ case 0x80000:
+ printk("Machine check signal\n");
+ break;
+ case 0x40000:
+ printk("Transfer error ack signal\n");
+ break;
+ case 0x20000:
+ printk("Data parity error signal\n");
+ break;
+ case 0x10000:
+ printk("Address parity error signal\n");
+ break;
+ default:
+ printk("Unknown values in msr\n");
+ }
+ show_regs(regs);
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
- debugger(regs);
+ debugger(regs);
#endif
- print_backtrace((unsigned long *)regs->gpr[1]);
- panic("machine check");
- }
- _exception(SIGSEGV, regs);
+ print_backtrace((unsigned long *)regs->gpr[1]);
+ panic("machine check");
}
void
@@ -166,6 +197,46 @@ RunModeException(struct pt_regs *regs)
_exception(SIGTRAP, regs);
}
+/* Illegal instruction emulation support. Originally written to
+ * provide the PVR to user applications using the mfspr rd, PVR.
+ * Return non-zero if we can't emulate, or EFAULT if the associated
+ * memory access caused an access fault. Return zero on success.
+ *
+ * There are a couple of ways to do this, either "decode" the instruction
+ * or directly match lots of bits. In this case, matching lots of
+ * bits is faster and easier.
+ *
+ */
+#define INST_MFSPR_PVR 0x7c1f42a6
+#define INST_MFSPR_PVR_MASK 0xfc1fffff
+
+static int
+emulate_instruction(struct pt_regs *regs)
+{
+ uint instword;
+ uint rd;
+ uint retval;
+
+ retval = EFAULT;
+
+ if (!user_mode(regs))
+ return retval;
+
+ if (get_user(instword, (uint *)(regs->nip)))
+ return retval;
+
+ /* Emulate the mfspr rD, PVR.
+ */
+ if ((instword & INST_MFSPR_PVR_MASK) == INST_MFSPR_PVR) {
+ rd = (instword >> 21) & 0x1f;
+ regs->gpr[rd] = _get_PVR();
+ retval = 0;
+ }
+ if (retval == 0)
+ regs->nip += 4;
+ return(retval);
+}
+
void
ProgramCheckException(struct pt_regs *regs)
{
@@ -193,7 +264,14 @@ ProgramCheckException(struct pt_regs *regs)
#endif
_exception(SIGTRAP, regs);
} else {
- _exception(SIGILL, regs);
+ /* Try to emulate it if we should. */
+ int errcode;
+ if ((errcode = emulate_instruction(regs))) {
+ if (errcode == EFAULT)
+ _exception(SIGBUS, regs);
+ else
+ _exception(SIGILL, regs);
+ }
}
#endif
}
diff --git a/arch/ppc/kernel/walnut_setup.c b/arch/ppc/kernel/walnut_setup.c
index 768c36a94..e48a3e61a 100644
--- a/arch/ppc/kernel/walnut_setup.c
+++ b/arch/ppc/kernel/walnut_setup.c
@@ -226,10 +226,11 @@ walnut_halt(void)
/*
* Document me.
*/
-void __init
+long __init
walnut_time_init(void)
{
/* XXX - Implement me */
+ return 0;
}
/*
diff --git a/arch/ppc/kernel/xics.c b/arch/ppc/kernel/xics.c
index a9772821b..2b277f952 100644
--- a/arch/ppc/kernel/xics.c
+++ b/arch/ppc/kernel/xics.c
@@ -166,7 +166,7 @@ xics_get_irq(struct pt_regs *regs)
void xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
{
qirr_info(smp_processor_id()) = 0xff;
- smp_message_recv(MSG_RESCHEDULE);
+ smp_message_recv(MSG_RESCHEDULE, regs);
}
void xics_cause_IPI(int cpu)
diff --git a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S
index 1c4f1f78e..a922b4361 100644
--- a/arch/ppc/lib/string.S
+++ b/arch/ppc/lib/string.S
@@ -9,13 +9,74 @@
* 2 of the License, or (at your option) any later version.
*/
#include "../kernel/ppc_asm.tmpl"
+#include <linux/config.h>
#include <asm/processor.h>
#include <asm/errno.h>
-CACHELINE_BYTES = 32
-LG_CACHELINE_BYTES = 5
-CACHELINE_MASK = 0x1f
-CACHELINE_WORDS = 8
+#if defined(CONFIG_4xx) || defined(CONFIG_8xx)
+#define CACHE_LINE_SIZE 16
+#define LG_CACHE_LINE_SIZE 4
+#define MAX_COPY_PREFETCH 1
+#elif !defined(CONFIG_PPC64BRIDGE)
+#define CACHE_LINE_SIZE 32
+#define LG_CACHE_LINE_SIZE 5
+#define MAX_COPY_PREFETCH 4
+#else
+#define CACHE_LINE_SIZE 128
+#define LG_CACHE_LINE_SIZE 7
+#define MAX_COPY_PREFETCH 1
+#endif /* CONFIG_4xx || CONFIG_8xx */
+
+#define COPY_16_BYTES \
+ lwz r7,4(r4); \
+ lwz r8,8(r4); \
+ lwz r9,12(r4); \
+ lwzu r10,16(r4); \
+ stw r7,4(r6); \
+ stw r8,8(r6); \
+ stw r9,12(r6); \
+ stwu r10,16(r6)
+
+#define COPY_16_BYTES_WITHEX(n) \
+8 ## n ## 0: \
+ lwz r7,4(r4); \
+8 ## n ## 1: \
+ lwz r8,8(r4); \
+8 ## n ## 2: \
+ lwz r9,12(r4); \
+8 ## n ## 3: \
+ lwzu r10,16(r4); \
+8 ## n ## 4: \
+ stw r7,4(r6); \
+8 ## n ## 5: \
+ stw r8,8(r6); \
+8 ## n ## 6: \
+ stw r9,12(r6); \
+8 ## n ## 7: \
+ stwu r10,16(r6)
+
+#define COPY_16_BYTES_EXCODE(n) \
+9 ## n ## 0: \
+ addi r5,r5,-(16 * n); \
+ b 104f; \
+9 ## n ## 1: \
+ addi r5,r5,-(16 * n); \
+ b 105f; \
+.section __ex_table,"a"; \
+ .align 2; \
+ .long 8 ## n ## 0b,9 ## n ## 0b; \
+ .long 8 ## n ## 1b,9 ## n ## 0b; \
+ .long 8 ## n ## 2b,9 ## n ## 0b; \
+ .long 8 ## n ## 3b,9 ## n ## 0b; \
+ .long 8 ## n ## 4b,9 ## n ## 1b; \
+ .long 8 ## n ## 5b,9 ## n ## 1b; \
+ .long 8 ## n ## 6b,9 ## n ## 1b; \
+ .long 8 ## n ## 7b,9 ## n ## 1b; \
+.text
+
+CACHELINE_BYTES = CACHE_LINE_SIZE
+LG_CACHELINE_BYTES = LG_CACHE_LINE_SIZE
+CACHELINE_MASK = (CACHE_LINE_SIZE-1)
.globl strcpy
strcpy:
@@ -105,7 +166,14 @@ cacheable_memzero:
bdnz 4b
3: mtctr r9
li r7,4
+#if !defined(CONFIG_8xx)
10: dcbz r7,r6
+#else
+10: stw r4, 4(r6)
+ stw r4, 8(r6)
+ stw r4, 12(r6)
+ stw r4, 16(r6)
+#endif
addi r6,r6,CACHELINE_BYTES
bdnz 10b
clrlwi r5,r8,32-LG_CACHELINE_BYTES
@@ -202,23 +270,24 @@ cacheable_memcpy:
li r11,4
mtctr r0
beq 63f
-53: dcbz r11,r6
- lwz r7,4(r4)
- lwz r8,8(r4)
- lwz r9,12(r4)
- lwzu r10,16(r4)
- stw r7,4(r6)
- stw r8,8(r6)
- stw r9,12(r6)
- stwu r10,16(r6)
- lwz r7,4(r4)
- lwz r8,8(r4)
- lwz r9,12(r4)
- lwzu r10,16(r4)
- stw r7,4(r6)
- stw r8,8(r6)
- stw r9,12(r6)
- stwu r10,16(r6)
+53:
+#if !defined(CONFIG_8xx)
+ dcbz r11,r6
+#endif
+ COPY_16_BYTES
+#if CACHE_LINE_SIZE >= 32
+ COPY_16_BYTES
+#if CACHE_LINE_SIZE >= 64
+ COPY_16_BYTES
+ COPY_16_BYTES
+#if CACHE_LINE_SIZE >= 128
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+ COPY_16_BYTES
+#endif
+#endif
+#endif
bdnz 53b
63: srwi. r0,r5,2
@@ -380,25 +449,59 @@ __copy_tofrom_user:
58: srwi. r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
clrlwi r5,r5,32-LG_CACHELINE_BYTES
li r11,4
- mtctr r0
beq 63f
-53: dcbz r11,r6
-10: lwz r7,4(r4)
-11: lwz r8,8(r4)
-12: lwz r9,12(r4)
-13: lwzu r10,16(r4)
-14: stw r7,4(r6)
-15: stw r8,8(r6)
-16: stw r9,12(r6)
-17: stwu r10,16(r6)
-20: lwz r7,4(r4)
-21: lwz r8,8(r4)
-22: lwz r9,12(r4)
-23: lwzu r10,16(r4)
-24: stw r7,4(r6)
-25: stw r8,8(r6)
-26: stw r9,12(r6)
-27: stwu r10,16(r6)
+
+#if !defined(CONFIG_8xx)
+ /* Here we decide how far ahead to prefetch the source */
+#if MAX_COPY_PREFETCH > 1
+ /* Heuristically, for large transfers we prefetch
+ MAX_COPY_PREFETCH cachelines ahead. For small transfers
+ we prefetch 1 cacheline ahead. */
+ cmpwi r0,MAX_COPY_PREFETCH
+ li r7,1
+ li r3,4
+ ble 111f
+ li r7,MAX_COPY_PREFETCH
+111: mtctr r7
+112: dcbt r3,r4
+ addi r3,r3,CACHELINE_BYTES
+ bdnz 112b
+#else /* MAX_COPY_PREFETCH == 1 */
+ li r3,CACHELINE_BYTES + 4
+ dcbt r11,r4
+#endif /* MAX_COPY_PREFETCH */
+#endif /* CONFIG_8xx */
+
+ mtctr r0
+53:
+#if !defined(CONFIG_8xx)
+ dcbt r3,r4
+ dcbz r11,r6
+#endif
+/* had to move these to keep extable in order */
+ .section __ex_table,"a"
+ .align 2
+ .long 70b,100f
+ .long 71b,101f
+ .long 72b,102f
+ .long 73b,103f
+ .long 53b,105f
+ .text
+/* the main body of the cacheline loop */
+ COPY_16_BYTES_WITHEX(0)
+#if CACHE_LINE_SIZE >= 32
+ COPY_16_BYTES_WITHEX(1)
+#if CACHE_LINE_SIZE >= 64
+ COPY_16_BYTES_WITHEX(2)
+ COPY_16_BYTES_WITHEX(3)
+#if CACHE_LINE_SIZE >= 128
+ COPY_16_BYTES_WITHEX(4)
+ COPY_16_BYTES_WITHEX(5)
+ COPY_16_BYTES_WITHEX(6)
+ COPY_16_BYTES_WITHEX(7)
+#endif
+#endif
+#endif
bdnz 53b
63: srwi. r0,r5,2
@@ -434,15 +537,31 @@ __copy_tofrom_user:
103: li r4,1
91: li r3,2
b 99f
-/* read fault in 2nd half of cacheline loop */
-106: addi r5,r5,-16
-/* read fault in 1st half of cacheline loop */
+
+/*
+ * this stuff handles faults in the cacheline loop and branches to either
+ * 104f (if in read part) or 105f (if in write part), after updating r5
+ */
+ COPY_16_BYTES_EXCODE(0)
+#if CACHE_LINE_SIZE >= 32
+ COPY_16_BYTES_EXCODE(1)
+#if CACHE_LINE_SIZE >= 64
+ COPY_16_BYTES_EXCODE(2)
+ COPY_16_BYTES_EXCODE(3)
+#if CACHE_LINE_SIZE >= 128
+ COPY_16_BYTES_EXCODE(4)
+ COPY_16_BYTES_EXCODE(5)
+ COPY_16_BYTES_EXCODE(6)
+ COPY_16_BYTES_EXCODE(7)
+#endif
+#endif
+#endif
+
+/* read fault in cacheline loop */
104: li r4,0
b 92f
-/* write fault in 2nd half of cacheline loop */
-107: addi r5,r5,-16
/* fault on dcbz (effectively a write fault) */
-/* or write fault in 1st half of cacheline loop */
+/* or write fault in cacheline loop */
105: li r4,1
92: li r3,LG_CACHELINE_BYTES
b 99f
@@ -485,36 +604,15 @@ __copy_tofrom_user:
bdnz 114b
120: blr
-.section __ex_table,"a"
+ .section __ex_table,"a"
.align 2
- .long 70b,100b
- .long 71b,101b
- .long 72b,102b
- .long 73b,103b
- .long 53b,105b
- .long 10b,104b
- .long 11b,104b
- .long 12b,104b
- .long 13b,104b
- .long 14b,105b
- .long 15b,105b
- .long 16b,105b
- .long 17b,105b
- .long 20b,106b
- .long 21b,106b
- .long 22b,106b
- .long 23b,106b
- .long 24b,107b
- .long 25b,107b
- .long 26b,107b
- .long 27b,107b
.long 30b,108b
.long 31b,109b
.long 40b,110b
.long 41b,111b
.long 112b,120b
.long 114b,120b
-.text
+ .text
.globl __clear_user
__clear_user:
@@ -546,12 +644,13 @@ __clear_user:
blr
99: li r3,-EFAULT
blr
-.section __ex_table,"a"
+
+ .section __ex_table,"a"
.align 2
.long 11b,99b
.long 1b,99b
.long 8b,99b
-.text
+ .text
.globl __strncpy_from_user
__strncpy_from_user:
@@ -570,10 +669,11 @@ __strncpy_from_user:
blr
99: li r3,-EFAULT
blr
-.section __ex_table,"a"
+
+ .section __ex_table,"a"
.align 2
.long 1b,99b
-.text
+ .text
/* r3 = str, r4 = len (> 0), r5 = top (highest addr) */
.globl __strnlen_user
@@ -596,6 +696,7 @@ __strnlen_user:
blr
99: li r3,0 /* bad address, return 0 */
blr
-.section __ex_table,"a"
+
+ .section __ex_table,"a"
.align 2
.long 1b,99b
diff --git a/arch/ppc/mbxboot/misc.c b/arch/ppc/mbxboot/misc.c
index 60563122d..ac400b8c6 100644
--- a/arch/ppc/mbxboot/misc.c
+++ b/arch/ppc/mbxboot/misc.c
@@ -269,6 +269,11 @@ decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, b
*/
#ifdef CONFIG_MBX
cmd_line = (char *)(load_addr - 0x10000);
+
+ /* To be like everyone else, we need one too, although this
+ * board information is passed from the boot rom.
+ */
+ bp->bi_baudrate = 9600;
#else
cmd_line = (char *)(0x200000);
#endif
diff --git a/arch/ppc/mm/extable.c b/arch/ppc/mm/extable.c
index dc57bf868..f43bfaff4 100644
--- a/arch/ppc/mm/extable.c
+++ b/arch/ppc/mm/extable.c
@@ -4,11 +4,47 @@
* from linux/arch/i386/mm/extable.c
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <asm/uaccess.h>
-extern const struct exception_table_entry __start___ex_table[];
-extern const struct exception_table_entry __stop___ex_table[];
+extern struct exception_table_entry __start___ex_table[];
+extern struct exception_table_entry __stop___ex_table[];
+
+/*
+ * The exception table needs to be sorted because we use the macros
+ * which put things into the exception table in a variety of segments
+ * such as the prep, pmac, chrp, etc. segments as well as the init
+ * segment and the main kernel text segment.
+ */
+static inline void
+sort_ex_table(struct exception_table_entry *start,
+ struct exception_table_entry *finish)
+{
+ struct exception_table_entry el, *p, *q;
+
+ /* insertion sort */
+ for (p = start + 1; p < finish; ++p) {
+ /* start .. p-1 is sorted */
+ if (p[0].insn < p[-1].insn) {
+ /* move element p down to its right place */
+ el = *p;
+ q = p;
+ do {
+ /* el comes before q[-1], move q[-1] up one */
+ q[0] = q[-1];
+ --q;
+ } while (q > start && el.insn < q[-1].insn);
+ *q = el;
+ }
+ }
+}
+
+void
+sort_exception_table(void)
+{
+ sort_ex_table(__start___ex_table, __stop___ex_table);
+}
static inline unsigned long
search_one_table(const struct exception_table_entry *first,
@@ -36,25 +72,21 @@ search_exception_table(unsigned long addr)
{
unsigned long ret;
-#if 1 /*ndef CONFIG_MODULES*/
+#ifndef CONFIG_MODULES
/* There is only the kernel to search. */
ret = search_one_table(__start___ex_table, __stop___ex_table-1, addr);
if (ret) return ret;
#else
/* The kernel is the last "module" -- no need to treat it special. */
struct module *mp;
- read_lock(&modlist_lock);
for (mp = module_list; mp != NULL; mp = mp->next) {
if (mp->ex_table_start == NULL)
continue;
ret = search_one_table(mp->ex_table_start,
mp->ex_table_end - 1, addr);
- if (ret) {
- read_unlock(&modlist_lock);
+ if (ret)
return ret;
- }
}
- read_unlock(&modlist_lock);
#endif
return 0;
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index 0b551c803..b6da2cdfc 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -67,7 +67,7 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
#if defined(CONFIG_4xx)
int is_write = error_code & ESR_DST;
#else
- int is_write = error_code & 0x02000000;
+ int is_write = 0;
/*
* Fortunately the bit assignments in SRR1 for an instruction
@@ -77,6 +77,8 @@ void do_page_fault(struct pt_regs *regs, unsigned long address,
*/
if (regs->trap == 0x400)
error_code &= 0x48200000;
+ else
+ is_write = error_code & 0x02000000;
#endif /* CONFIG_4xx */
#if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c
index 67257c50b..be7d1f063 100644
--- a/arch/ppc/mm/init.c
+++ b/arch/ppc/mm/init.c
@@ -36,6 +36,7 @@
#include <linux/delay.h>
#include <linux/openpic.h>
#include <linux/bootmem.h>
+#include <linux/highmem.h>
#ifdef CONFIG_BLK_DEV_INITRD
#include <linux/blk.h> /* for initrd_* */
#endif
@@ -69,15 +70,20 @@
#include "4xx_tlb.h"
#endif
+#define MAX_LOW_MEM (640 << 20)
+
#define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10)
int prom_trashed;
atomic_t next_mmu_context;
unsigned long *end_of_DRAM;
+unsigned long total_memory;
+unsigned long total_lowmem;
int mem_init_done;
int init_bootmem_done;
int boot_mapsize;
unsigned long totalram_pages = 0;
+unsigned long totalhigh_pages = 0;
extern pgd_t swapper_pg_dir[];
extern char _start[], _end[];
extern char etext[], _stext[];
@@ -98,22 +104,26 @@ extern unsigned int rtas_data, rtas_size;
#ifndef CONFIG_SMP
struct pgtable_cache_struct quicklists;
#endif
+#ifdef CONFIG_HIGHMEM
+pte_t *kmap_pte;
+pgprot_t kmap_prot;
+#endif
void MMU_init(void);
static void *MMU_get_page(void);
-unsigned long *prep_find_end_of_memory(void);
-unsigned long *pmac_find_end_of_memory(void);
-unsigned long *apus_find_end_of_memory(void);
-unsigned long *gemini_find_end_of_memory(void);
-extern unsigned long *find_end_of_memory(void);
+unsigned long prep_find_end_of_memory(void);
+unsigned long pmac_find_end_of_memory(void);
+unsigned long apus_find_end_of_memory(void);
+unsigned long gemini_find_end_of_memory(void);
+extern unsigned long find_end_of_memory(void);
#ifdef CONFIG_8xx
-unsigned long *m8xx_find_end_of_memory(void);
+unsigned long m8xx_find_end_of_memory(void);
#endif /* CONFIG_8xx */
#ifdef CONFIG_4xx
-unsigned long *oak_find_end_of_memory(void);
+unsigned long oak_find_end_of_memory(void);
#endif
#ifdef CONFIG_8260
-unsigned long *m8260_find_end_of_memory(void);
+unsigned long m8260_find_end_of_memory(void);
#endif /* CONFIG_8260 */
static void mapin_ram(void);
void map_page(unsigned long va, unsigned long pa, int flags);
@@ -269,6 +279,7 @@ void show_mem(void)
int i,free = 0,total = 0,reserved = 0;
int shared = 0, cached = 0;
struct task_struct *p;
+ int highmem = 0;
printk("Mem-info:\n");
show_free_areas();
@@ -276,6 +287,8 @@ void show_mem(void)
i = max_mapnr;
while (i-- > 0) {
total++;
+ if (PageHighMem(mem_map+i))
+ highmem++;
if (PageReserved(mem_map+i))
reserved++;
else if (PageSwapCache(mem_map+i))
@@ -286,6 +299,7 @@ void show_mem(void)
shared += atomic_read(&mem_map[i].count) - 1;
}
printk("%d pages of RAM\n",total);
+ printk("%d pages of HIGHMEM\n", highmem);
printk("%d free pages\n",free);
printk("%d reserved pages\n",reserved);
printk("%d pages shared\n",shared);
@@ -354,6 +368,8 @@ void si_meminfo(struct sysinfo *val)
continue;
val->sharedram += atomic_read(&mem_map[i].count) - 1;
}
+ val->totalhigh = totalhigh_pages;
+ val->freehigh = nr_free_highpages();
val->mem_unit = PAGE_SIZE;
}
@@ -443,7 +459,8 @@ out:
void iounmap(void *addr)
{
- /* XXX todo */
+ if (addr > high_memory && (unsigned long) addr < ioremap_bot)
+ vfree((void *) (PAGE_MASK & (unsigned long) addr));
}
unsigned long iopa(unsigned long addr)
@@ -476,7 +493,7 @@ map_page(unsigned long va, unsigned long pa, int flags)
{
pmd_t *pd, oldpd;
pte_t *pg;
-
+
/* Use upper 10 bits of VA to index the first level map */
pd = pmd_offset(pgd_offset_k(va), va);
oldpd = *pd;
@@ -516,6 +533,7 @@ local_flush_tlb_all(void)
flush_hash_segments(0xd, 0xffffff);
#else
__clear_user(Hash, Hash_size);
+ _tlbia();
#ifdef CONFIG_SMP
smp_send_tlb_invalidate(0);
#endif /* CONFIG_SMP */
@@ -610,6 +628,13 @@ mmu_context_overflow(void)
}
#endif /* CONFIG_8xx */
+void flush_page_to_ram(struct page *page)
+{
+ unsigned long vaddr = kmap(page);
+ __flush_page_to_ram(vaddr);
+ kunmap(page);
+}
+
#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx)
static void get_mem_prop(char *, struct mem_pieces *);
@@ -722,7 +747,7 @@ static void __init mapin_ram(void)
if (align && align < max_size)
max_size = align;
- tot = (unsigned long)end_of_DRAM - KERNELBASE;
+ tot = total_lowmem;
for (bl = 128<<10; bl < max_size; bl <<= 1) {
if (bl * 2 > tot)
break;
@@ -745,6 +770,8 @@ static void __init mapin_ram(void)
for (i = 0; i < phys_mem.n_regions; ++i) {
v = (ulong)__va(phys_mem.regions[i].address);
p = phys_mem.regions[i].address;
+ if (p >= total_lowmem)
+ break;
for (s = 0; s < phys_mem.regions[i].size; s += PAGE_SIZE) {
/* On the MPC8xx, we want the page shared so we
* don't get ASID compares on kernel space.
@@ -766,6 +793,8 @@ static void __init mapin_ram(void)
map_page(v, p, f);
v += PAGE_SIZE;
p += PAGE_SIZE;
+ if (p >= total_lowmem)
+ break;
}
}
}
@@ -788,77 +817,42 @@ static void __init *MMU_get_page(void)
return p;
}
-void __init free_initmem(void)
+static void free_sec(unsigned long start, unsigned long end, const char *name)
{
- unsigned long a;
- unsigned long num_freed_pages = 0, num_prep_pages = 0,
- num_pmac_pages = 0, num_openfirmware_pages = 0,
- num_apus_pages = 0, num_chrp_pages = 0;
-#define FREESEC(START,END,CNT) do { \
- a = (unsigned long)(&START); \
- for (; a < (unsigned long)(&END); a += PAGE_SIZE) { \
- clear_bit(PG_reserved, &virt_to_page(a)->flags); \
- set_page_count(virt_to_page(a), 1); \
- free_page(a); \
- CNT++; \
- } \
-} while (0)
-
- FREESEC(__init_begin,__init_end,num_freed_pages);
- switch (_machine)
- {
- case _MACH_Pmac:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- case _MACH_chrp:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- break;
- case _MACH_prep:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- case _MACH_mbx:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- case _MACH_apus:
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- case _MACH_gemini:
- FREESEC(__apus_begin,__apus_end,num_apus_pages);
- FREESEC(__pmac_begin,__pmac_end,num_pmac_pages);
- FREESEC(__prep_begin,__prep_end,num_prep_pages);
- FREESEC(__chrp_begin,__chrp_end,num_chrp_pages);
- break;
- }
+ unsigned long cnt = 0;
- if ( !have_of )
- FREESEC( __openfirmware_begin, __openfirmware_end,
- num_openfirmware_pages );
-
- printk ("Freeing unused kernel memory: %ldk init",
- PGTOKB(num_freed_pages));
-
- if ( num_prep_pages )
- printk(" %ldk prep", PGTOKB(num_prep_pages));
- if ( num_chrp_pages )
- printk(" %ldk chrp", PGTOKB(num_chrp_pages));
- if ( num_pmac_pages )
- printk(" %ldk pmac", PGTOKB(num_pmac_pages));
- if ( num_openfirmware_pages )
- printk(" %ldk open firmware", PGTOKB(num_openfirmware_pages));
- if ( num_apus_pages )
- printk(" %ldk apus", PGTOKB(num_apus_pages));
- printk("\n");
+ while (start < end) {
+ clear_bit(PG_reserved, &virt_to_page(start)->flags);
+ set_page_count(virt_to_page(start), 1);
+ free_page(start);
+ cnt++;
+ start += PAGE_SIZE;
+ }
+ if (cnt)
+ printk(" %ldk %s", PGTOKB(cnt), name);
+}
+
+void free_initmem(void)
+{
+#define FREESEC(TYPE) \
+ free_sec((unsigned long)(&__ ## TYPE ## _begin), \
+ (unsigned long)(&__ ## TYPE ## _end), \
+ #TYPE);
+
+ printk ("Freeing unused kernel memory:");
+ FREESEC(init);
+ if (_machine != _MACH_Pmac)
+ FREESEC(pmac);
+ if (_machine != _MACH_chrp)
+ FREESEC(chrp);
+ if (_machine != _MACH_prep)
+ FREESEC(prep);
+ if (_machine != _MACH_apus)
+ FREESEC(apus);
+ if (!have_of)
+ FREESEC(openfirmware);
+ printk("\n");
+#undef FREESEC
}
#ifdef CONFIG_BLK_DEV_INITRD
@@ -909,7 +903,8 @@ MMU_init(void)
* at KERNELBASE.
*/
- end_of_DRAM = oak_find_end_of_memory();
+ total_memory = total_lowmem = oak_find_end_of_memory();
+ end_of_DRAM = __va(total_memory);
mapin_ram();
/*
@@ -939,23 +934,33 @@ void __init MMU_init(void)
if ( ppc_md.progress ) ppc_md.progress("MMU:enter", 0x111);
#ifndef CONFIG_8xx
if (have_of)
- end_of_DRAM = pmac_find_end_of_memory();
+ total_memory = pmac_find_end_of_memory();
#ifdef CONFIG_APUS
else if (_machine == _MACH_apus )
- end_of_DRAM = apus_find_end_of_memory();
+ total_memory = apus_find_end_of_memory();
#endif
#ifdef CONFIG_GEMINI
else if ( _machine == _MACH_gemini )
- end_of_DRAM = gemini_find_end_of_memory();
+ total_memory = gemini_find_end_of_memory();
#endif /* CONFIG_GEMINI */
#if defined(CONFIG_8260)
else
- end_of_DRAM = m8260_find_end_of_memory();
+ total_memory = m8260_find_end_of_memory();
#else
else /* prep */
- end_of_DRAM = prep_find_end_of_memory();
+ total_memory = prep_find_end_of_memory();
#endif
+ total_lowmem = total_memory;
+#ifdef CONFIG_HIGHMEM
+ if (total_lowmem > MAX_LOW_MEM) {
+ total_lowmem = MAX_LOW_MEM;
+ mem_pieces_remove(&phys_avail, total_lowmem,
+ total_memory - total_lowmem, 0);
+ }
+#endif /* CONFIG_HIGHMEM */
+ end_of_DRAM = __va(total_lowmem);
+
if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300);
hash_init();
#ifndef CONFIG_PPC64BRIDGE
@@ -995,7 +1000,7 @@ void __init MMU_init(void)
#endif
break;
case _MACH_Pmac:
- ioremap_base = 0xf8000000;
+ ioremap_base = 0xfe000000;
break;
case _MACH_apus:
/* Map PPC exception vectors. */
@@ -1022,7 +1027,15 @@ void __init MMU_init(void)
#endif /* CONFIG_POWER4 */
#else /* CONFIG_8xx */
- end_of_DRAM = m8xx_find_end_of_memory();
+ total_memory = total_lowmem = m8xx_find_end_of_memory();
+#ifdef CONFIG_HIGHMEM
+ if (total_lowmem > MAX_LOW_MEM) {
+ total_lowmem = MAX_LOW_MEM;
+ mem_pieces_remove(&phys_avail, total_lowmem,
+ total_memory - total_lowmem, 0);
+ }
+#endif /* CONFIG_HIGHMEM */
+ end_of_DRAM = __va(total_lowmem);
/* Map in all of RAM starting at KERNELBASE */
mapin_ram();
@@ -1055,7 +1068,7 @@ void __init MMU_init(void)
if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211);
#ifdef CONFIG_BOOTX_TEXT
/* Must be done last, or ppc_md.progress will die */
- if (_machine == _MACH_Pmac)
+ if (_machine == _MACH_Pmac || _machine == _MACH_chrp)
map_bootx_text();
#endif
}
@@ -1092,7 +1105,7 @@ void __init do_init_bootmem(void)
start = PAGE_ALIGN(start);
boot_mapsize = init_bootmem(start >> PAGE_SHIFT,
- __pa(end_of_DRAM) >> PAGE_SHIFT);
+ total_lowmem >> PAGE_SHIFT);
/* remove the bootmem bitmap from the available memory */
mem_pieces_remove(&phys_avail, start, boot_mapsize, 1);
@@ -1105,47 +1118,6 @@ void __init do_init_bootmem(void)
init_bootmem_done = 1;
}
-#if 0
-/*
- * Find some memory for setup_arch to return.
- * We use the largest chunk of available memory as the area
- * that setup_arch returns, making sure that there are at
- * least 32 pages unused before this for MMU_get_page to use.
- */
-unsigned long __init find_available_memory(void)
-{
- int i, rn;
- unsigned long a, free;
- unsigned long start, end;
-
- if (_machine == _MACH_mbx) {
- /* Return the first, not the last region, because we
- * may not yet have properly initialized the additonal
- * memory DIMM.
- */
- a = PAGE_ALIGN(phys_avail.regions[0].address);
- avail_start = (unsigned long) __va(a);
- return avail_start;
- }
-
- rn = 0;
- for (i = 1; i < phys_avail.n_regions; ++i)
- if (phys_avail.regions[i].size > phys_avail.regions[rn].size)
- rn = i;
- free = 0;
- for (i = 0; i < rn; ++i) {
- start = phys_avail.regions[i].address;
- end = start + phys_avail.regions[i].size;
- free += (end & PAGE_MASK) - PAGE_ALIGN(start);
- }
- a = PAGE_ALIGN(phys_avail.regions[rn].address);
- if (free < 32 * PAGE_SIZE)
- a += 32 * PAGE_SIZE - free;
- avail_start = (unsigned long) __va(a);
- return avail_start;
-}
-#endif /* 0 */
-
/*
* paging_init() sets up the page tables - in fact we've already done this.
*/
@@ -1153,6 +1125,14 @@ void __init paging_init(void)
{
unsigned long zones_size[MAX_NR_ZONES], i;
+#ifdef CONFIG_HIGHMEM
+ map_page(PKMAP_BASE, 0, 0); /* XXX gross */
+ pkmap_page_table = pte_offset(pmd_offset(pgd_offset_k(PKMAP_BASE), PKMAP_BASE), PKMAP_BASE);
+ map_page(KMAP_FIX_BEGIN, 0, 0); /* XXX gross */
+ kmap_pte = pte_offset(pmd_offset(pgd_offset_k(KMAP_FIX_BEGIN), KMAP_FIX_BEGIN), KMAP_FIX_BEGIN);
+ kmap_prot = PAGE_KERNEL;
+#endif /* CONFIG_HIGHMEM */
+
/*
* Grab some memory for bad_page and bad_pagetable to use.
*/
@@ -1162,9 +1142,14 @@ void __init paging_init(void)
/*
* All pages are DMA-able so we put them all in the DMA zone.
*/
- zones_size[0] = ((unsigned long)end_of_DRAM - KERNELBASE) >> PAGE_SHIFT;
+ zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT;
for (i = 1; i < MAX_NR_ZONES; i++)
zones_size[i] = 0;
+
+#ifdef CONFIG_HIGHMEM
+ zones_size[ZONE_HIGHMEM] = (total_memory - total_lowmem) >> PAGE_SHIFT;
+#endif /* CONFIG_HIGHMEM */
+
free_area_init(zones_size);
}
@@ -1176,7 +1161,17 @@ void __init mem_init(void)
int codepages = 0;
int datapages = 0;
int initpages = 0;
+#ifdef CONFIG_HIGHMEM
+ unsigned long highmem_mapnr;
+
+ highmem_mapnr = total_lowmem >> PAGE_SHIFT;
+ highmem_start_page = mem_map + highmem_mapnr;
+ max_mapnr = total_memory >> PAGE_SHIFT;
+ totalram_pages += max_mapnr - highmem_mapnr;
+#else
max_mapnr = max_low_pfn;
+#endif /* CONFIG_HIGHMEM */
+
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
num_physpages = max_mapnr; /* RAM is assumed contiguous */
@@ -1217,11 +1212,28 @@ void __init mem_init(void)
datapages++;
}
- printk("Memory: %luk available (%dk kernel code, %dk data, %dk init) [%08x,%08lx]\n",
+#ifdef CONFIG_HIGHMEM
+ {
+ unsigned long pfn;
+
+ for (pfn = highmem_mapnr; pfn < max_mapnr; ++pfn) {
+ struct page *page = mem_map + pfn;
+
+ ClearPageReserved(page);
+ set_bit(PG_highmem, &page->flags);
+ atomic_set(&page->count, 1);
+ __free_page(page);
+ totalhigh_pages++;
+ }
+ totalram_pages += totalhigh_pages;
+ }
+#endif /* CONFIG_HIGHMEM */
+
+ printk("Memory: %luk available (%dk kernel code, %dk data, %dk init, %ldk highmem)\n",
(unsigned long)nr_free_pages()<< (PAGE_SHIFT-10),
codepages<< (PAGE_SHIFT-10), datapages<< (PAGE_SHIFT-10),
initpages<< (PAGE_SHIFT-10),
- PAGE_OFFSET, (unsigned long) end_of_DRAM);
+ (unsigned long) (totalhigh_pages << (PAGE_SHIFT-10)));
mem_init_done = 1;
}
@@ -1234,7 +1246,7 @@ void __init mem_init(void)
* Our text, data, bss use something over 1MB, starting at 0.
* Open Firmware may be using 1MB at the 4MB point.
*/
-unsigned long __init *pmac_find_end_of_memory(void)
+unsigned long __init pmac_find_end_of_memory(void)
{
unsigned long a, total;
unsigned long ram_limit = 0xe0000000 - KERNELBASE;
@@ -1279,7 +1291,7 @@ unsigned long __init *pmac_find_end_of_memory(void)
set_phys_avail(&phys_mem);
- return __va(total);
+ return total;
}
#endif /* CONFIG_ALL_PPC */
@@ -1290,7 +1302,7 @@ unsigned long __init *pmac_find_end_of_memory(void)
* this will likely stay separate from the pmac.
* -- Cort
*/
-unsigned long __init *prep_find_end_of_memory(void)
+unsigned long __init prep_find_end_of_memory(void)
{
unsigned long total;
total = res->TotalMemory;
@@ -1308,15 +1320,15 @@ unsigned long __init *prep_find_end_of_memory(void)
mem_pieces_append(&phys_mem, 0, total);
set_phys_avail(&phys_mem);
- return (__va(total));
+ return (total);
}
#endif /* defined(CONFIG_ALL_PPC) */
#if defined(CONFIG_GEMINI)
-unsigned long __init *gemini_find_end_of_memory(void)
+unsigned long __init gemini_find_end_of_memory(void)
{
- unsigned long total, *ret;
+ unsigned long total;
unsigned char reg;
reg = readb(GEMINI_MEMCFG);
@@ -1327,9 +1339,8 @@ unsigned long __init *gemini_find_end_of_memory(void)
phys_mem.regions[0].size = total;
phys_mem.n_regions = 1;
- ret = __va(phys_mem.regions[0].size);
set_phys_avail(&phys_mem);
- return ret;
+ return phys_mem.regions[0].size;
}
#endif /* defined(CONFIG_GEMINI) */
@@ -1337,10 +1348,9 @@ unsigned long __init *gemini_find_end_of_memory(void)
/*
* Same hack as 8xx.
*/
-unsigned long __init *m8260_find_end_of_memory(void)
+unsigned long __init m8260_find_end_of_memory(void)
{
bd_t *binfo;
- unsigned long *ret;
extern unsigned char __res[];
binfo = (bd_t *)__res;
@@ -1349,15 +1359,14 @@ unsigned long __init *m8260_find_end_of_memory(void)
phys_mem.regions[0].size = binfo->bi_memsize;
phys_mem.n_regions = 1;
- ret = __va(phys_mem.regions[0].size);
set_phys_avail(&phys_mem);
- return ret;
+ return phys_mem.regions[0].size;
}
#endif /* CONFIG_8260 */
#ifdef CONFIG_APUS
#define HARDWARE_MAPPED_SIZE (512*1024)
-unsigned long __init *apus_find_end_of_memory(void)
+unsigned long __init apus_find_end_of_memory(void)
{
int shadow = 0;
@@ -1421,7 +1430,7 @@ unsigned long __init *apus_find_end_of_memory(void)
the PowerUP board. Other system memory is horrible slow in
comparison. The user can use other memory for swapping
using the z2ram device. */
- return __va(memory[0].addr + memory[0].size);
+ return memory[0].addr + memory[0].size;
}
#endif /* CONFIG_APUS */
@@ -1484,7 +1493,7 @@ static void __init hash_init(void)
/* Find some memory for the hash table. */
if ( Hash_size ) {
Hash = mem_pieces_find(Hash_size, Hash_size);
- /*__clear_user(Hash, Hash_size);*/
+ cacheable_memzero(Hash, Hash_size);
} else
Hash = 0;
#endif /* CONFIG_PPC64BRIDGE */
@@ -1544,10 +1553,9 @@ static void __init hash_init(void)
* functions in the image just to get prom_init, all we really need right
* now is the initialization of the physical memory region.
*/
-unsigned long __init *m8xx_find_end_of_memory(void)
+unsigned long __init m8xx_find_end_of_memory(void)
{
bd_t *binfo;
- unsigned long *ret;
extern unsigned char __res[];
binfo = (bd_t *)__res;
@@ -1555,12 +1563,9 @@ unsigned long __init *m8xx_find_end_of_memory(void)
phys_mem.regions[0].address = 0;
phys_mem.regions[0].size = binfo->bi_memsize;
phys_mem.n_regions = 1;
-
- ret = __va(phys_mem.regions[0].address+
- phys_mem.regions[0].size);
set_phys_avail(&phys_mem);
- return ret;
+ return phys_mem.regions[0].address + phys_mem.regions[0].size;
}
#endif /* !CONFIG_4xx && !CONFIG_8xx */
@@ -1569,7 +1574,7 @@ unsigned long __init *m8xx_find_end_of_memory(void)
* Return the virtual address representing the top of physical RAM
* on the Oak board.
*/
-unsigned long __init *
+unsigned long __init
oak_find_end_of_memory(void)
{
extern unsigned char __res[];
@@ -1580,12 +1585,9 @@ oak_find_end_of_memory(void)
phys_mem.regions[0].address = 0;
phys_mem.regions[0].size = bip->bi_memsize;
phys_mem.n_regions = 1;
-
- ret = __va(phys_mem.regions[0].address +
- phys_mem.regions[0].size);
set_phys_avail(&phys_mem);
- return (ret);
+ return (phys_mem.regions[0].address + phys_mem.regions[0].size);
}
#endif
diff --git a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c
index a816f0b9d..499c5b6c8 100644
--- a/arch/ppc/xmon/start.c
+++ b/arch/ppc/xmon/start.c
@@ -8,6 +8,7 @@
#include <asm/page.h>
#include <linux/adb.h>
#include <linux/pmu.h>
+#include <linux/cuda.h>
#include <linux/kernel.h>
#include <asm/prom.h>
#include <asm/bootx.h>
@@ -67,6 +68,12 @@ xmon_map_scc(void)
use_screen = 1;
}
#endif
+#ifdef CONFIG_ADB_CUDA
+ if (!via_modem && disp_bi ) {
+ prom_drawstring("xmon uses screen and keyboard\n");
+ use_screen = 1;
+ }
+#endif
#endif
#ifdef CHRP_ESCC
@@ -100,6 +107,10 @@ xmon_map_scc(void)
/* should already be mapped by the kernel boot */
sccc = (volatile unsigned char *) (isa_io_base + 0x3fd);
sccd = (volatile unsigned char *) (isa_io_base + 0x3f8);
+ if (xmon_use_sccb) {
+ sccc -= 0x100;
+ sccd -= 0x100;
+ }
TXRDY = 0x20;
RXRDY = 1;
}
@@ -109,6 +120,19 @@ static int scc_initialized = 0;
void xmon_init_scc(void);
extern void pmu_poll(void);
+extern void cuda_poll(void);
+
+static inline void do_poll_adb(void)
+{
+#ifdef CONFIG_ADB_PMU
+ if (sys_ctrler == SYS_CTRLER_PMU)
+ pmu_poll();
+#endif /* CONFIG_ADB_PMU */
+#ifdef CONFIG_ADB_CUDA
+ if (sys_ctrler == SYS_CTRLER_CUDA)
+ cuda_poll();
+#endif /* CONFIG_ADB_CUDA */
+}
int
xmon_write(void *handle, void *ptr, int nb)
@@ -128,12 +152,8 @@ xmon_write(void *handle, void *ptr, int nb)
xmon_init_scc();
ct = 0;
for (i = 0; i < nb; ++i) {
- while ((*sccc & TXRDY) == 0) {
-#ifdef CONFIG_ADB_PMU
- if (sys_ctrler == SYS_CTRLER_PMU)
- pmu_poll();
-#endif /* CONFIG_ADB_PMU */
- }
+ while ((*sccc & TXRDY) == 0)
+ do_poll_adb();
c = p[i];
if (c == '\n' && !ct) {
c = '\r';
@@ -189,9 +209,7 @@ xmon_get_adb_key(void)
prom_drawchar('\b');
t = 200000;
}
-#ifdef CONFIG_ADB_PMU
- pmu_poll();
-#endif /* CONFIG_ADB_PMU */
+ do_poll_adb();
} while (xmon_adb_keycode == -1);
k = xmon_adb_keycode;
if (on)
@@ -230,14 +248,9 @@ xmon_read(void *handle, void *ptr, int nb)
xmon_init_scc();
for (i = 0; i < nb; ++i) {
while ((*sccc & RXRDY) == 0)
-#ifdef CONFIG_ADB_PMU
- if (sys_ctrler == SYS_CTRLER_PMU)
- pmu_poll();
-#else
- ;
-#endif /* CONFIG_ADB_PMU */
+ do_poll_adb();
buf_access();
- *p++ = *sccd;
+ *p++ = *sccd;
}
return i;
}
@@ -246,10 +259,7 @@ int
xmon_read_poll(void)
{
if ((*sccc & RXRDY) == 0) {
-#ifdef CONFIG_ADB_PMU
- if (sys_ctrler == SYS_CTRLER_PMU)
- pmu_poll();
-#endif /* CONFIG_ADB_PMU */
+ do_poll_adb();
return -1;
}
buf_access();
@@ -491,3 +501,19 @@ xmon_fgets(char *str, int nb, void *f)
*p = 0;
return str;
}
+
+void
+xmon_enter(void)
+{
+#ifdef CONFIG_ADB_PMU
+ pmu_suspend();
+#endif
+}
+
+void
+xmon_leave(void)
+{
+#ifdef CONFIG_ADB_PMU
+ pmu_resume();
+#endif
+}
diff --git a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c
index 75160d9b8..49c3be834 100644
--- a/arch/ppc/xmon/xmon.c
+++ b/arch/ppc/xmon/xmon.c
@@ -6,15 +6,23 @@
#include <linux/config.h>
#include <linux/errno.h>
#include <linux/sched.h>
+#include <linux/smp.h>
#include <asm/ptrace.h>
#include <asm/string.h>
#include <asm/prom.h>
+#include <asm/bitops.h>
#include "nonstdio.h"
#include "privinst.h"
#define scanhex xmon_scanhex
#define skipbl xmon_skipbl
+#ifdef CONFIG_SMP
+static unsigned long cpus_in_xmon = 0;
+static unsigned long got_xmon = 0;
+static volatile int take_xmon = -1;
+#endif /* CONFIG_SMP */
+
static unsigned adrs;
static int size = 1;
static unsigned ndump = 64;
@@ -84,6 +92,9 @@ static void insert_bpts(void);
static struct bpt *at_breakpoint(unsigned pc);
static void bpt_cmds(void);
static void cacheflush(void);
+#ifdef CONFIG_SMP
+static void cpu_cmd(void);
+#endif /* CONFIG_SMP */
#if 0 /* Makes compile with -Wall */
static char *pretty_print_addr(unsigned long addr);
static char *lookup_name(unsigned long addr);
@@ -96,8 +107,18 @@ extern int putchar(int ch);
extern int setjmp(u_int *);
extern void longjmp(u_int *, int);
+extern void xmon_enter(void);
+extern void xmon_leave(void);
+
#define GETWORD(v) (((v)[0] << 24) + ((v)[1] << 16) + ((v)[2] << 8) + (v)[3])
+#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
+ || ('a' <= (c) && (c) <= 'f') \
+ || ('A' <= (c) && (c) <= 'F'))
+#define isalnum(c) (('0' <= (c) && (c) <= '9') \
+ || ('a' <= (c) && (c) <= 'z') \
+ || ('A' <= (c) && (c) <= 'Z'))
+
static char *help_string = "\
Commands:\n\
d dump bytes\n\
@@ -117,10 +138,12 @@ Commands:\n\
x exit monitor\n\
";
-static int xmon_trace;
+static int xmon_trace[NR_CPUS];
#define SSTEP 1 /* stepping because of 's' command */
#define BRSTEP 2 /* stepping over breakpoint */
+static struct pt_regs *xmon_regs[NR_CPUS];
+
void
xmon(struct pt_regs *excp)
{
@@ -143,27 +166,52 @@ xmon(struct pt_regs *excp)
msr = get_msr();
set_msr(msr & ~0x8000); /* disable interrupts */
- remove_bpts();
+ xmon_regs[smp_processor_id()] = excp;
+ xmon_enter();
excprint(excp);
+#ifdef CONFIG_SMP
+ if (test_and_set_bit(smp_processor_id(), &cpus_in_xmon))
+ for (;;)
+ ;
+ while (test_and_set_bit(0, &got_xmon)) {
+ if (take_xmon == smp_processor_id()) {
+ take_xmon = -1;
+ break;
+ }
+ }
+ /*
+ * XXX: breakpoints are removed while any cpu is in xmon
+ */
+#endif /* CONFIG_SMP */
+ remove_bpts();
cmd = cmds(excp);
if (cmd == 's') {
- xmon_trace = SSTEP;
+ xmon_trace[smp_processor_id()] = SSTEP;
excp->msr |= 0x400;
} else if (at_breakpoint(excp->nip)) {
- xmon_trace = BRSTEP;
+ xmon_trace[smp_processor_id()] = BRSTEP;
excp->msr |= 0x400;
} else {
- xmon_trace = 0;
+ xmon_trace[smp_processor_id()] = 0;
insert_bpts();
}
+ xmon_leave();
+ xmon_regs[smp_processor_id()] = 0;
+#ifdef CONFIG_SMP
+ clear_bit(0, &got_xmon);
+ clear_bit(smp_processor_id(), &cpus_in_xmon);
+#endif /* CONFIG_SMP */
set_msr(msr); /* restore interrupt enable */
}
void
xmon_irq(int irq, void *d, struct pt_regs *regs)
{
+ unsigned long flags;
+ save_flags(flags);cli();
printf("Keyboard interrupt\n");
xmon(regs);
+ restore_flags(flags);
}
int
@@ -178,7 +226,7 @@ xmon_bpt(struct pt_regs *regs)
--bp->count;
remove_bpts();
excprint(regs);
- xmon_trace = BRSTEP;
+ xmon_trace[smp_processor_id()] = BRSTEP;
regs->msr |= 0x400;
} else {
xmon(regs);
@@ -189,10 +237,10 @@ xmon_bpt(struct pt_regs *regs)
int
xmon_sstep(struct pt_regs *regs)
{
- if (!xmon_trace)
+ if (!xmon_trace[smp_processor_id()])
return 0;
- if (xmon_trace == BRSTEP) {
- xmon_trace = 0;
+ if (xmon_trace[smp_processor_id()] == BRSTEP) {
+ xmon_trace[smp_processor_id()] = 0;
insert_bpts();
} else {
xmon(regs);
@@ -207,7 +255,7 @@ xmon_dabr_match(struct pt_regs *regs)
--dabr.count;
remove_bpts();
excprint(regs);
- xmon_trace = BRSTEP;
+ xmon_trace[smp_processor_id()] = BRSTEP;
regs->msr |= 0x400;
} else {
dabr.instr = regs->nip;
@@ -223,7 +271,7 @@ xmon_iabr_match(struct pt_regs *regs)
--iabr.count;
remove_bpts();
excprint(regs);
- xmon_trace = BRSTEP;
+ xmon_trace[smp_processor_id()] = BRSTEP;
regs->msr |= 0x400;
} else {
xmon(regs);
@@ -264,6 +312,7 @@ insert_bpts()
bp->address);
bp->enabled = 0;
}
+ store_inst((void *) bp->address);
}
#if !defined(CONFIG_8xx) && !defined(CONFIG_POWER4)
if (dabr.enabled)
@@ -293,6 +342,7 @@ remove_bpts()
&& mwrite(bp->address, &bp->instr, 4) != 4)
printf("Couldn't remove breakpoint at %x\n",
bp->address);
+ store_inst((void *) bp->address);
}
}
@@ -306,6 +356,9 @@ cmds(struct pt_regs *excp)
last_cmd = NULL;
for(;;) {
+#ifdef CONFIG_SMP
+ printf("%d:", smp_processor_id());
+#endif /* CONFIG_SMP */
printf("mon> ");
fflush(stdout);
flush_input();
@@ -383,12 +436,67 @@ cmds(struct pt_regs *excp)
case 'b':
bpt_cmds();
break;
- case 'c':
+ case 'C':
csum();
break;
+#ifdef CONFIG_SMP
+ case 'c':
+ cpu_cmd();
+ break;
+#endif /* CONFIG_SMP */
+ }
+ }
+}
+
+#ifdef CONFIG_SMP
+static void cpu_cmd(void)
+{
+ unsigned cpu;
+ int timeout;
+ int cmd;
+
+ cmd = inchar();
+ if (cmd == 'i') {
+ /* interrupt other cpu(s) */
+ cpu = MSG_ALL_BUT_SELF;
+ scanhex(&cpu);
+ smp_send_xmon_break(cpu);
+ return;
+ }
+ termch = cmd;
+ if (!scanhex(&cpu)) {
+ /* print cpus waiting or in xmon */
+ printf("cpus stopped:");
+ for (cpu = 0; cpu < NR_CPUS; ++cpu) {
+ if (test_bit(cpu, &cpus_in_xmon)) {
+ printf(" %d", cpu);
+ if (cpu == smp_processor_id())
+ printf("*", cpu);
+ }
+ }
+ printf("\n");
+ return;
+ }
+ /* try to switch to cpu specified */
+ take_xmon = cpu;
+ timeout = 10000000;
+ while (take_xmon >= 0) {
+ if (--timeout == 0) {
+ /* yes there's a race here */
+ take_xmon = -1;
+ printf("cpu %u didn't take control\n", cpu);
+ return;
+ }
+ }
+ /* now have to wait to be given control back */
+ while (test_and_set_bit(0, &got_xmon)) {
+ if (take_xmon == smp_processor_id()) {
+ take_xmon = -1;
+ break;
}
}
}
+#endif /* CONFIG_SMP */
static unsigned short fcstab[256] = {
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
@@ -551,6 +659,8 @@ backtrace(struct pt_regs *excp)
extern char lost_irq_ret, do_bottom_half_ret, do_signal_ret;
extern char ret_from_except;
+ printf("backtrace:\n");
+
if (excp != NULL)
sp = excp->gpr[1];
else
@@ -592,6 +702,9 @@ getsp()
void
excprint(struct pt_regs *fp)
{
+#ifdef CONFIG_SMP
+ printf("cpu %d: ", smp_processor_id());
+#endif /* CONFIG_SMP */
printf("vector: %x at pc = %x",
fp->trap, fp->nip);
printf(", lr = %x, msr = %x, sp = %x [%x]\n",
@@ -1163,9 +1276,6 @@ bsesc()
return c;
}
-#define isxdigit(c) (('0' <= (c) && (c) <= '9') \
- || ('a' <= (c) && (c) <= 'f') \
- || ('A' <= (c) && (c) <= 'F'))
void
dump()
{
@@ -1402,6 +1512,16 @@ skipbl()
return c;
}
+#define N_PTREGS 44
+static char *regnames[N_PTREGS] = {
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
+ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
+ "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "pc", "msr", "or3", "ctr", "lr", "xer", "ccr", "mq",
+ "trap", "dar", "dsisr", "res"
+};
+
int
scanhex(vp)
unsigned *vp;
@@ -1410,6 +1530,36 @@ unsigned *vp;
unsigned v;
c = skipbl();
+ if (c == '%') {
+ /* parse register name */
+ char regname[8];
+ int i;
+
+ for (i = 0; i < sizeof(regname) - 1; ++i) {
+ c = inchar();
+ if (!isalnum(c)) {
+ termch = c;
+ break;
+ }
+ regname[i] = c;
+ }
+ regname[i] = 0;
+ for (i = 0; i < N_PTREGS; ++i) {
+ if (strcmp(regnames[i], regname) == 0) {
+ unsigned *rp = (unsigned *)
+ xmon_regs[smp_processor_id()];
+ if (rp == NULL) {
+ printf("regs not available\n");
+ return 0;
+ }
+ *vp = rp[i];
+ return 1;
+ }
+ }
+ printf("invalid register name '%%%s'\n", regname);
+ return 0;
+ }
+
d = hexdigit(c);
if( d == EOF ){
termch = c;
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 6f6a5287b..2fc6d08fa 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -264,6 +264,7 @@ void release_thread(struct task_struct *dead_task)
}
int copy_thread(int nr, unsigned long clone_flags, unsigned long new_stackp,
+ unsigned long unused,
struct task_struct * p, struct pt_regs * regs)
{
struct stack_frame
@@ -313,7 +314,7 @@ asmlinkage int sys_fork(struct pt_regs regs)
int ret;
lock_kernel();
- ret = do_fork(SIGCHLD, regs.gprs[15], &regs);
+ ret = do_fork(SIGCHLD, regs.gprs[15], &regs, 0);
unlock_kernel();
return ret;
}
@@ -329,7 +330,7 @@ asmlinkage int sys_clone(struct pt_regs regs)
newsp = regs.gprs[2];
if (!newsp)
newsp = regs.gprs[15];
- ret = do_fork(clone_flags, newsp, &regs);
+ ret = do_fork(clone_flags, newsp, &regs, 0);
unlock_kernel();
return ret;
}
@@ -347,7 +348,7 @@ asmlinkage int sys_clone(struct pt_regs regs)
asmlinkage int sys_vfork(struct pt_regs regs)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD,
- regs.gprs[15], &regs);
+ regs.gprs[15], &regs, 0);
}
/*
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index fd1a5e58a..a4df59c65 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -528,7 +528,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
default:
lock_kernel();
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 8f72782d2..6cf2e6918 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -528,7 +528,7 @@ static int __init fork_by_hand(void)
/* don't care about the psw and regs settings since we'll never
reschedule the forked task. */
memset(&regs,sizeof(pt_regs),0);
- return do_fork(CLONE_VM|CLONE_PID, 0, &regs);
+ return do_fork(CLONE_VM|CLONE_PID, 0, &regs, 0);
}
static void __init do_boot_cpu(int cpu)
diff --git a/arch/sh/boot/compressed/Makefile b/arch/sh/boot/compressed/Makefile
index bd419991b..7e34e14da 100644
--- a/arch/sh/boot/compressed/Makefile
+++ b/arch/sh/boot/compressed/Makefile
@@ -36,7 +36,7 @@ piggy.o: $(SYSTEM)
$(OBJCOPY) -R .empty_zero_page $(SYSTEM) $$tmppiggy; \
gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
- $(LD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-shl -T $$tmppiggy.lnk; \
+ $(LD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-sh-linux -T $$tmppiggy.lnk; \
rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
clean:
diff --git a/arch/sh/config.in b/arch/sh/config.in
index fa36d92f7..f0a51f8d6 100644
--- a/arch/sh/config.in
+++ b/arch/sh/config.in
@@ -123,6 +123,8 @@ source drivers/mtd/Config.in
source drivers/block/Config.in
+source drivers/md/Config.in
+
if [ "$CONFIG_NET" = "y" ]; then
source net/Config.in
fi
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S
index 7335803da..3b74e2d8e 100644
--- a/arch/sh/kernel/entry.S
+++ b/arch/sh/kernel/entry.S
@@ -14,7 +14,12 @@
#include <linux/linkage.h>
#include <linux/config.h>
-#define COMPAT_OLD_SYSCALL_ABI 1
+
+/*
+ * Define this to turn on compatibility with the previous
+ * system call ABI. This feature is not properly maintained.
+ */
+#undef COMPAT_OLD_SYSCALL_ABI
! NOTE:
! GNU as (as of 2.9.1) changes bf/s into bt/s and bra, when the address
@@ -28,6 +33,12 @@
* NOTE: This code handles signal-recognition, which happens every time
* after a timer-interrupt and after each system call.
*
+ * NOTE: This code uses a convention that instructions in the delay slot
+ * of a transfer-control instruction are indented by an extra space, thus:
+ *
+ * jmp @$k0 ! control-transfer instruction
+ * ldc $k1, $ssr ! delay slot
+ *
* Stack layout in 'ret_from_syscall':
* ptrace needs to have all regs on the stack.
* if the order here is changed, it needs to be
@@ -58,6 +69,7 @@ PT_TRACESYS = 0x00000002
PF_USEDFPU = 0x00100000
ENOSYS = 38
+EINVAL = 22
#if defined(__sh3__)
TRA = 0xffffffd0
@@ -76,7 +88,14 @@ MMU_TEA = 0xff00000c ! TLB Exception Address Register
#endif
/* Offsets to the stack */
-R0 = 0 /* Return value */
+R0 = 0 /* Return value. New ABI also arg4 */
+R1 = 4 /* New ABI: arg5 */
+R2 = 8 /* New ABI: arg6 */
+R3 = 12 /* New ABI: syscall_nr */
+R4 = 16 /* New ABI: arg0 */
+R5 = 20 /* New ABI: arg1 */
+R6 = 24 /* New ABI: arg2 */
+R7 = 28 /* New ABI: arg3 */
SP = (15*4)
SR = (16*4+8)
SYSCALL_NR = (16*4+6*4)
@@ -132,7 +151,6 @@ SYSCALL_NR = (16*4+6*4)
tlb_miss_load:
mov.l 2f, $r0
mov.l @$r0, $r6
- STI()
mov $r15, $r4
mov.l 1f, $r0
jmp @$r0
@@ -142,7 +160,6 @@ tlb_miss_load:
tlb_miss_store:
mov.l 2f, $r0
mov.l @$r0, $r6
- STI()
mov $r15, $r4
mov.l 1f, $r0
jmp @$r0
@@ -152,7 +169,6 @@ tlb_miss_store:
initial_page_write:
mov.l 2f, $r0
mov.l @$r0, $r6
- STI()
mov $r15, $r4
mov.l 1f, $r0
jmp @$r0
@@ -162,7 +178,6 @@ initial_page_write:
tlb_protection_violation_load:
mov.l 2f, $r0
mov.l @$r0, $r6
- STI()
mov $r15, $r4
mov.l 1f, $r0
jmp @$r0
@@ -172,14 +187,13 @@ tlb_protection_violation_load:
tlb_protection_violation_store:
mov.l 2f, $r0
mov.l @$r0, $r6
- STI()
mov $r15, $r4
mov.l 1f, $r0
jmp @$r0
mov #1, $r5
.align 2
-1: .long SYMBOL_NAME(do_page_fault)
+1: .long SYMBOL_NAME(__do_page_fault)
2: .long MMU_TEA
#if defined(CONFIG_DEBUG_KERNEL_WITH_GDB_STUB) || defined(CONFIG_SH_STANDARD_BIOS)
@@ -249,9 +263,6 @@ error:
.align 2
1: .long SYMBOL_NAME(do_exception_error)
-badsys: mov #-ENOSYS, $r0
- rts ! go to ret_from_syscall..
- mov.l $r0, @(R0,$r15)
!
!
@@ -291,7 +302,7 @@ ENTRY(ret_from_fork)
*/
system_call:
- mov.l 1f, $r9
+ mov.l __TRA, $r9
mov.l @$r9, $r8
!
! Is the trap argument >= 0x20? (TRA will be >= 0x80)
@@ -304,122 +315,160 @@ system_call:
mov #SYSCALL_NR, $r14
add $r15, $r14
!
- mov #0x40, $r9
#ifdef COMPAT_OLD_SYSCALL_ABI
+ mov #0x40, $r9
cmp/hs $r9, $r8
- mov $r0, $r10
- bf/s 0f
- mov $r0, $r9
+ bf/s old_abi_system_call
+ nop
#endif
! New Syscall ABI
add #-0x40, $r8
shlr2 $r8
shll8 $r8
- shll8 $r8
+ shll8 $r8 ! $r8 = num_args<<16
mov $r3, $r10
or $r8, $r10 ! Encode syscall # and # of arguments
- !
- mov $r3, $r9
- mov #0, $r8
-0:
mov.l $r10, @$r14 ! set syscall_nr
STI()
- mov.l __n_sys, $r10
- cmp/hs $r10, $r9
- bt badsys
!
-#ifdef COMPAT_OLD_SYSCALL_ABI
- ! Build the stack frame if TRA > 0
- mov $r8, $r10
- cmp/pl $r10
- bf 0f
- mov.l @(SP,$r15), $r0 ! get original stack
-7: add #-4, $r10
-4: mov.l @($r0,$r10), $r1 ! May cause address error exception..
- mov.l $r1, @-$r15
- cmp/pl $r10
- bt 7b
-#endif
-0: stc $k_current, $r11
- mov.l @(tsk_ptrace,$r11), $r10 ! Is it trace?
+ stc $k_current, $r11
+ mov.l @(tsk_ptrace,$r11), $r10 ! Is current PTRACE_SYSCALL'd?
mov #PT_TRACESYS, $r11
tst $r11, $r10
bt 5f
- ! Trace system call
- mov #-ENOSYS, $r11
- mov.l $r11, @(R0,$r15)
- ! Push up $R0--$R2, and $R4--$R7
- mov.l $r0, @-$r15
- mov.l $r1, @-$r15
- mov.l $r2, @-$r15
- mov.l $r4, @-$r15
- mov.l $r5, @-$r15
- mov.l $r6, @-$r15
- mov.l $r7, @-$r15
- !
- mov.l 2f, $r11
- jsr @$r11
+ ! Yes it is traced.
+ mov.l __syscall_trace, $r11 ! Call syscall_trace() which notifies
+ jsr @$r11 ! superior (will chomp $R[0-7])
nop
- ! Pop down $R0--$R2, and $R4--$R7
- mov.l @$r15+, $r7
- mov.l @$r15+, $r6
- mov.l @$r15+, $r5
- mov.l @$r15+, $r4
- mov.l @$r15+, $r2
- mov.l @$r15+, $r1
- mov.l @$r15+, $r0
- !
+ ! Reload $R0-$R4 from kernel stack, where the
+ ! parent may have modified them using
+ ! ptrace(POKEUSR). (Note that $R0-$R2 are
+ ! used by the system call handler directly
+ ! from the kernel stack anyway, so don't need
+ ! to be reloaded here.) This allows the parent
+ ! to rewrite system calls and args on the fly.
+ mov.l @(R4,$r15), $r4 ! arg0
+ mov.l @(R5,$r15), $r5
+ mov.l @(R6,$r15), $r6
+ mov.l @(R7,$r15), $r7 ! arg3
+ mov.l @(R3,$r15), $r3 ! syscall_nr
+ ! Arrange for syscall_trace() to be called
+ ! again as the system call returns.
mov.l __syscall_ret_trace, $r10
bra 6f
lds $r10, $pr
- !
+ ! No it isn't traced.
+ ! Arrange for normal system call return.
5: mov.l __syscall_ret, $r10
lds $r10, $pr
- !
-6: mov $r9, $r10
- shll2 $r10 ! x4
+ ! Call the system call handler through the table.
+ ! (both normal and ptrace'd)
+ ! First check for bad syscall number
+6: mov $r3, $r9
+ mov.l __n_sys, $r10
+ cmp/hs $r10, $r9
+ bf 2f
+ ! Bad syscall number
+ rts ! go to syscall_ret or syscall_ret_trace
+ mov #-ENOSYS, $r0
+ ! Good syscall number
+2: shll2 $r9 ! x4
mov.l __sct, $r11
- add $r11, $r10
- mov.l @$r10, $r11
- jmp @$r11
+ add $r11, $r9
+ mov.l @$r9, $r11
+ jmp @$r11 ! jump to specific syscall handler
nop
! In case of trace
- .align 2
-3:
-#ifdef COMPAT_OLD_SYSCALL_ABI
- add $r8, $r15 ! pop off the arguments
-#endif
+syscall_ret_trace:
mov.l $r0, @(R0,$r15) ! save the return value
- mov.l 2f, $r1
+ mov.l __syscall_trace, $r1
mova SYMBOL_NAME(ret_from_syscall), $r0
- jmp @$r1
- lds $r0, $pr
- .align 2
-1: .long TRA
-2: .long SYMBOL_NAME(syscall_trace)
-__n_sys: .long NR_syscalls
-__sct: .long SYMBOL_NAME(sys_call_table)
-__syscall_ret_trace:
- .long 3b
-__syscall_ret:
- .long SYMBOL_NAME(syscall_ret)
+ jmp @$r1 ! Call syscall_trace() which notifies superior
+ lds $r0, $pr ! Then return to ret_from_syscall()
+
+
#ifdef COMPAT_OLD_SYSCALL_ABI
+! Handle old ABI system call.
+! Note that ptrace(SYSCALL) is not supported for the old ABI.
+! At this point:
+! $r0, $r4-7 as per ABI
+! $r8 = value of TRA register (= num_args<<2)
+! $r14 = points to SYSCALL_NR in stack frame
+old_abi_system_call:
+ mov $r0, $r9 ! Save system call number in $r9
+ ! ! arrange for return which pops stack
+ mov.l __old_abi_syscall_ret, $r10
+ lds $r10, $pr
+ ! Build the stack frame if TRA > 0
+ mov $r8, $r10
+ cmp/pl $r10
+ bf 0f
+ mov.l @(SP,$r15), $r0 ! get original user stack
+7: add #-4, $r10
+4: mov.l @($r0,$r10), $r1 ! May cause address error exception..
+ mov.l $r1, @-$r15
+ cmp/pl $r10
+ bt 7b
+0:
+ mov.l $r9, @$r14 ! set syscall_nr
+ STI()
+ ! Call the system call handler through the table.
+ ! First check for bad syscall number
+ mov.l __n_sys, $r10
+ cmp/hs $r10, $r9
+ bf 2f
+ ! Bad syscall number
+ rts ! return to old_abi_syscall_ret
+ mov #-ENOSYS, $r0
+ ! Good syscall number
+2: shll2 $r9 ! x4
+ mov.l __sct, $r11
+ add $r11, $r9
+ mov.l @$r9, $r11
+ jmp @$r11 ! call specific syscall handler,
+ nop
+
+ .align 2
+__old_abi_syscall_ret:
+ .long old_abi_syscall_ret
+
+ ! This code gets called on address error exception when copying
+ ! syscall arguments from user stack to kernel stack. It is
+ ! supposed to return -EINVAL through old_abi_syscall_ret, but it
+ ! appears to have been broken for a long time in that the $r0
+ ! return value will be saved into the kernel stack relative to $r15
+ ! but the value of $r15 is not correct partway through the loop.
+ ! So the user prog is returned its old $r0 value, not -EINVAL.
+ ! Greg Banks 28 Aug 2000.
.section .fixup,"ax"
fixup_syscall_argerr:
+ ! First get $r15 back to
rts
- mov.l 1f, $r0
-1: .long -22 ! -EINVAL
-.previous
+ mov #-EINVAL, $r0
+ .previous
.section __ex_table, "a"
.align 2
.long 4b,fixup_syscall_argerr
-.previous
+ .previous
#endif
.align 2
+__TRA: .long TRA
+__syscall_trace:
+ .long SYMBOL_NAME(syscall_trace)
+__n_sys:.long NR_syscalls
+__sct: .long SYMBOL_NAME(sys_call_table)
+__syscall_ret_trace:
+ .long syscall_ret_trace
+__syscall_ret:
+ .long SYMBOL_NAME(syscall_ret)
+
+
+
+ .align 2
reschedule:
mova SYMBOL_NAME(ret_from_syscall), $r0
mov.l 1f, $r1
@@ -454,10 +503,12 @@ __INV_IMASK:
.long 0xffffff0f ! ~(IMASK)
.align 2
-syscall_ret:
#ifdef COMPAT_OLD_SYSCALL_ABI
+old_abi_syscall_ret:
add $r8, $r15 ! pop off the arguments
+ /* fall through */
#endif
+syscall_ret:
mov.l $r0, @(R0,$r15) ! save the return value
/* fall through */
@@ -707,7 +758,7 @@ handle_exception:
#endif
8: /* User space to kernel */
mov #0x20, $k1
- shll8 $k1 ! $k1 <= 8192
+ shll8 $k1 ! $k1 <= 8192 == THREAD_SIZE
add $current, $k1
mov $k1, $r15 ! change to kernel stack
!
@@ -1107,6 +1158,7 @@ ENTRY(sys_call_table)
.long SYMBOL_NAME(sys_mincore)
.long SYMBOL_NAME(sys_madvise)
.long SYMBOL_NAME(sys_getdents64) /* 220 */
+ .long SYMBOL_NAME(sys_fcntl64)
/*
* NOTE!! This doesn't have to be exact - we just have
@@ -1114,7 +1166,7 @@ ENTRY(sys_call_table)
* entries. Don't panic if you notice that this hasn't
* been shrunk every time we add a new system call.
*/
- .rept NR_syscalls-220
+ .rept NR_syscalls-221
.long SYMBOL_NAME(sys_ni_syscall)
.endr
diff --git a/arch/sh/kernel/head.S b/arch/sh/kernel/head.S
index db3e8b0a3..f1ac6fd17 100644
--- a/arch/sh/kernel/head.S
+++ b/arch/sh/kernel/head.S
@@ -21,9 +21,9 @@ ENTRY(empty_zero_page)
.long 0x00360000 /* INITRD_START */
.long 0x000a0000 /* INITRD_SIZE */
.long 0
+ .balign 4096,0,4096
.text
- .balign 4096,0,4096
/*
* Condition at the entry of _stext:
*
diff --git a/arch/sh/kernel/io.c b/arch/sh/kernel/io.c
index fca718ece..80f50d9ad 100644
--- a/arch/sh/kernel/io.c
+++ b/arch/sh/kernel/io.c
@@ -1,5 +1,5 @@
/*
- * linux/arch/sh/kernel/io_generic.c
+ * linux/arch/sh/kernel/io.c
*
* Copyright (C) 2000 Stuart Menefy
*
diff --git a/arch/sh/kernel/irq_imask.c b/arch/sh/kernel/irq_imask.c
index 8ac95823b..27d91b372 100644
--- a/arch/sh/kernel/irq_imask.c
+++ b/arch/sh/kernel/irq_imask.c
@@ -41,7 +41,7 @@ static void end_imask_irq(unsigned int irq);
static unsigned int startup_imask_irq(unsigned int irq)
{
- enable_imask_irq(irq);
+ /* Nothing to do */
return 0; /* never anything pending */
}
@@ -71,7 +71,8 @@ void static inline set_interrupt_registers(int ip)
"ldc %0, $sr\n"
"1:"
: "=&z" (__dummy)
- : "r" (~0xf0), "r" (ip << 4));
+ : "r" (~0xf0), "r" (ip << 4)
+ : "t");
}
static void disable_imask_irq(unsigned int irq)
@@ -103,7 +104,7 @@ static void end_imask_irq(unsigned int irq)
static void shutdown_imask_irq(unsigned int irq)
{
- disable_imask_irq(irq);
+ /* Nothing to do */
}
void make_imask_irq(unsigned int irq)
diff --git a/arch/sh/kernel/irq_ipr.c b/arch/sh/kernel/irq_ipr.c
index f229e8a12..918e010e9 100644
--- a/arch/sh/kernel/irq_ipr.c
+++ b/arch/sh/kernel/irq_ipr.c
@@ -128,12 +128,14 @@ void __init init_IRQ(void)
#ifdef SCIF_ERI_IRQ
make_ipr_irq(SCIF_ERI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
make_ipr_irq(SCIF_RXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
+ make_ipr_irq(SCIF_BRI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
make_ipr_irq(SCIF_TXI_IRQ, SCIF_IPR_ADDR, SCIF_IPR_POS, SCIF_PRIORITY);
#endif
#ifdef IRDA_ERI_IRQ
make_ipr_irq(IRDA_ERI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
make_ipr_irq(IRDA_RXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
+ make_ipr_irq(IRDA_BRI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
make_ipr_irq(IRDA_TXI_IRQ, IRDA_IPR_ADDR, IRDA_IPR_POS, IRDA_PRIORITY);
#endif
diff --git a/arch/sh/kernel/process.c b/arch/sh/kernel/process.c
index 60205379c..c7511093b 100644
--- a/arch/sh/kernel/process.c
+++ b/arch/sh/kernel/process.c
@@ -136,11 +136,12 @@ void free_task_struct(struct task_struct *p)
*/
int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
{ /* Don't use this in BL=1(cli). Or else, CPU resets! */
- register unsigned long __sc0 __asm__ ("$r3") = __NR_clone;
- register unsigned long __sc4 __asm__ ("$r4") = (long) flags | CLONE_VM;
- register unsigned long __sc5 __asm__ ("$r5") = 0;
- register unsigned long __sc8 __asm__ ("$r8") = (long) arg;
- register unsigned long __sc9 __asm__ ("$r9") = (long) fn;
+ register unsigned long __sc0 __asm__ ("r0");
+ register unsigned long __sc3 __asm__ ("r3") = __NR_clone;
+ register unsigned long __sc4 __asm__ ("r4") = (long) flags | CLONE_VM;
+ register unsigned long __sc5 __asm__ ("r5") = 0;
+ register unsigned long __sc8 __asm__ ("r8") = (long) arg;
+ register unsigned long __sc9 __asm__ ("r9") = (long) fn;
__asm__("trapa #0x12\n\t" /* Linux/SH system call */
"tst #0xff, $r0\n\t" /* child or parent? */
@@ -148,13 +149,13 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
"jsr @$r9\n\t" /* call fn */
" mov $r8, $r4\n\t" /* push argument */
"mov $r0, $r4\n\t" /* return value to arg of exit */
- "mov %2, $r3\n\t" /* exit */
+ "mov %1, $r3\n\t" /* exit */
"trapa #0x11\n"
"1:"
: "=z" (__sc0)
- : "0" (__sc0), "i" (__NR_exit),
- "r" (__sc4), "r" (__sc5), "r" (__sc8), "r" (__sc9)
- : "memory");
+ : "i" (__NR_exit), "r" (__sc3), "r" (__sc4), "r" (__sc5),
+ "r" (__sc8), "r" (__sc9)
+ : "memory", "t");
return __sc0;
}
@@ -211,6 +212,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
asmlinkage void ret_from_fork(void);
int copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+ unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
struct pt_regs *childregs;
@@ -292,7 +294,7 @@ asmlinkage int sys_fork(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs regs)
{
- return do_fork(SIGCHLD, regs.regs[15], &regs);
+ return do_fork(SIGCHLD, regs.regs[15], &regs, 0);
}
asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
@@ -301,7 +303,7 @@ asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp,
{
if (!newsp)
newsp = regs.regs[15];
- return do_fork(clone_flags, newsp, &regs);
+ return do_fork(clone_flags, newsp, &regs, 0);
}
/*
@@ -318,7 +320,7 @@ asmlinkage int sys_vfork(unsigned long r4, unsigned long r5,
unsigned long r6, unsigned long r7,
struct pt_regs regs)
{
- return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], &regs);
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.regs[15], &regs, 0);
}
/*
diff --git a/arch/sh/kernel/setup_cqreek.c b/arch/sh/kernel/setup_cqreek.c
index ea5dd7ece..af7dfe568 100644
--- a/arch/sh/kernel/setup_cqreek.c
+++ b/arch/sh/kernel/setup_cqreek.c
@@ -1,4 +1,4 @@
-/* $Id: setup_cqreek.c,v 1.1 2000/08/05 06:25:23 gniibe Exp $
+/* $Id: setup_cqreek.c,v 1.5 2000/09/18 05:51:24 gniibe Exp $
*
* arch/sh/kernel/setup_cqreek.c
*
@@ -44,15 +44,24 @@ static unsigned long cqreek_port2addr(unsigned long port)
return ISA_OFFSET + port;
}
+struct cqreek_irq_data {
+ unsigned short mask_port; /* Port of Interrupt Mask Register */
+ unsigned short stat_port; /* Port of Interrupt Status Register */
+ unsigned short bit; /* Value of the bit */
+};
+static struct cqreek_irq_data cqreek_irq_data[NR_IRQS];
+
static void disable_cqreek_irq(unsigned int irq)
{
unsigned long flags;
unsigned short mask;
+ unsigned short mask_port = cqreek_irq_data[irq].mask_port;
+ unsigned short bit = cqreek_irq_data[irq].bit;
save_and_cli(flags);
/* Disable IRQ */
- mask = inw(BRIDGE_ISA_INTR_MASK) & ~(1 << irq);
- outw_p(mask, BRIDGE_ISA_INTR_MASK);
+ mask = inw(mask_port) & ~bit;
+ outw_p(mask, mask_port);
restore_flags(flags);
}
@@ -60,32 +69,29 @@ static void enable_cqreek_irq(unsigned int irq)
{
unsigned long flags;
unsigned short mask;
+ unsigned short mask_port = cqreek_irq_data[irq].mask_port;
+ unsigned short bit = cqreek_irq_data[irq].bit;
save_and_cli(flags);
/* Enable IRQ */
- mask = inw(BRIDGE_ISA_INTR_MASK) | (1 << irq);
- outw_p(mask, BRIDGE_ISA_INTR_MASK);
+ mask = inw(mask_port) | bit;
+ outw_p(mask, mask_port);
restore_flags(flags);
}
-#define CLEAR_AT_ACCEPT
-
static void mask_and_ack_cqreek(unsigned int irq)
{
- inw(BRIDGE_ISA_INTR_STAT);
+ unsigned short stat_port = cqreek_irq_data[irq].stat_port;
+ unsigned short bit = cqreek_irq_data[irq].bit;
+
+ inw(stat_port);
disable_cqreek_irq(irq);
-#ifdef CLEAR_AT_ACCEPT
/* Clear IRQ (it might be edge IRQ) */
- outw_p((1<<irq), BRIDGE_ISA_INTR_STAT);
-#endif
+ outw_p(bit, stat_port);
}
static void end_cqreek_irq(unsigned int irq)
{
-#ifndef CLEAR_AT_ACCEPT
- /* Clear IRQ (it might be edge IRQ) */
- outw_p((1<<irq), BRIDGE_ISA_INTR_STAT);
-#endif
enable_cqreek_irq(irq);
}
@@ -101,7 +107,7 @@ static void shutdown_cqreek_irq(unsigned int irq)
}
static struct hw_interrupt_type cqreek_irq_type = {
- "CQREEK-IRQ",
+ "CqREEK-IRQ",
startup_cqreek_irq,
shutdown_cqreek_irq,
enable_cqreek_irq,
@@ -116,10 +122,24 @@ static int has_ide, has_isa;
What we really need is virtualized IRQ and demultiplexer like HP600 port */
void __init init_cqreek_IRQ(void)
{
- if (has_ide)
- make_ipr_irq(14, IDE_OFFSET+BRIDGE_IDE_INTR_LVL, 0, 0x0f-14);
+ if (has_ide) {
+ cqreek_irq_data[14].mask_port = BRIDGE_IDE_INTR_MASK;
+ cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT;
+ cqreek_irq_data[14].bit = 1;
+
+ irq_desc[14].handler = &cqreek_irq_type;
+ irq_desc[14].status = IRQ_DISABLED;
+ irq_desc[14].action = 0;
+ irq_desc[14].depth = 1;
+
+ disable_cqreek_irq(14);
+ }
if (has_isa) {
+ cqreek_irq_data[10].mask_port = BRIDGE_ISA_INTR_MASK;
+ cqreek_irq_data[10].stat_port = BRIDGE_ISA_INTR_STAT;
+ cqreek_irq_data[10].bit = (1 << 10);
+
/* XXX: Err... we may need demultiplexer for ISA irq... */
irq_desc[10].handler = &cqreek_irq_type;
irq_desc[10].status = IRQ_DISABLED;
@@ -135,10 +155,17 @@ void __init init_cqreek_IRQ(void)
*/
void __init setup_cqreek(void)
{
+ extern void disable_hlt(void);
int i;
/* udelay is not available at setup time yet... */
#define DELAY() do {for (i=0; i<10000; i++) ctrl_inw(0xa0000000);} while(0)
+ /*
+ * XXX: I don't know the reason, but it becomes so fragile with
+ * "sleep", so we need to stop sleeping.
+ */
+ disable_hlt();
+
if ((inw (BRIDGE_FEATURE) & 1)) { /* We have IDE interface */
outw_p(0, BRIDGE_IDE_INTR_LVL);
outw_p(0, BRIDGE_IDE_INTR_MASK);
@@ -219,7 +246,6 @@ struct sh_machine_vector mv_cqreek __initmv = {
mv_init_arch: setup_cqreek,
mv_init_irq: init_cqreek_IRQ,
- mv_port2addr: cqreek_port2addr,
mv_isa_port2addr: cqreek_port2addr,
};
ALIAS_MV(cqreek)
diff --git a/arch/sh/kernel/sh_bios.c b/arch/sh/kernel/sh_bios.c
index 12f716249..81a56b960 100644
--- a/arch/sh/kernel/sh_bios.c
+++ b/arch/sh/kernel/sh_bios.c
@@ -1,4 +1,4 @@
-/* $Id: sh_bios.c,v 1.2 2000/07/26 04:37:32 gniibe Exp $
+/* $Id: sh_bios.c,v 1.3 2000/09/30 03:43:30 gniibe Exp $
*
* linux/arch/sh/kernel/sh_bios.c
* C interface for trapping into the standard LinuxSH BIOS.
@@ -20,11 +20,11 @@
static __inline__ long sh_bios_call(long func, long arg0, long arg1, long arg2, long arg3)
{
- register long r0 __asm__("$r0") = func;
- register long r4 __asm__("$r4") = arg0;
- register long r5 __asm__("$r5") = arg1;
- register long r6 __asm__("$r6") = arg2;
- register long r7 __asm__("$r7") = arg3;
+ register long r0 __asm__("r0") = func;
+ register long r4 __asm__("r4") = arg0;
+ register long r5 __asm__("r5") = arg1;
+ register long r6 __asm__("r6") = arg2;
+ register long r7 __asm__("r7") = arg3;
__asm__ __volatile__("trapa #0x3f"
: "=z" (r0)
: "0" (r0), "r" (r4), "r" (r5), "r" (r6), "r" (r7)
diff --git a/arch/sh/kernel/sh_ksyms.c b/arch/sh/kernel/sh_ksyms.c
index 73d971982..de03cfb19 100644
--- a/arch/sh/kernel/sh_ksyms.c
+++ b/arch/sh/kernel/sh_ksyms.c
@@ -17,6 +17,7 @@
#include <asm/hardirq.h>
#include <asm/delay.h>
#include <asm/irq.h>
+#include <asm/pgtable.h>
extern void dump_thread(struct pt_regs *, struct user *);
extern int dump_fpu(elf_fpregset_t *);
@@ -35,7 +36,35 @@ EXPORT_SYMBOL(csum_partial_copy);
EXPORT_SYMBOL(strtok);
EXPORT_SYMBOL(strpbrk);
EXPORT_SYMBOL(strstr);
+EXPORT_SYMBOL(strlen);
+
+/* mem exports */
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(memmove);
+
+/* this is not provided by arch/sh/lib/*.S but is
+ potentially needed by modules (af_packet.o/unix.o
+ use memcmp, for instance) */
+EXPORT_SYMBOL(memcmp);
#ifdef CONFIG_VT
EXPORT_SYMBOL(screen_info);
#endif
+
+
+#define DECLARE_EXPORT(name) extern void name(void);EXPORT_SYMBOL_NOVERS(name)
+
+/* These symbols are generated by the compiler itself */
+#ifdef __SH4__
+
+DECLARE_EXPORT(__udivsi3_i4);
+DECLARE_EXPORT(__sdivsi3_i4);
+DECLARE_EXPORT(__movstr_i4_even);
+DECLARE_EXPORT(__movstr_i4_odd);
+DECLARE_EXPORT(__ashrdi3);
+DECLARE_EXPORT(__ashldi3);
+
+/* needed by some modules */
+EXPORT_SYMBOL(flush_dcache_page);
+#endif
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c
index 9bdddc9d9..fe2f1b319 100644
--- a/arch/sh/kernel/signal.c
+++ b/arch/sh/kernel/signal.c
@@ -672,7 +672,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
/* FALLTHRU */
default:
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c
index f1e8d28bf..5af1e6de8 100644
--- a/arch/sh/kernel/time.c
+++ b/arch/sh/kernel/time.c
@@ -274,37 +274,6 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
write_unlock(&xtime_lock);
}
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static inline unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
static unsigned long get_rtc_time(void)
{
unsigned int sec, min, hr, wk, day, mon, yr, yr100;
@@ -373,7 +342,8 @@ static __init unsigned int get_cpu_mhz(void)
"bt/s 1b\n\t"
" add #1,%0"
: "=r"(count), "=z" (__dummy)
- : "0" (0), "1" (0));
+ : "0" (0), "1" (0)
+ : "t");
cli();
/*
* SH-3:
diff --git a/arch/sh/kernel/traps.c b/arch/sh/kernel/traps.c
index a9775f306..db11c1247 100644
--- a/arch/sh/kernel/traps.c
+++ b/arch/sh/kernel/traps.c
@@ -131,9 +131,16 @@ void dump_stack(void)
asm("mov $r15, %0" : "=r" (start));
asm("stc $r7_bank, %0" : "=r" (end));
- end += 8192;
+ end += 8192/4;
printk("%08lx:%08lx\n", (unsigned long)start, (unsigned long)end);
- for (p=start; p < end; p++)
- printk("%08lx\n", *p);
+ for (p=start; p < end; p++) {
+ extern long _text, _etext;
+ unsigned long v=*p;
+
+ if ((v >= (unsigned long )&_text)
+ && (v <= (unsigned long )&_etext)) {
+ printk("%08lx\n", v);
+ }
+ }
}
diff --git a/arch/sh/lib/checksum.S b/arch/sh/lib/checksum.S
index 3317b3ccc..c7e96a394 100644
--- a/arch/sh/lib/checksum.S
+++ b/arch/sh/lib/checksum.S
@@ -159,14 +159,14 @@ unsigned int csum_partial_copy_generic (const char *src, char *dst, int len,
* them all but there's no guarantee.
*/
-#define SRC(y...) \
- 9999: y; \
+#define SRC(x,y) \
+ 9999: x,y; \
.section __ex_table, "a"; \
.long 9999b, 6001f ; \
.previous
-#define DST(y...) \
- 9999: y; \
+#define DST(x,y) \
+ 9999: x,y; \
.section __ex_table, "a"; \
.long 9999b, 6002f ; \
.previous
@@ -276,7 +276,7 @@ DST( mov.l r0,@r5 )
DST( mov.l r1,@r5 )
add #4,r5
-SRC( mov.l @r4+,r0 )
+SRC( mov.l @r4+,r0 )
SRC( mov.l @r4+,r1 )
addc r0,r7
DST( mov.l r0,@r5 )
diff --git a/arch/sh/mm/cache.c b/arch/sh/mm/cache.c
index af494b9a3..ab63535e4 100644
--- a/arch/sh/mm/cache.c
+++ b/arch/sh/mm/cache.c
@@ -64,9 +64,9 @@ static struct _cache_system_info cache_system_info = {0,};
#define CACHE_IC_WAY_SHIFT 13
#define CACHE_OC_ENTRY_SHIFT 5
#define CACHE_IC_ENTRY_SHIFT 5
-#define CACHE_OC_ENTRY_MASK 0x3fe0
-#define CACHE_OC_ENTRY_PHYS_MASK 0x0fe0
-#define CACHE_IC_ENTRY_MASK 0x1fe0
+#define CACHE_OC_ENTRY_MASK 0x3fe0
+#define CACHE_OC_ENTRY_PHYS_MASK 0x0fe0
+#define CACHE_IC_ENTRY_MASK 0x1fe0
#define CACHE_IC_NUM_ENTRIES 256
#define CACHE_OC_NUM_ENTRIES 512
#define CACHE_OC_NUM_WAYS 1
@@ -92,7 +92,8 @@ static inline void cache_wback_all(void)
addr = CACHE_OC_ADDRESS_ARRAY|(j<<CACHE_OC_WAY_SHIFT)|
(i<<CACHE_OC_ENTRY_SHIFT);
data = ctrl_inl(addr);
- if (data & CACHE_UPDATED) {
+ if ((data & (CACHE_UPDATED|CACHE_VALID))
+ == (CACHE_UPDATED|CACHE_VALID)) {
data &= ~CACHE_UPDATED;
ctrl_outl(data, addr);
}
@@ -114,17 +115,25 @@ detect_cpu_and_cache_system(void)
*/
addr0 = CACHE_OC_ADDRESS_ARRAY + (3 << 12);
addr1 = CACHE_OC_ADDRESS_ARRAY + (1 << 12);
+
+ /* First, write back & invalidate */
data0 = ctrl_inl(addr0);
- data0 ^= 0x00000001;
- ctrl_outl(data0,addr0);
+ ctrl_outl(data0&~(CACHE_VALID|CACHE_UPDATED), addr0);
+ data1 = ctrl_inl(addr1);
+ ctrl_outl(data1&~(CACHE_VALID|CACHE_UPDATED), addr1);
+
+ /* Next, check if there's shadow or not */
+ data0 = ctrl_inl(addr0);
+ data0 ^= CACHE_VALID;
+ ctrl_outl(data0, addr0);
data1 = ctrl_inl(addr1);
- data2 = data1 ^ 0x00000001;
- ctrl_outl(data2,addr1);
+ data2 = data1 ^ CACHE_VALID;
+ ctrl_outl(data2, addr1);
data3 = ctrl_inl(addr0);
- /* Invaliate them, in case the cache has been enabled already. */
- ctrl_outl(data0&~0x00000001, addr0);
- ctrl_outl(data2&~0x00000001, addr1);
+ /* Lastly, invaliate them. */
+ ctrl_outl(data0&~CACHE_VALID, addr0);
+ ctrl_outl(data2&~CACHE_VALID, addr1);
back_to_P1();
if (data0 == data1 && data2 == data3) { /* Shadow */
@@ -150,8 +159,6 @@ void __init cache_init(void)
detect_cpu_and_cache_system();
ccr = ctrl_inl(CCR);
- if (ccr == CCR_CACHE_VAL)
- return;
jump_to_P2();
if (ccr & CCR_CACHE_ENABLE)
/*
@@ -380,29 +387,114 @@ void flush_cache_page(struct vm_area_struct *vma, unsigned long addr)
}
/*
+ * Write-back & invalidate the cache.
+ *
* After accessing the memory from kernel space (P1-area), we need to
- * write back the cache line to maintain DMA coherency.
+ * write back the cache line.
*
* We search the D-cache to see if we have the entries corresponding to
* the page, and if found, write back them.
*/
+void __flush_page_to_ram(void *kaddr)
+{
+ unsigned long phys, addr, data, i;
+
+ /* Physical address of this page */
+ phys = PHYSADDR(kaddr);
+
+ jump_to_P2();
+ /* Loop all the D-cache */
+ for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
+ addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT);
+ data = ctrl_inl(addr);
+ if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) {
+ data &= ~(CACHE_UPDATED|CACHE_VALID);
+ ctrl_outl(data, addr);
+ }
+ }
+ back_to_P1();
+}
+
void flush_page_to_ram(struct page *pg)
{
+ unsigned long phys;
+
+ /* Physical address of this page */
+ phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START;
+ __flush_page_to_ram(phys_to_virt(phys));
+}
+
+/*
+ * Check entries of the I-cache & D-cache of the page.
+ * (To see "alias" issues)
+ */
+void check_cache_page(struct page *pg)
+{
unsigned long phys, addr, data, i;
+ unsigned long kaddr;
+ unsigned long cache_line_index;
+ int bingo = 0;
/* Physical address of this page */
phys = (pg - mem_map)*PAGE_SIZE + __MEMORY_START;
+ kaddr = phys + PAGE_OFFSET;
+ cache_line_index = (kaddr&CACHE_OC_ENTRY_MASK)>>CACHE_OC_ENTRY_SHIFT;
jump_to_P2();
/* Loop all the D-cache */
for (i=0; i<CACHE_OC_NUM_ENTRIES; i++) {
addr = CACHE_OC_ADDRESS_ARRAY| (i<<CACHE_OC_ENTRY_SHIFT);
data = ctrl_inl(addr);
- if ((data & CACHE_UPDATED) && (data&PAGE_MASK) == phys) {
- data &= ~CACHE_UPDATED;
+ if ((data & (CACHE_UPDATED|CACHE_VALID))
+ == (CACHE_UPDATED|CACHE_VALID)
+ && (data&PAGE_MASK) == phys) {
+ data &= ~(CACHE_VALID|CACHE_UPDATED);
ctrl_outl(data, addr);
+ if ((i^cache_line_index)&0x180)
+ bingo = 1;
+ }
+ }
+
+ cache_line_index &= 0xff;
+ /* Loop all the I-cache */
+ for (i=0; i<CACHE_IC_NUM_ENTRIES; i++) {
+ addr = CACHE_IC_ADDRESS_ARRAY| (i<<CACHE_IC_ENTRY_SHIFT);
+ data = ctrl_inl(addr);
+ if ((data & CACHE_VALID) && (data&PAGE_MASK) == phys) {
+ data &= ~CACHE_VALID;
+ ctrl_outl(data, addr);
+ if (((i^cache_line_index)&0x80))
+ bingo = 2;
}
}
back_to_P1();
+
+ if (bingo) {
+ extern void dump_stack(void);
+
+ if (bingo ==1)
+ printk("BINGO!\n");
+ else
+ printk("Bingo!\n");
+ dump_stack();
+ printk("--------------------\n");
+ }
+}
+
+/* Page is 4K, OC size is 16K, there are four lines. */
+#define CACHE_ALIAS 0x00003000
+
+void clear_user_page(void *to, unsigned long address)
+{
+ clear_page(to);
+ if (((address ^ (unsigned long)to) & CACHE_ALIAS))
+ __flush_page_to_ram(to);
+}
+
+void copy_user_page(void *to, void *from, unsigned long address)
+{
+ copy_page(to, from);
+ if (((address ^ (unsigned long)to) & CACHE_ALIAS))
+ __flush_page_to_ram(to);
}
#endif
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index f2e342f0b..9c06626da 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -28,9 +28,9 @@
#include <asm/mmu_context.h>
extern void die(const char *,struct pt_regs *,long);
-static void __flush_tlb_page(struct mm_struct *mm, unsigned long page);
+static void __flush_tlb_page(unsigned long asid, unsigned long page);
#if defined(__SH4__)
-static void __flush_tlb_phys(struct mm_struct *mm, unsigned long phys);
+static void __flush_tlb_phys(unsigned long phys);
#endif
/*
@@ -85,42 +85,6 @@ bad_area:
return 0;
}
-static void handle_vmalloc_fault(struct mm_struct *mm, unsigned long address)
-{
- pgd_t *dir;
- pmd_t *pmd;
- pte_t *pte;
- pte_t entry;
-
- dir = pgd_offset_k(address);
- pmd = pmd_offset(dir, address);
- if (pmd_none(*pmd)) {
- printk(KERN_ERR "vmalloced area %08lx bad\n", address);
- return;
- }
- if (pmd_bad(*pmd)) {
- pmd_ERROR(*pmd);
- pmd_clear(pmd);
- return;
- }
- pte = pte_offset(pmd, address);
- entry = *pte;
- if (pte_none(entry) || !pte_present(entry) || !pte_write(entry)) {
- printk(KERN_ERR "vmalloced area %08lx bad\n", address);
- return;
- }
-
-#if defined(__SH4__)
- /*
- * ITLB is not affected by "ldtlb" instruction.
- * So, we need to flush the entry by ourselves.
- */
- if (mm)
- __flush_tlb_page(mm, address&PAGE_MASK);
-#endif
- update_mmu_cache(NULL, address, entry);
-}
-
/*
* This routine handles page faults. It determines the address,
* and the problem, and then passes it off to one of the appropriate
@@ -138,11 +102,6 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
tsk = current;
mm = tsk->mm;
- if (address >= VMALLOC_START && address < VMALLOC_END) {
- handle_vmalloc_fault(mm, address);
- return;
- }
-
/*
* If we're in an interrupt or have no user
* context, we must not take the fault..
@@ -272,6 +231,67 @@ do_sigbus:
goto no_context;
}
+static int __do_page_fault1(struct pt_regs *regs, unsigned long writeaccess,
+ unsigned long address)
+{
+ pgd_t *dir;
+ pmd_t *pmd;
+ pte_t *pte;
+ pte_t entry;
+
+ if (address >= VMALLOC_START && address < VMALLOC_END)
+ /* We can change the implementation of P3 area pte entries.
+ set_pgdir and such. */
+ dir = pgd_offset_k(address);
+ else
+ dir = pgd_offset(current->mm, address);
+
+ pmd = pmd_offset(dir, address);
+ if (pmd_none(*pmd))
+ return 1;
+ if (pmd_bad(*pmd)) {
+ pmd_ERROR(*pmd);
+ pmd_clear(pmd);
+ return 1;
+ }
+ pte = pte_offset(pmd, address);
+ entry = *pte;
+ if (pte_none(entry) || !pte_present(entry)
+ || (writeaccess && !pte_write(entry)))
+ return 1;
+
+ if (writeaccess)
+ entry = pte_mkdirty(entry);
+ entry = pte_mkyoung(entry);
+#if defined(__SH4__)
+ /*
+ * ITLB is not affected by "ldtlb" instruction.
+ * So, we need to flush the entry by ourselves.
+ */
+ __flush_tlb_page(get_asid(), address&PAGE_MASK);
+#endif
+ set_pte(pte, entry);
+ update_mmu_cache(NULL, address, entry);
+ return 0;
+}
+
+/*
+ * Called with interrupt disabled.
+ */
+asmlinkage void __do_page_fault(struct pt_regs *regs, unsigned long writeaccess,
+ unsigned long address)
+{
+ /*
+ * XXX: Could you please implement this (calling __do_page_fault1)
+ * in assembler language in entry.S?
+ */
+ if (__do_page_fault1(regs, writeaccess, address) == 0)
+ /* Done. */
+ return;
+ sti();
+ do_page_fault(regs, writeaccess, address);
+}
+
void update_mmu_cache(struct vm_area_struct * vma,
unsigned long address, pte_t pte)
{
@@ -282,28 +302,30 @@ void update_mmu_cache(struct vm_area_struct * vma,
save_and_cli(flags);
#if defined(__SH4__)
- if (vma && (vma->vm_flags & VM_SHARED)) {
+ if (pte_shared(pte)) {
struct page *pg;
pteval = pte_val(pte);
pteval &= PAGE_MASK; /* Physicall page address */
- __flush_tlb_phys(vma->vm_mm, pteval);
+ __flush_tlb_phys(pteval);
pg = virt_to_page(__va(pteval));
flush_dcache_page(pg);
}
#endif
- /* Set PTEH register */
- if (vma) {
- pteaddr = (address & MMU_VPN_MASK) |
- (vma->vm_mm->context & MMU_CONTEXT_ASID_MASK);
- ctrl_outl(pteaddr, MMU_PTEH);
+ /* Ptrace may call this routine. */
+ if (vma && current->active_mm != vma->vm_mm) {
+ restore_flags(flags);
+ return;
}
+ /* Set PTEH register */
+ pteaddr = (address & MMU_VPN_MASK) | get_asid();
+ ctrl_outl(pteaddr, MMU_PTEH);
+
/* Set PTEL register */
pteval = pte_val(pte);
pteval &= _PAGE_FLAGS_HARDWARE_MASK; /* drop software flags */
- pteval |= _PAGE_FLAGS_HARDWARE_DEFAULT; /* add default flags */
ctrl_outl(pteval, MMU_PTEL);
/* Load the TLB */
@@ -311,24 +333,16 @@ void update_mmu_cache(struct vm_area_struct * vma,
restore_flags(flags);
}
-static void __flush_tlb_page(struct mm_struct *mm, unsigned long page)
+static void __flush_tlb_page(unsigned long asid, unsigned long page)
{
- unsigned long addr, data, asid;
- unsigned long saved_asid = MMU_NO_ASID;
-
- if (mm->context == NO_CONTEXT)
- return;
-
- asid = mm->context & MMU_CONTEXT_ASID_MASK;
- if (mm != current->mm) {
- saved_asid = get_asid();
- /*
- * We need to set ASID of the target entry to flush,
- * because TLB is indexed by (ASID and PAGE).
- */
- set_asid(asid);
- }
+ unsigned long addr, data;
+ /*
+ * NOTE: PTEH.ASID should be set to this MM
+ * _AND_ we need to write ASID to the array.
+ *
+ * It would be simple if we didn't need to set PTEH.ASID...
+ */
#if defined(__sh3__)
addr = MMU_TLB_ADDRESS_ARRAY |(page & 0x1F000)| MMU_PAGE_ASSOC_BIT;
data = (page & 0xfffe0000) | asid; /* VALID bit is off */
@@ -340,12 +354,10 @@ static void __flush_tlb_page(struct mm_struct *mm, unsigned long page)
ctrl_outl(data, addr);
back_to_P1();
#endif
- if (saved_asid != MMU_NO_ASID)
- set_asid(saved_asid);
}
#if defined(__SH4__)
-static void __flush_tlb_phys(struct mm_struct *mm, unsigned long phys)
+static void __flush_tlb_phys(unsigned long phys)
{
int i;
unsigned long addr, data;
@@ -373,12 +385,22 @@ static void __flush_tlb_phys(struct mm_struct *mm, unsigned long phys)
void flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
{
- unsigned long flags;
+ if (vma->vm_mm && vma->vm_mm->context != NO_CONTEXT) {
+ unsigned long flags;
+ unsigned long asid;
+ unsigned long saved_asid = MMU_NO_ASID;
- if (vma->vm_mm) {
+ asid = vma->vm_mm->context & MMU_CONTEXT_ASID_MASK;
page &= PAGE_MASK;
+
save_and_cli(flags);
- __flush_tlb_page(vma->vm_mm, page);
+ if (vma->vm_mm != current->mm) {
+ saved_asid = get_asid();
+ set_asid(asid);
+ }
+ __flush_tlb_page(asid, page);
+ if (saved_asid != MMU_NO_ASID)
+ set_asid(saved_asid);
restore_flags(flags);
}
}
@@ -397,13 +419,22 @@ void flush_tlb_range(struct mm_struct *mm, unsigned long start,
if (mm == current->mm)
activate_context(mm);
} else {
+ unsigned long asid = mm->context&MMU_CONTEXT_ASID_MASK;
+ unsigned long saved_asid = MMU_NO_ASID;
+
start &= PAGE_MASK;
end += (PAGE_SIZE - 1);
end &= PAGE_MASK;
+ if (mm != current->mm) {
+ saved_asid = get_asid();
+ set_asid(asid);
+ }
while (start < end) {
- __flush_tlb_page(mm, start);
+ __flush_tlb_page(asid, start);
start += PAGE_SIZE;
}
+ if (saved_asid != MMU_NO_ASID)
+ set_asid(saved_asid);
}
restore_flags(flags);
}
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 5e0632a86..8568afb31 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -227,7 +227,7 @@ void __init paging_init(void)
zones_size[ZONE_DMA] = max_dma - start_pfn;
zones_size[ZONE_NORMAL] = low - max_dma;
}
- free_area_init_node(0, 0, zones_size, __MEMORY_START, 0);
+ free_area_init_node(0, 0, 0, zones_size, __MEMORY_START, 0);
}
}
@@ -241,6 +241,7 @@ void __init mem_init(void)
/* clear the zero-page */
memset(empty_zero_page, 0, PAGE_SIZE);
+ flush_page_to_ram(virt_to_page(empty_zero_page));
/* this will put all low memory onto the freelists */
totalram_pages += free_all_bootmem();
diff --git a/arch/sh/vmlinux.lds.S b/arch/sh/vmlinux.lds.S
index ad1fc1c1b..93ea453cb 100644
--- a/arch/sh/vmlinux.lds.S
+++ b/arch/sh/vmlinux.lds.S
@@ -4,9 +4,9 @@
*/
#include <linux/config.h>
#ifdef CONFIG_CPU_LITTLE_ENDIAN
-OUTPUT_FORMAT("elf32-shl", "elf32-shl", "elf32-shl")
+OUTPUT_FORMAT("elf32-sh-linux", "elf32-sh-linux", "elf32-sh-linux")
#else
-OUTPUT_FORMAT("elf32-sh", "elf32-sh", "elf32-sh")
+OUTPUT_FORMAT("elf32-shbig-linux", "elf32-shbig-linux", "elf32-shbig-linux")
#endif
OUTPUT_ARCH(sh)
ENTRY(_start)
@@ -89,6 +89,7 @@ SECTIONS
/DISCARD/ : {
*(.text.exit)
*(.data.exit)
+ *(.exitcall.exit)
}
/* Stabs debugging sections. */
diff --git a/arch/sparc/config.in b/arch/sparc/config.in
index ef948c181..0a7c2140a 100644
--- a/arch/sparc/config.in
+++ b/arch/sparc/config.in
@@ -94,15 +94,7 @@ dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
# bool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y
#fi
-tristate 'Multiple devices driver support' CONFIG_BLK_DEV_MD
-dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD
-dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD
-dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD
-#dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD
-#if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then
-# bool ' Boot support' CONFIG_MD_BOOT
-# bool ' Auto Detect support' CONFIG_AUTODETECT_RAID
-#fi
+include drivers/md/Config.in
tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
index c8c79591c..d57c23c1f 100644
--- a/arch/sparc/kernel/Makefile
+++ b/arch/sparc/kernel/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.60 2000/08/12 08:35:53 ecd Exp $
+# $Id: Makefile,v 1.61 2000/09/03 13:58:04 anton Exp $
# Makefile for the linux kernel.
#
# Note! Dependencies are done automagically by 'make dep', which also
@@ -22,7 +22,7 @@ IRQ_OBJS := irq.o sun4m_irq.o sun4c_irq.o sun4d_irq.o
O_OBJS := entry.o wof.o wuf.o etrap.o rtrap.o traps.o ${IRQ_OBJS} \
process.o signal.o ioport.o setup.o idprom.o \
sys_sparc.o sunos_asm.o sparc-stub.o systbls.o \
- time.o windows.o cpu.o devices.o sclow.o solaris.o \
+ time.o windows.o cpu.o devices.o sclow.o \
tadpole.o tick14.o ptrace.o sys_solaris.o \
unaligned.o muldiv.o pcic.o semaphore.o
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S
index f701027e0..c44fe3196 100644
--- a/arch/sparc/kernel/entry.S
+++ b/arch/sparc/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.166 2000/06/19 06:24:36 davem Exp $
+/* $Id: entry.S,v 1.167 2000/09/06 00:45:00 davem Exp $
* arch/sparc/kernel/entry.S: Sparc trap low-level entry points.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1391,6 +1391,7 @@ flush_patch_two:
mov %fp, %o1 ! arg1: usp
std %g4, [%curptr + AOFF_task_thread + AOFF_thread_fork_kpsr]
add %sp, REGWIN_SZ, %o2 ! arg2: pt_regs ptr
+ mov 0, %o3
call C_LABEL(do_fork)
mov %l5, %o7
@@ -1413,6 +1414,7 @@ flush_patch_three:
1:
std %g4, [%curptr + AOFF_task_thread + AOFF_thread_fork_kpsr]
add %sp, REGWIN_SZ, %o2 ! arg2: pt_regs ptr
+ mov 0, %o3
call C_LABEL(do_fork)
mov %l5, %o7
@@ -1430,6 +1432,7 @@ flush_patch_four:
mov %fp, %o1
or %o0, %lo(0x4000 | 0x0100 | SIGCHLD), %o0
sethi %hi(C_LABEL(do_fork)), %l1
+ mov 0, %o3
jmpl %l1 + %lo(C_LABEL(do_fork)), %g0
add %sp, REGWIN_SZ, %o2
diff --git a/arch/sparc/kernel/irq.c b/arch/sparc/kernel/irq.c
index f2aa6cae4..eaa7fc4a3 100644
--- a/arch/sparc/kernel/irq.c
+++ b/arch/sparc/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.106 2000/08/05 10:48:40 davem Exp $
+/* $Id: irq.c,v 1.109 2000/08/31 10:00:39 anton Exp $
* arch/sparc/kernel/irq.c: Interrupt request handling routines. On the
* Sparc the IRQ's are basically 'cast in stone'
* and you are supposed to probe the prom's device
@@ -8,7 +8,7 @@
* Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
* Copyright (C) 1995 Pete A. Zaitcev (zaitcev@metabyte.com)
* Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
- * Copyright (C) 1998-99 Anton Blanchard (anton@progsoc.uts.edu.au)
+ * Copyright (C) 1998-2000 Anton Blanchard (anton@linuxcare.com)
*/
#include <linux/config.h>
@@ -196,41 +196,29 @@ void free_irq(unsigned int irq, void *dev_id)
}
#ifdef CONFIG_SMP
-/* SMP interrupt locking on Sparc. */
-/* Who has global_irq_lock. */
+/* Who has the global irq brlock */
unsigned char global_irq_holder = NO_PROC_ID;
-/* This protects IRQ's. */
-spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED;
-
-/* Global IRQ locking depth. */
-atomic_t global_irq_count = ATOMIC_INIT(0);
-
void smp_show_backtrace_all_cpus(void);
void show_backtrace(void);
-#define MAXCOUNT 100000000
#define VERBOSE_DEBUG_IRQLOCK
+#define MAXCOUNT 100000000
static void show(char * str)
{
- int i;
int cpu = smp_processor_id();
+ int i;
printk("\n%s, CPU %d:\n", str, cpu);
- printk("irq: %d [ ", atomic_read(&global_irq_count));
-
- for (i = 0; i < NR_CPUS; i++) {
- printk("%d ", local_irq_count(i));
- }
- printk("]\n");
-
- printk("bh: %d [ ", (spin_is_locked(&global_bh_lock) ? 1 : 0));
-
- for (i = 0; i < NR_CPUS; i++) {
- printk("%d ", local_bh_count(cpu));
- }
+ printk("irq: %d [ ", irqs_running());
+ for (i = 0; i < smp_num_cpus; i++)
+ printk("%u ", __brlock_array[i][BR_GLOBALIRQ_LOCK]);
+ printk("]\nbh: %d [ ",
+ (spin_is_locked(&global_bh_lock) ? 1 : 0));
+ for (i = 0; i < smp_num_cpus; i++)
+ printk("%u ", local_bh_count(i));
printk("]\n");
#ifdef VERBOSE_DEBUG_IRQLOCK
@@ -240,48 +228,11 @@ static void show(char * str)
#endif
}
+
/*
* We have to allow irqs to arrive between __sti and __cli
*/
-#define SYNC_OTHER_CORES(x) udelay(x+1)
-
-static inline void wait_on_irq(int cpu)
-{
- int count = MAXCOUNT;
-
- for (;;) {
- /*
- * Wait until all interrupts are gone. Wait
- * for bottom half handlers unless we're
- * already executing in one..
- */
- if (!atomic_read(&global_irq_count)) {
- if (local_bh_count(cpu) || !spin_is_locked(&global_bh_lock))
- break;
- }
-
- /* Duh, we have to loop. Release the lock to avoid deadlocks */
- spin_unlock(&global_irq_lock);
-
- for (;;) {
- if (!--count) {
- show("wait_on_irq");
- count = ~0;
- }
- __sti();
- SYNC_OTHER_CORES(cpu);
- __cli();
- if (atomic_read(&global_irq_count))
- continue;
- if (spin_is_locked (&global_irq_lock))
- continue;
- if (!local_bh_count(cpu) && spin_is_locked(&global_bh_lock))
- continue;
- if (spin_trylock(&global_irq_lock))
- break;
- }
- }
-}
+#define SYNC_OTHER_CORES(x) barrier()
/*
* This is called when we want to synchronize with
@@ -292,8 +243,7 @@ static inline void wait_on_irq(int cpu)
*/
void synchronize_irq(void)
{
- if (atomic_read(&global_irq_count)) {
- /* Stupid approach */
+ if (irqs_running()) {
cli();
sti();
}
@@ -301,32 +251,37 @@ void synchronize_irq(void)
static inline void get_irqlock(int cpu)
{
- int count = MAXCOUNT;
+ int count;
- if (!spin_trylock(&global_irq_lock)) {
- /* do we already hold the lock? */
- if ((unsigned char) cpu == global_irq_holder)
- return;
- /* Uhhuh.. Somebody else got it. Wait.. */
- do {
- while (spin_is_locked(&global_irq_lock)) {
- if (!--count) {
- show("get_irqlock");
- count = ~0;
- }
- barrier();
+ if ((unsigned char)cpu == global_irq_holder)
+ return;
+
+ count = MAXCOUNT;
+again:
+ br_write_lock(BR_GLOBALIRQ_LOCK);
+ for (;;) {
+ spinlock_t *lock;
+
+ if (!irqs_running() &&
+ (local_bh_count(smp_processor_id()) || !spin_is_locked(&global_bh_lock)))
+ break;
+
+ br_write_unlock(BR_GLOBALIRQ_LOCK);
+ lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock;
+ while (irqs_running() ||
+ spin_is_locked(lock) ||
+ (!local_bh_count(smp_processor_id()) && spin_is_locked(&global_bh_lock))) {
+ if (!--count) {
+ show("get_irqlock");
+ count = (~0 >> 1);
}
- } while (!spin_trylock(&global_irq_lock));
+ __sti();
+ SYNC_OTHER_CORES(cpu);
+ __cli();
+ }
+ goto again;
}
- /*
- * We also to make sure that nobody else is running
- * in an interrupt context.
- */
- wait_on_irq(cpu);
- /*
- * Ok, finally..
- */
global_irq_holder = cpu;
}
@@ -344,7 +299,7 @@ static inline void get_irqlock(int cpu)
*/
void __global_cli(void)
{
- unsigned int flags;
+ unsigned long flags;
__save_flags(flags);
@@ -374,9 +329,8 @@ void __global_sti(void)
*/
unsigned long __global_save_flags(void)
{
- int retval;
- int local_enabled = 0;
- unsigned long flags;
+ unsigned long flags, retval;
+ unsigned long local_enabled = 0;
__save_flags(flags);
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index d5ce7038a..028612687 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -1,4 +1,4 @@
-/* $Id: pcic.c,v 1.16 2000/07/11 01:38:57 davem Exp $
+/* $Id: pcic.c,v 1.18 2000/09/25 06:09:12 anton Exp $
* pcic.c: Sparc/PCI controller support
*
* Copyright (C) 1998 V. Roganov and G. Raiko
@@ -35,11 +35,6 @@
#ifndef CONFIG_PCI
-int pcibios_present(void)
-{
- return 0;
-}
-
asmlinkage int sys_pciconfig_read(unsigned long bus,
unsigned long dfn,
unsigned long off,
@@ -940,7 +935,6 @@ asmlinkage int sys_pciconfig_read(unsigned long bus,
if(!suser())
return -EPERM;
- lock_kernel();
switch(len) {
case 1:
pcibios_read_config_byte(bus, dfn, off, &ubyte);
@@ -959,7 +953,6 @@ asmlinkage int sys_pciconfig_read(unsigned long bus,
err = -EINVAL;
break;
};
- unlock_kernel();
return err;
}
@@ -978,7 +971,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus,
if(!suser())
return -EPERM;
- lock_kernel();
switch(len) {
case 1:
err = get_user(ubyte, (unsigned char *)buf);
@@ -1006,7 +998,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus,
break;
};
- unlock_kernel();
return err;
}
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c
index f119c59ac..fe45f1f3c 100644
--- a/arch/sparc/kernel/process.c
+++ b/arch/sparc/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.151 2000/07/11 23:22:17 davem Exp $
+/* $Id: process.c,v 1.153 2000/09/06 00:45:01 davem Exp $
* linux/arch/sparc/kernel/process.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -234,7 +234,6 @@ void show_backtrace(void)
void smp_show_backtrace_all_cpus(void)
{
xc0((smpfunc_t) show_backtrace);
- show_backtrace();
}
#endif
@@ -462,6 +461,7 @@ extern void ret_from_syscall(void);
#endif
int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+ unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
struct pt_regs *childregs;
diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c
index 5398a9381..bce4ffcdf 100644
--- a/arch/sparc/kernel/setup.c
+++ b/arch/sparc/kernel/setup.c
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.118 2000/05/09 17:40:13 davem Exp $
+/* $Id: setup.c,v 1.119 2000/08/31 10:24:17 anton Exp $
* linux/arch/sparc/kernel/setup.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -80,12 +80,7 @@ void prom_sync_me(void)
{
unsigned long prom_tbr, flags;
-#ifdef CONFIG_SMP
- global_irq_holder = NO_PROC_ID;
- *((unsigned char *)&global_irq_lock) = 0;
- *((unsigned char *)&global_bh_lock) = 0;
-#endif
- __save_and_cli(flags);
+ save_and_cli(flags);
__asm__ __volatile__("rd %%tbr, %0\n\t" : "=r" (prom_tbr));
__asm__ __volatile__("wr %0, 0x0, %%tbr\n\t"
"nop\n\t"
@@ -99,9 +94,9 @@ void prom_sync_me(void)
prom_printf("PROM SYNC COMMAND...\n");
show_free_areas();
if(current->pid != 0) {
- __sti();
+ sti();
sys_sync();
- __cli();
+ cli();
}
prom_printf("Returning to prom\n");
@@ -109,7 +104,7 @@ void prom_sync_me(void)
"nop\n\t"
"nop\n\t"
"nop\n\t" : : "r" (prom_tbr));
- __restore_flags(flags);
+ restore_flags(flags);
return;
}
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c
index bcad13dbc..6ac8c4b00 100644
--- a/arch/sparc/kernel/signal.c
+++ b/arch/sparc/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.106 2000/07/07 04:25:17 davem Exp $
+/* $Id: signal.c,v 1.107 2000/09/05 21:44:54 davem Exp $
* linux/arch/sparc/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -1282,7 +1282,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
#endif
/* fall through */
default:
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
diff --git a/arch/sparc/kernel/smp.c b/arch/sparc/kernel/smp.c
index 677b2c811..0e1944411 100644
--- a/arch/sparc/kernel/smp.c
+++ b/arch/sparc/kernel/smp.c
@@ -145,35 +145,33 @@ void __init smp_boot_cpus(void)
void smp_flush_cache_all(void)
{
xc0((smpfunc_t) BTFIXUP_CALL(local_flush_cache_all));
- local_flush_cache_all();
}
void smp_flush_tlb_all(void)
{
xc0((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_all));
- local_flush_tlb_all();
}
void smp_flush_cache_mm(struct mm_struct *mm)
{
if(mm->context != NO_CONTEXT) {
- if(mm->cpu_vm_mask != (1 << smp_processor_id()))
+ if(mm->cpu_vm_mask == (1 << smp_processor_id()))
+ local_flush_cache_mm(mm);
+ else
xc1((smpfunc_t) BTFIXUP_CALL(local_flush_cache_mm), (unsigned long) mm);
-
- local_flush_cache_mm(mm);
}
}
void smp_flush_tlb_mm(struct mm_struct *mm)
{
if(mm->context != NO_CONTEXT) {
- if(mm->cpu_vm_mask != (1 << smp_processor_id())) {
+ if(mm->cpu_vm_mask == (1 << smp_processor_id())) {
+ local_flush_tlb_mm(mm);
+ } else {
xc1((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_mm), (unsigned long) mm);
if(atomic_read(&mm->mm_users) == 1 && current->active_mm == mm)
mm->cpu_vm_mask = (1 << smp_processor_id());
}
-
- local_flush_tlb_mm(mm);
}
}
@@ -181,10 +179,10 @@ void smp_flush_cache_range(struct mm_struct *mm, unsigned long start,
unsigned long end)
{
if(mm->context != NO_CONTEXT) {
- if(mm->cpu_vm_mask != (1 << smp_processor_id()))
+ if(mm->cpu_vm_mask == (1 << smp_processor_id()))
+ local_flush_cache_range(mm, start, end);
+ else
xc3((smpfunc_t) BTFIXUP_CALL(local_flush_cache_range), (unsigned long) mm, start, end);
-
- local_flush_cache_range(mm, start, end);
}
}
@@ -192,10 +190,10 @@ void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start,
unsigned long end)
{
if(mm->context != NO_CONTEXT) {
- if(mm->cpu_vm_mask != (1 << smp_processor_id()))
+ if(mm->cpu_vm_mask == (1 << smp_processor_id()))
+ local_flush_tlb_range(mm, start, end);
+ else
xc3((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_range), (unsigned long) mm, start, end);
-
- local_flush_tlb_range(mm, start, end);
}
}
@@ -204,10 +202,10 @@ void smp_flush_cache_page(struct vm_area_struct *vma, unsigned long page)
struct mm_struct *mm = vma->vm_mm;
if(mm->context != NO_CONTEXT) {
- if(mm->cpu_vm_mask != (1 << smp_processor_id()))
+ if(mm->cpu_vm_mask == (1 << smp_processor_id()))
+ local_flush_cache_page(vma, page);
+ else
xc2((smpfunc_t) BTFIXUP_CALL(local_flush_cache_page), (unsigned long) vma, page);
-
- local_flush_cache_page(vma, page);
}
}
@@ -216,10 +214,10 @@ void smp_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
struct mm_struct *mm = vma->vm_mm;
if(mm->context != NO_CONTEXT) {
- if(mm->cpu_vm_mask != (1 << smp_processor_id()))
+ if(mm->cpu_vm_mask == (1 << smp_processor_id()))
+ local_flush_tlb_page(vma, page);
+ else
xc2((smpfunc_t) BTFIXUP_CALL(local_flush_tlb_page), (unsigned long) vma, page);
-
- local_flush_tlb_page(vma, page);
}
}
@@ -233,7 +231,6 @@ void smp_flush_page_to_ram(unsigned long page)
*/
#if 1
xc1((smpfunc_t) BTFIXUP_CALL(local_flush_page_to_ram), page);
- local_flush_page_to_ram(page);
#else
local_flush_page_to_ram(page);
#endif
@@ -241,10 +238,10 @@ void smp_flush_page_to_ram(unsigned long page)
void smp_flush_sig_insns(struct mm_struct *mm, unsigned long insn_addr)
{
- if(mm->cpu_vm_mask != (1 << smp_processor_id()))
+ if(mm->cpu_vm_mask == (1 << smp_processor_id()))
+ local_flush_sig_insns(mm, insn_addr);
+ else
xc2((smpfunc_t) BTFIXUP_CALL(local_flush_sig_insns), (unsigned long) mm, insn_addr);
-
- local_flush_sig_insns(mm, insn_addr);
}
/* Reschedule call back. */
diff --git a/arch/sparc/kernel/solaris.c b/arch/sparc/kernel/solaris.c
deleted file mode 100644
index bcebd9262..000000000
--- a/arch/sparc/kernel/solaris.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/* solaris.c: Solaris binary emulation, whee...
- *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
- */
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/smp_lock.h>
-
-#include <asm/errno.h>
-#include <asm/solerrno.h>
-
-asmlinkage int solaris_open(const char *filename, int flags, int mode)
-{
- int newflags;
- int ret;
-
- lock_kernel();
- newflags = flags & 0xf;
- flags &= ~0xf;
- if(flags & 0x8050)
- newflags |= FASYNC;
- if(flags & 0x80)
- newflags |= O_NONBLOCK;
- if(flags & 0x100)
- newflags |= O_CREAT;
- if(flags & 0x200)
- newflags |= O_TRUNC;
- if(flags & 0x400)
- newflags |= O_EXCL;
- if(flags & 0x800)
- newflags |= O_NOCTTY;
- ret = sys_open(filename, newflags, mode);
- unlock_kernel();
- return ret;
-}
diff --git a/arch/sparc/kernel/sparc-stub.c b/arch/sparc/kernel/sparc-stub.c
index c9bb60a86..a0e5f6ad2 100644
--- a/arch/sparc/kernel/sparc-stub.c
+++ b/arch/sparc/kernel/sparc-stub.c
@@ -123,7 +123,7 @@ extern char getDebugChar(void); /* read and return a single char */
*/
#define BUFMAX 2048
-static int initialized = 0; /* !0 means we've been initialized */
+static int initialized; /* !0 means we've been initialized */
static const char hexchars[]="0123456789abcdef";
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c
index e05b20f4e..997e4d0ce 100644
--- a/arch/sparc/kernel/sparc_ksyms.c
+++ b/arch/sparc/kernel/sparc_ksyms.c
@@ -1,4 +1,4 @@
-/* $Id: sparc_ksyms.c,v 1.102 2000/08/05 10:48:40 davem Exp $
+/* $Id: sparc_ksyms.c,v 1.104 2000/09/06 05:43:00 anton Exp $
* arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -111,13 +111,6 @@ EXPORT_SYMBOL_PRIVATE(_rw_read_enter);
EXPORT_SYMBOL_PRIVATE(_rw_read_exit);
EXPORT_SYMBOL_PRIVATE(_rw_write_enter);
#endif
-#ifdef CONFIG_SMP
-EXPORT_SYMBOL(__global_save_flags);
-EXPORT_SYMBOL(__global_restore_flags);
-EXPORT_SYMBOL(__global_sti);
-EXPORT_SYMBOL(__global_cli);
-#endif
-
/* rw semaphores */
EXPORT_SYMBOL_NOVERS(___down_read);
EXPORT_SYMBOL_NOVERS(___down_write);
@@ -137,14 +130,22 @@ EXPORT_SYMBOL_PRIVATE(_change_bit);
EXPORT_SYMBOL_PRIVATE(_set_le_bit);
EXPORT_SYMBOL_PRIVATE(_clear_le_bit);
-/* IRQ implementation. */
#ifdef CONFIG_SMP
+/* Kernel wide locking */
EXPORT_SYMBOL(kernel_flag);
+
+/* IRQ implementation. */
EXPORT_SYMBOL(global_irq_holder);
-EXPORT_SYMBOL(global_irq_lock);
-EXPORT_SYMBOL(global_bh_lock);
-EXPORT_SYMBOL(global_irq_count);
EXPORT_SYMBOL(synchronize_irq);
+EXPORT_SYMBOL(__global_cli);
+EXPORT_SYMBOL(__global_sti);
+EXPORT_SYMBOL(__global_save_flags);
+EXPORT_SYMBOL(__global_restore_flags);
+
+/* Misc SMP information */
+EXPORT_SYMBOL(smp_num_cpus);
+EXPORT_SYMBOL(__cpu_number_map);
+EXPORT_SYMBOL(__cpu_logical_map);
#endif
EXPORT_SYMBOL(udelay);
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index 280392629..3a4e93eb8 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -376,6 +376,9 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
}
}
+ /* First, run local copy. */
+ func(arg1, arg2, arg3, arg4, arg5);
+
{
register int i;
@@ -393,6 +396,8 @@ void smp4d_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
}
spin_unlock_irqrestore(&cross_call_lock, flags);
+ } else {
+ func(arg1, arg2, arg3, arg4, arg5); /* Just need to run local copy. */
}
}
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c
index d6c126d00..52c37f51b 100644
--- a/arch/sparc/kernel/sun4m_smp.c
+++ b/arch/sparc/kernel/sun4m_smp.c
@@ -405,6 +405,9 @@ void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
}
}
+ /* First, run local copy. */
+ func(arg1, arg2, arg3, arg4, arg5);
+
{
register int i;
@@ -422,6 +425,8 @@ void smp4m_cross_call(smpfunc_t func, unsigned long arg1, unsigned long arg2,
}
spin_unlock_irqrestore(&cross_call_lock, flags);
+ } else {
+ func(arg1, arg2, arg3, arg4, arg5); /* Just need to run local copy. */
}
}
diff --git a/arch/sparc/kernel/sunos_ioctl.c b/arch/sparc/kernel/sunos_ioctl.c
index dc26d2cc2..61df3ea6d 100644
--- a/arch/sparc/kernel/sunos_ioctl.c
+++ b/arch/sparc/kernel/sunos_ioctl.c
@@ -1,4 +1,4 @@
-/* $Id: sunos_ioctl.c,v 1.33 1999/07/28 12:59:03 anton Exp $
+/* $Id: sunos_ioctl.c,v 1.34 2000/09/03 14:10:56 anton Exp $
* sunos_ioctl.c: The Linux Operating system: SunOS ioctl compatibility.
*
* Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -39,7 +39,6 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
{
int ret = -EBADF;
- lock_kernel();
if (fd >= SUNOS_NR_OPEN || !fcheck(fd))
goto out;
@@ -227,7 +226,6 @@ asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
/* so stupid... */
ret = (ret == -EINVAL ? -EOPNOTSUPP : ret);
out:
- unlock_kernel();
return ret;
}
diff --git a/arch/sparc/kernel/sys_solaris.c b/arch/sparc/kernel/sys_solaris.c
index d099c4e8a..fb7578554 100644
--- a/arch/sparc/kernel/sys_solaris.c
+++ b/arch/sparc/kernel/sys_solaris.c
@@ -16,30 +16,13 @@
#include <linux/smp_lock.h>
#include <linux/module.h>
-/* CHECKME: this stuff looks rather bogus */
asmlinkage int
do_solaris_syscall (struct pt_regs *regs)
{
- int ret;
-
- lock_kernel();
- set_personality(PER_SVR4);
-
- if (current->exec_domain && current->exec_domain->handler){
- current->exec_domain->handler (0, regs);
-
- /* What is going on here? Why do we do this? */
-
- /* XXX current->exec_domain->use_count = 0; XXX */
-
- ret = regs->u_regs [UREG_I0];
- } else {
- printk ("No solaris handler\n");
- send_sig (SIGSEGV, current, 1);
- ret = 0;
- }
- unlock_kernel();
- return ret;
+ static int cnt = 0;
+ if (++cnt < 10) printk ("No solaris handler\n");
+ force_sig(SIGSEGV, current);
+ return 0;
}
#ifndef CONFIG_SUNOS_EMUL
@@ -48,9 +31,7 @@ do_sunos_syscall (struct pt_regs *regs)
{
static int cnt = 0;
if (++cnt < 10) printk ("SunOS binary emulation not compiled in\n");
- lock_kernel();
force_sig (SIGSEGV, current);
- unlock_kernel();
return 0;
}
#endif
diff --git a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
index 43ffb3d33..980981592 100644
--- a/arch/sparc/kernel/time.c
+++ b/arch/sparc/kernel/time.c
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.56 2000/06/13 22:51:28 anton Exp $
+/* $Id: time.c,v 1.57 2000/09/16 07:33:45 davem Exp $
* linux/arch/sparc/kernel/time.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -149,37 +149,6 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs * regs)
write_unlock(&xtime_lock);
}
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static inline unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
/* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
static void __init kick_start_clock(void)
{
diff --git a/arch/sparc/kernel/traps.c b/arch/sparc/kernel/traps.c
index 3564a4517..5c361f933 100644
--- a/arch/sparc/kernel/traps.c
+++ b/arch/sparc/kernel/traps.c
@@ -1,4 +1,4 @@
-/* $Id: traps.c,v 1.63 2000/06/04 06:23:52 anton Exp $
+/* $Id: traps.c,v 1.64 2000/09/03 15:00:49 anton Exp $
* arch/sparc/kernel/traps.c
*
* Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -132,7 +132,6 @@ void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc)
{
siginfo_t info;
- lock_kernel();
if(type < 0x80) {
/* Sun OS's puke from bad traps, Linux survives! */
printk("Unimplemented Sparc TRAP, type = %02lx\n", type);
@@ -148,7 +147,6 @@ void do_hw_interrupt(unsigned long type, unsigned long psr, unsigned long pc)
info.si_addr = (void *)pc;
info.si_trapno = type - 0x80;
force_sig_info(SIGILL, &info, current);
- unlock_kernel();
}
void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc,
@@ -156,7 +154,6 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon
{
siginfo_t info;
- lock_kernel();
if(psr & PSR_PS)
die_if_kernel("Kernel illegal instruction", regs);
#ifdef TRAP_DEBUG
@@ -166,7 +163,7 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon
if (sparc_cpu_model == sun4c || sparc_cpu_model == sun4) {
extern int do_user_muldiv (struct pt_regs *, unsigned long);
if (!do_user_muldiv (regs, pc))
- goto out;
+ return;
}
info.si_signo = SIGILL;
info.si_errno = 0;
@@ -174,8 +171,6 @@ void do_illegal_instruction(struct pt_regs *regs, unsigned long pc, unsigned lon
info.si_addr = (void *)pc;
info.si_trapno = 0;
send_sig_info(SIGILL, &info, current);
-out:
- unlock_kernel();
}
void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long npc,
@@ -183,7 +178,6 @@ void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long n
{
siginfo_t info;
- lock_kernel();
if(psr & PSR_PS)
die_if_kernel("Penguin instruction from Penguin mode??!?!", regs);
info.si_signo = SIGILL;
@@ -192,7 +186,6 @@ void do_priv_instruction(struct pt_regs *regs, unsigned long pc, unsigned long n
info.si_addr = (void *)pc;
info.si_trapno = 0;
send_sig_info(SIGILL, &info, current);
- unlock_kernel();
}
/* XXX User may want to be allowed to do this. XXX */
@@ -202,7 +195,6 @@ void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned lon
{
siginfo_t info;
- lock_kernel();
if(regs->psr & PSR_PS) {
printk("KERNEL MNA at pc %08lx npc %08lx called by %08lx\n", pc, npc,
regs->u_regs[UREG_RETPC]);
@@ -220,7 +212,6 @@ void do_memaccess_unaligned(struct pt_regs *regs, unsigned long pc, unsigned lon
info.si_addr = /* FIXME: Should dig out mna address */ (void *)0;
info.si_trapno = 0;
send_sig_info(SIGBUS, &info, current);
- unlock_kernel();
}
extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
@@ -237,7 +228,6 @@ static unsigned long init_fregs[32] __attribute__ ((aligned (8))) =
void do_fpd_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
unsigned long psr)
{
- lock_kernel();
/* Sanity check... */
if(psr & PSR_PS)
die_if_kernel("Kernel gets FloatingPenguinUnit disabled trap", regs);
@@ -246,7 +236,7 @@ void do_fpd_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
regs->psr |= PSR_EF;
#ifndef CONFIG_SMP
if(last_task_used_math == current)
- goto out;
+ return;
if(last_task_used_math) {
/* Other processes fpu state, save away */
struct task_struct *fptask = last_task_used_math;
@@ -270,10 +260,6 @@ void do_fpd_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
}
current->flags |= PF_USEDFPU;
#endif
-#ifndef CONFIG_SMP
-out:
-#endif
- unlock_kernel();
}
static unsigned long fake_regs[32] __attribute__ ((aligned (8)));
@@ -295,7 +281,6 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
#else
struct task_struct *fpt = current;
#endif
- lock_kernel();
put_psr(get_psr() | PSR_EF);
/* If nobody owns the fpu right now, just clear the
* error into our fake static buffer and hope it don't
@@ -308,7 +293,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
#endif
fpsave(&fake_regs[0], &fake_fsr, &fake_queue[0], &fake_depth);
regs->psr &= ~PSR_EF;
- goto out;
+ return;
}
fpsave(&fpt->thread.float_regs[0], &fpt->thread.fsr,
&fpt->thread.fpqueue[0], &fpt->thread.fpqdepth);
@@ -361,7 +346,7 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
if(calls > 2)
die_if_kernel("Too many Penguin-FPU traps from kernel mode",
regs);
- goto out;
+ return;
}
fsr = fpt->thread.fsr;
@@ -389,8 +374,6 @@ void do_fpe_trap(struct pt_regs *regs, unsigned long pc, unsigned long npc,
regs->psr &= ~PSR_EF;
if(calls > 0)
calls=0;
-out:
- unlock_kernel();
}
void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long npc,
@@ -398,7 +381,6 @@ void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long n
{
siginfo_t info;
- lock_kernel();
if(psr & PSR_PS)
die_if_kernel("Penguin overflow trap from kernel mode", regs);
info.si_signo = SIGEMT;
@@ -407,13 +389,11 @@ void handle_tag_overflow(struct pt_regs *regs, unsigned long pc, unsigned long n
info.si_addr = (void *)pc;
info.si_trapno = 0;
send_sig_info(SIGEMT, &info, current);
- unlock_kernel();
}
void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc,
unsigned long psr)
{
- lock_kernel();
#ifdef TRAP_DEBUG
printk("Watchpoint detected at PC %08lx NPC %08lx PSR %08lx\n",
pc, npc, psr);
@@ -421,7 +401,6 @@ void handle_watchpoint(struct pt_regs *regs, unsigned long pc, unsigned long npc
if(psr & PSR_PS)
panic("Tell me what a watchpoint trap is, and I'll then deal "
"with such a beast...");
- unlock_kernel();
}
void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc,
@@ -429,7 +408,6 @@ void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc
{
siginfo_t info;
- lock_kernel();
#ifdef TRAP_DEBUG
printk("Register Access Exception at PC %08lx NPC %08lx PSR %08lx\n",
pc, npc, psr);
@@ -440,7 +418,6 @@ void handle_reg_access(struct pt_regs *regs, unsigned long pc, unsigned long npc
info.si_addr = (void *)pc;
info.si_trapno = 0;
force_sig_info(SIGBUS, &info, current);
- unlock_kernel();
}
void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long npc,
@@ -448,14 +425,12 @@ void handle_cp_disabled(struct pt_regs *regs, unsigned long pc, unsigned long np
{
siginfo_t info;
- lock_kernel();
info.si_signo = SIGILL;
info.si_errno = 0;
info.si_code = ILL_COPROC;
info.si_addr = (void *)pc;
info.si_trapno = 0;
send_sig_info(SIGILL, &info, current);
- unlock_kernel();
}
void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long npc,
@@ -463,7 +438,6 @@ void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long n
{
siginfo_t info;
- lock_kernel();
#ifdef TRAP_DEBUG
printk("Co-Processor Exception at PC %08lx NPC %08lx PSR %08lx\n",
pc, npc, psr);
@@ -474,7 +448,6 @@ void handle_cp_exception(struct pt_regs *regs, unsigned long pc, unsigned long n
info.si_addr = (void *)pc;
info.si_trapno = 0;
send_sig_info(SIGILL, &info, current);
- unlock_kernel();
}
void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc,
@@ -482,15 +455,12 @@ void handle_hw_divzero(struct pt_regs *regs, unsigned long pc, unsigned long npc
{
siginfo_t info;
- lock_kernel();
info.si_signo = SIGFPE;
info.si_errno = 0;
info.si_code = FPE_INTDIV;
info.si_addr = (void *)pc;
info.si_trapno = 0;
send_sig_info(SIGFPE, &info, current);
-
- unlock_kernel();
}
/* Since we have our mappings set up, on multiprocessors we can spin them
diff --git a/arch/sparc/mm/init.c b/arch/sparc/mm/init.c
index b323ccacd..642c986bd 100644
--- a/arch/sparc/mm/init.c
+++ b/arch/sparc/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.91 2000/08/09 23:10:19 anton Exp $
+/* $Id: init.c,v 1.93 2000/08/31 11:40:55 anton Exp $
* linux/arch/sparc/mm/init.c
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -89,8 +89,6 @@ pgprot_t kmap_prot;
void __init kmap_init(void)
{
- unsigned long pteval;
-
/* cache the first kmap pte */
kmap_pte = kmap_get_fixed_pte(FIX_KMAP_BEGIN);
kmap_prot = __pgprot(SRMMU_ET_PTE | SRMMU_PRIV | SRMMU_CACHE);
@@ -583,6 +581,6 @@ void flush_page_to_ram(struct page *page)
{
unsigned long vaddr;
vaddr = kmap(page);
- __flush_page_to_ram(page_address(page));
+ __flush_page_to_ram((unsigned long)page_address(page));
kunmap(page);
}
diff --git a/arch/sparc/mm/srmmu.c b/arch/sparc/mm/srmmu.c
index 4f5bd16c5..408d59cbf 100644
--- a/arch/sparc/mm/srmmu.c
+++ b/arch/sparc/mm/srmmu.c
@@ -1,4 +1,4 @@
-/* $Id: srmmu.c,v 1.221 2000/08/14 00:46:13 anton Exp $
+/* $Id: srmmu.c,v 1.222 2000/08/29 08:59:23 davem Exp $
* srmmu.c: SRMMU specific routines for memory management.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -1323,8 +1323,8 @@ static void srmmu_vac_update_mmu_cache(struct vm_area_struct * vma,
mapping = file->f_dentry->d_inode->i_mapping;
offset = (address & PAGE_MASK) - vma->vm_start;
spin_lock(&mapping->i_shared_lock);
- vmaring = mapping->i_mmap;
- do {
+ vmaring = mapping->i_mmap_shared;
+ if (vmaring != NULL) do {
/* Do not mistake ourselves as another mapping. */
if(vmaring == vma)
continue;
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index 66bc3af7b..a99ce736e 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -1,4 +1,4 @@
-/* $Id: sun4c.c,v 1.198 2000/08/14 00:46:13 anton Exp $
+/* $Id: sun4c.c,v 1.199 2000/08/29 08:59:23 davem Exp $
* sun4c.c: Doing in software what should be done in hardware.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -2404,8 +2404,8 @@ static void sun4c_vac_alias_fixup(struct vm_area_struct *vma, unsigned long addr
mapping = vma->vm_file->f_dentry->d_inode->i_mapping;
spin_lock(&mapping->i_shared_lock);
- vmaring = mapping->i_mmap;
- do {
+ vmaring = mapping->i_mmap_shared;
+ if (vmaring != NULL) do {
unsigned long vaddr = vmaring->vm_start + offset;
unsigned long start;
diff --git a/arch/sparc/prom/console.c b/arch/sparc/prom/console.c
index c2b857459..bf61ff1a7 100644
--- a/arch/sparc/prom/console.c
+++ b/arch/sparc/prom/console.c
@@ -1,4 +1,4 @@
-/* $Id: console.c,v 1.22 2000/02/08 20:24:23 davem Exp $
+/* $Id: console.c,v 1.23 2000/08/26 02:38:03 anton Exp $
* console.c: Routines that deal with sending and receiving IO
* to/from the current console device using the PROM.
*
@@ -30,7 +30,7 @@ prom_nbgetchar(void)
int i = -1;
unsigned long flags;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
switch(prom_vers) {
case PROM_V0:
case PROM_SUN4:
@@ -49,7 +49,7 @@ prom_nbgetchar(void)
break;
};
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return i; /* Ugh, we could spin forever on unsupported proms ;( */
}
@@ -63,7 +63,7 @@ prom_nbputchar(char c)
unsigned long flags;
int i = -1;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
switch(prom_vers) {
case PROM_V0:
case PROM_SUN4:
@@ -82,7 +82,7 @@ prom_nbputchar(char c)
break;
};
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return i; /* Ugh, we could spin forever on unsupported proms ;( */
}
@@ -125,10 +125,10 @@ prom_query_input_device()
return PROMDEV_I_UNK;
};
case PROM_V3:
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdin);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
if(prom_node_has_property(st_p, "keyboard"))
return PROMDEV_IKBD;
if (prom_getproperty(st_p, "name", propb, sizeof(propb)) != -1) {
@@ -174,10 +174,10 @@ prom_query_output_device()
break;
case PROM_V2:
case PROM_V3:
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
st_p = (*romvec->pv_v2devops.v2_inst2pkg)(*romvec->pv_v2bootargs.fd_stdout);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
propl = prom_getproperty(st_p, "device_type", propb, sizeof(propb));
if (propl >= 0 && propl == sizeof("display") &&
strncmp("display", propb, sizeof("display")) == 0)
diff --git a/arch/sparc/prom/devmap.c b/arch/sparc/prom/devmap.c
index 463b07527..eb1207357 100644
--- a/arch/sparc/prom/devmap.c
+++ b/arch/sparc/prom/devmap.c
@@ -1,4 +1,4 @@
-/* $Id: devmap.c,v 1.6 1998/03/09 14:04:23 jj Exp $
+/* $Id: devmap.c,v 1.7 2000/08/26 02:38:03 anton Exp $
* promdevmap.c: Map device/IO areas to virtual addresses.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -29,13 +29,13 @@ prom_mapio(char *vhint, int ios, unsigned int paddr, unsigned int num_bytes)
unsigned long flags;
char *ret;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
if((num_bytes == 0) || (paddr == 0)) ret = (char *) 0x0;
else
ret = (*(romvec->pv_v2devops.v2_dumb_mmap))(vhint, ios, paddr,
num_bytes);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return ret;
}
@@ -46,9 +46,9 @@ prom_unmapio(char *vaddr, unsigned int num_bytes)
unsigned long flags;
if(num_bytes == 0x0) return;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
(*(romvec->pv_v2devops.v2_dumb_munmap))(vaddr, num_bytes);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return;
}
diff --git a/arch/sparc/prom/devops.c b/arch/sparc/prom/devops.c
index 5a58efa0b..61919b54f 100644
--- a/arch/sparc/prom/devops.c
+++ b/arch/sparc/prom/devops.c
@@ -1,4 +1,4 @@
-/* $Id: devops.c,v 1.12 2000/01/29 01:09:12 anton Exp $
+/* $Id: devops.c,v 1.13 2000/08/26 02:38:03 anton Exp $
* devops.c: Device operations using the PROM.
*
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -21,7 +21,7 @@ prom_devopen(char *dstr)
{
int handle;
unsigned long flags;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
switch(prom_vers) {
case PROM_V0:
handle = (*(romvec->pv_v0devops.v0_devopen))(dstr);
@@ -36,7 +36,7 @@ prom_devopen(char *dstr)
break;
};
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return handle;
}
@@ -46,7 +46,7 @@ int
prom_devclose(int dhandle)
{
unsigned long flags;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
switch(prom_vers) {
case PROM_V0:
(*(romvec->pv_v0devops.v0_devclose))(dhandle);
@@ -59,7 +59,7 @@ prom_devclose(int dhandle)
break;
};
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return 0;
}
@@ -70,7 +70,7 @@ void
prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
{
unsigned long flags;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
switch(prom_vers) {
case PROM_V0:
(*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo);
@@ -83,7 +83,7 @@ prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo)
break;
};
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return;
}
diff --git a/arch/sparc/prom/misc.c b/arch/sparc/prom/misc.c
index 3c2f2434d..86ce39910 100644
--- a/arch/sparc/prom/misc.c
+++ b/arch/sparc/prom/misc.c
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.17 1998/07/21 10:36:22 jj Exp $
+/* $Id: misc.c,v 1.18 2000/08/26 02:38:03 anton Exp $
* misc.c: Miscellaneous prom functions that don't belong
* anywhere else.
*
@@ -15,16 +15,18 @@
extern void restore_current(void);
+spinlock_t prom_lock = SPIN_LOCK_UNLOCKED;
+
/* Reset and reboot the machine with the command 'bcommand'. */
void
prom_reboot(char *bcommand)
{
unsigned long flags;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
(*(romvec->pv_reboot))(bcommand);
/* Never get here. */
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
}
/* Forth evaluate the expression contained in 'fstring'. */
@@ -34,13 +36,13 @@ prom_feval(char *fstring)
unsigned long flags;
if(!fstring || fstring[0] == 0)
return;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
if(prom_vers == PROM_V0)
(*(romvec->pv_fortheval.v0_eval))(strlen(fstring), fstring);
else
(*(romvec->pv_fortheval.v2_eval))(fstring);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
}
/* We want to do this more nicely some day. */
@@ -66,10 +68,10 @@ prom_cmdline(void)
prom_palette (1);
#endif
install_obp_ticker();
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
(*(romvec->pv_abort))();
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
install_linux_ticker();
#ifdef CONFIG_SUN_AUXIO
TURN_ON_LED;
@@ -88,11 +90,11 @@ prom_halt(void)
{
unsigned long flags;
again:
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
(*(romvec->pv_halt))();
/* Never get here. */
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
goto again; /* PROM is out to get me -DaveM */
}
diff --git a/arch/sparc/prom/mp.c b/arch/sparc/prom/mp.c
index ba624673f..92fe3739f 100644
--- a/arch/sparc/prom/mp.c
+++ b/arch/sparc/prom/mp.c
@@ -1,4 +1,4 @@
-/* $Id: mp.c,v 1.11 2000/01/29 01:09:12 anton Exp $
+/* $Id: mp.c,v 1.12 2000/08/26 02:38:03 anton Exp $
* mp.c: OpenBoot Prom Multiprocessor support routines. Don't call
* these on a UP or else you will halt and catch fire. ;)
*
@@ -25,7 +25,7 @@ prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, cha
int ret;
unsigned long flags;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
switch(prom_vers) {
case PROM_V0:
case PROM_V2:
@@ -37,7 +37,7 @@ prom_startcpu(int cpunode, struct linux_prom_registers *ctable_reg, int ctx, cha
break;
};
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return ret;
}
@@ -51,7 +51,7 @@ prom_stopcpu(int cpunode)
int ret;
unsigned long flags;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
switch(prom_vers) {
case PROM_V0:
case PROM_V2:
@@ -63,7 +63,7 @@ prom_stopcpu(int cpunode)
break;
};
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return ret;
}
@@ -77,7 +77,7 @@ prom_idlecpu(int cpunode)
int ret;
unsigned long flags;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
switch(prom_vers) {
case PROM_V0:
case PROM_V2:
@@ -89,7 +89,7 @@ prom_idlecpu(int cpunode)
break;
};
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return ret;
}
@@ -103,7 +103,7 @@ prom_restartcpu(int cpunode)
int ret;
unsigned long flags;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
switch(prom_vers) {
case PROM_V0:
case PROM_V2:
@@ -115,7 +115,7 @@ prom_restartcpu(int cpunode)
break;
};
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return ret;
}
diff --git a/arch/sparc/prom/segment.c b/arch/sparc/prom/segment.c
index 62b3f8542..09d646016 100644
--- a/arch/sparc/prom/segment.c
+++ b/arch/sparc/prom/segment.c
@@ -1,4 +1,4 @@
-/* $Id: segment.c,v 1.6 1998/03/09 14:04:27 jj Exp $
+/* $Id: segment.c,v 1.7 2000/08/26 02:38:03 anton Exp $
* segment.c: Prom routine to map segments in other contexts before
* a standalone is completely mapped. This is for sun4 and
* sun4c architectures only.
@@ -21,9 +21,9 @@ void
prom_putsegment(int ctx, unsigned long vaddr, int segment)
{
unsigned long flags;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
(*(romvec->pv_setctxt))(ctx, (char *) vaddr, segment);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return;
}
diff --git a/arch/sparc/prom/tree.c b/arch/sparc/prom/tree.c
index 2e79057d8..adfe6e75a 100644
--- a/arch/sparc/prom/tree.c
+++ b/arch/sparc/prom/tree.c
@@ -1,4 +1,4 @@
-/* $Id: tree.c,v 1.25 1998/09/17 11:04:58 jj Exp $
+/* $Id: tree.c,v 1.26 2000/08/26 02:38:03 anton Exp $
* tree.c: Basic device tree traversal/scanning for the Linux
* prom library.
*
@@ -26,10 +26,10 @@ int __prom_getchild(int node)
unsigned long flags;
int cnode;
- save_and_cli(flags);
+ spin_lock_irqsave(&prom_lock, flags);
cnode = prom_nodeops->no_child(node);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return cnode;
}
@@ -57,10 +57,10 @@ int __prom_getsibling(int node)
unsigned long flags;
int cnode;
- save_and_cli(flags);
+ spin_lock_irqsave(&prom_lock, flags);
cnode = prom_nodeops->no_nextnode(node);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return cnode;
}
@@ -93,10 +93,10 @@ int prom_getproplen(int node, char *prop)
if((!node) || (!prop))
return -1;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
ret = prom_nodeops->no_proplen(node, prop);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return ret;
}
@@ -113,10 +113,10 @@ int prom_getproperty(int node, char *prop, char *buffer, int bufsize)
if((plen > bufsize) || (plen == 0) || (plen == -1))
return -1;
/* Ok, things seem all right. */
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
ret = prom_nodeops->no_getprop(node, prop, buffer);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return ret;
}
@@ -226,10 +226,10 @@ char * __prom_nextprop(int node, char * oprop)
unsigned long flags;
char *prop;
- save_and_cli(flags);
+ spin_lock_irqsave(&prom_lock, flags);
prop = prom_nodeops->no_nextprop(node, oprop);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return prop;
}
@@ -325,10 +325,10 @@ int prom_setprop(int node, char *pname, char *value, int size)
if(size == 0) return 0;
if((pname == 0) || (value == 0)) return 0;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
ret = prom_nodeops->no_setprop(node, pname, value, size);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
return ret;
}
@@ -337,10 +337,10 @@ int prom_inst2pkg(int inst)
int node;
unsigned long flags;
- save_flags(flags); cli();
+ spin_lock_irqsave(&prom_lock, flags);
node = (*romvec->pv_v2devops.v2_inst2pkg)(inst);
restore_current();
- restore_flags(flags);
+ spin_unlock_irqrestore(&prom_lock, flags);
if (node == -1) return 0;
return node;
}
diff --git a/arch/sparc64/boot/piggyback.c b/arch/sparc64/boot/piggyback.c
index 503b366db..36f907408 100644
--- a/arch/sparc64/boot/piggyback.c
+++ b/arch/sparc64/boot/piggyback.c
@@ -1,4 +1,4 @@
-/* $Id: piggyback.c,v 1.1 1997/07/11 11:05:26 jj Exp $
+/* $Id: piggyback.c,v 1.2 2000/09/19 14:34:39 anton Exp $
Simple utility to make a single-image install kernel with initial ramdisk
for Sparc64 tftpbooting without need to set up nfs.
@@ -50,9 +50,9 @@ int main(int argc,char **argv)
map = fopen (argv[2], "r");
if (!map) die(argv[2]);
while (fgets (buffer, 1024, map)) {
- if (!strcmp (buffer + 19, "start\n"))
+ if (!strcmp (buffer + 19, "_start\n"))
start = strtoul (buffer + 8, NULL, 16);
- else if (!strcmp (buffer + 19, "end\n"))
+ else if (!strcmp (buffer + 19, "_end\n"))
end = strtoul (buffer + 8, NULL, 16);
}
fclose (map);
diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in
index bfcb973d7..c49a87ebf 100644
--- a/arch/sparc64/config.in
+++ b/arch/sparc64/config.in
@@ -94,15 +94,7 @@ dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET
# bool ' LVM information in proc filesystem' CONFIG_LVM_PROC_FS Y
#fi
-tristate 'Multiple devices driver support' CONFIG_BLK_DEV_MD
-dep_tristate ' Linear (append) mode' CONFIG_MD_LINEAR $CONFIG_BLK_DEV_MD
-dep_tristate ' RAID-0 (striping) mode' CONFIG_MD_RAID0 $CONFIG_BLK_DEV_MD
-dep_tristate ' RAID-1 (mirroring) mode' CONFIG_MD_RAID1 $CONFIG_BLK_DEV_MD
-#dep_tristate ' RAID-4/RAID-5 mode' CONFIG_MD_RAID5 $CONFIG_BLK_DEV_MD
-#if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_RAID0" = "y" -o "$CONFIG_MD_RAID1" = "y" -o "$CONFIG_MD_RAID5" = "y" ]; then
-# bool ' Boot support' CONFIG_MD_BOOT
-# bool ' Auto Detect support' CONFIG_AUTODETECT_RAID
-#fi
+include drivers/md/Config.in
tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
diff --git a/arch/sparc64/kernel/auxio.c b/arch/sparc64/kernel/auxio.c
index 9be09c3b0..cc26817b4 100644
--- a/arch/sparc64/kernel/auxio.c
+++ b/arch/sparc64/kernel/auxio.c
@@ -18,6 +18,7 @@
#include <asm/sbus.h>
#include <asm/ebus.h>
#include <asm/fhc.h>
+#include <asm/starfire.h>
/* Probe and map in the Auxiliary I/O register */
unsigned long auxio_register = 0;
@@ -55,7 +56,7 @@ found_sdev:
return;
}
#endif
- if(central_bus) {
+ if(central_bus || this_is_starfire) {
auxio_register = 0UL;
return;
}
diff --git a/arch/sparc64/kernel/central.c b/arch/sparc64/kernel/central.c
index 2c4fb1355..dba732a6d 100644
--- a/arch/sparc64/kernel/central.c
+++ b/arch/sparc64/kernel/central.c
@@ -1,4 +1,4 @@
-/* $Id: central.c,v 1.13 1999/12/01 10:44:43 davem Exp $
+/* $Id: central.c,v 1.14 2000/09/21 06:25:14 anton Exp $
* central.c: Central FHC driver for Sunfire/Starfire/Wildfire.
*
* Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com)
@@ -15,6 +15,7 @@
#include <asm/page.h>
#include <asm/fhc.h>
+#include <asm/starfire.h>
struct linux_central *central_bus = NULL;
struct linux_fhc *fhc_list = NULL;
@@ -254,9 +255,8 @@ void central_probe(void)
cnode = prom_finddevice("/central");
if(cnode == 0 || cnode == -1) {
- extern void starfire_check(void);
-
- starfire_check();
+ if (this_is_starfire)
+ starfire_cpu_setup();
return;
}
diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S
index e95e0392e..fd6096ec5 100644
--- a/arch/sparc64/kernel/entry.S
+++ b/arch/sparc64/kernel/entry.S
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.118 2000/08/01 00:11:31 davem Exp $
+/* $Id: entry.S,v 1.120 2000/09/08 13:58:12 jj Exp $
* arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points.
*
* Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
@@ -911,7 +911,7 @@ sys_fork: clr %o1
mov SIGCHLD, %o0
sys_clone: flushw
movrz %o1, %fp, %o1
- nop
+ mov 0, %o3
ba,pt %xcc, do_fork
add %sp, STACK_BIAS + REGWIN_SZ, %o2
ret_from_syscall:
@@ -940,8 +940,8 @@ ret_from_syscall:
1: b,pt %xcc, ret_sys_call
ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0], %o0
-sparc_exit: rdpr %otherwin, %g1
- wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV), %pstate
+sparc_exit: wrpr %g0, (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV), %pstate
+ rdpr %otherwin, %g1
rdpr %cansave, %g3
add %g3, %g1, %g3
wrpr %g3, 0x0, %cansave
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c
index 7f2e21a51..92bd3ed88 100644
--- a/arch/sparc64/kernel/irq.c
+++ b/arch/sparc64/kernel/irq.c
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.91 2000/08/05 10:48:40 davem Exp $
+/* $Id: irq.c,v 1.94 2000/09/21 06:27:10 anton Exp $
* irq.c: UltraSparc IRQ handling/init/registry.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -31,6 +31,7 @@
#include <asm/smp.h>
#include <asm/hardirq.h>
#include <asm/softirq.h>
+#include <asm/starfire.h>
/* Internal flag, should not be visible elsewhere at all. */
#define SA_IMAP_MASKED 0x100
@@ -123,7 +124,6 @@ int get_irq_list(char *buf)
/* Now these are always passed a true fully specified sun4u INO. */
void enable_irq(unsigned int irq)
{
- extern int this_is_starfire;
struct ino_bucket *bucket = __bucket(irq);
unsigned long imap;
unsigned long tid;
@@ -139,9 +139,6 @@ void enable_irq(unsigned int irq)
: "i" (ASI_UPA_CONFIG));
tid = ((tid & UPA_CONFIG_MID) << 9);
} else {
- extern unsigned int starfire_translate(unsigned long imap,
- unsigned int upaid);
-
tid = (starfire_translate(imap, current->processor) << 26);
}
@@ -550,7 +547,7 @@ out:
#ifdef CONFIG_SMP
-/* Who has global_irq_lock. */
+/* Who has the global irq brlock */
unsigned char global_irq_holder = NO_PROC_ID;
static void show(char * str)
@@ -608,7 +605,7 @@ again:
spin_is_locked(lock) ||
(!local_bh_count(smp_processor_id()) && spin_is_locked(&global_bh_lock))) {
if (!--count) {
- show("wait_on_irq");
+ show("get_irqlock");
count = (~0 >> 1);
}
__sti();
@@ -715,7 +712,6 @@ void handler_irq(int irq, struct pt_regs *regs)
struct ino_bucket *bp, *nbp;
int cpu = smp_processor_id();
#ifdef CONFIG_SMP
- extern int this_is_starfire;
int should_forward = (this_is_starfire == 0 &&
irq < 10 &&
current->pid != 0);
@@ -1029,7 +1025,6 @@ void init_timers(void (*cfunc)(int, void *, struct pt_regs *),
#ifdef CONFIG_SMP
static int retarget_one_irq(struct irqaction *p, int goal_cpu)
{
- extern int this_is_starfire;
struct ino_bucket *bucket = __bucket(p->mask);
unsigned long imap = bucket->imap;
unsigned int tid;
@@ -1041,9 +1036,6 @@ static int retarget_one_irq(struct irqaction *p, int goal_cpu)
if(this_is_starfire == 0) {
tid = __cpu_logical_map[goal_cpu] << 26;
} else {
- extern unsigned int starfire_translate(unsigned long imap,
- unsigned int upaid);
-
tid = (starfire_translate(imap, __cpu_logical_map[goal_cpu]) << 26);
}
upa_writel(IMAP_VALID | (tid & IMAP_TID), imap);
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
index cd28d9392..24b1a7217 100644
--- a/arch/sparc64/kernel/pci.c
+++ b/arch/sparc64/kernel/pci.c
@@ -1,4 +1,4 @@
-/* $Id: pci.c,v 1.16 2000/03/01 02:53:33 davem Exp $
+/* $Id: pci.c,v 1.17 2000/09/05 06:49:44 anton Exp $
* pci.c: UltraSparc PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@redhat.com)
@@ -24,7 +24,6 @@ unsigned long pci_memspace_mask = 0xffffffffUL;
#ifndef CONFIG_PCI
/* A "nop" PCI implementation. */
-int pcibios_present(void) { return 0; }
asmlinkage int sys_pciconfig_read(unsigned long bus, unsigned long dfn,
unsigned long off, unsigned long len,
unsigned char *buf)
@@ -274,7 +273,6 @@ asmlinkage int sys_pciconfig_read(unsigned long bus,
goto out;
}
- lock_kernel();
switch(len) {
case 1:
pci_read_config_byte(dev, off, &byte);
@@ -293,7 +291,6 @@ asmlinkage int sys_pciconfig_read(unsigned long bus,
err = -EINVAL;
break;
};
- unlock_kernel();
out:
return err;
}
@@ -318,7 +315,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus,
goto out;
}
- lock_kernel();
switch(len) {
case 1:
err = get_user(byte, (u8 *)buf);
@@ -346,7 +342,6 @@ asmlinkage int sys_pciconfig_write(unsigned long bus,
break;
};
- unlock_kernel();
out:
return err;
diff --git a/arch/sparc64/kernel/pci_psycho.c b/arch/sparc64/kernel/pci_psycho.c
index 8d7db0c9b..aff2de594 100644
--- a/arch/sparc64/kernel/pci_psycho.c
+++ b/arch/sparc64/kernel/pci_psycho.c
@@ -1,4 +1,4 @@
-/* $Id: pci_psycho.c,v 1.16 2000/04/15 10:06:16 davem Exp $
+/* $Id: pci_psycho.c,v 1.17 2000/09/21 06:25:14 anton Exp $
* pci_psycho.c: PSYCHO/U2P specific PCI controller support.
*
* Copyright (C) 1997, 1998, 1999 David S. Miller (davem@caipfs.rutgers.edu)
@@ -15,6 +15,7 @@
#include <asm/pbm.h>
#include <asm/iommu.h>
#include <asm/irq.h>
+#include <asm/starfire.h>
#include "pci_impl.h"
@@ -1254,8 +1255,6 @@ static void __init psycho_scan_bus(struct pci_controller_info *p)
static void __init psycho_iommu_init(struct pci_controller_info *p)
{
- extern int this_is_starfire;
- extern void *starfire_hookup(int);
unsigned long tsbbase, i;
u64 control;
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c
index 21d43bb1e..1f3386d53 100644
--- a/arch/sparc64/kernel/process.c
+++ b/arch/sparc64/kernel/process.c
@@ -1,4 +1,4 @@
-/* $Id: process.c,v 1.111 2000/08/16 11:13:12 davem Exp $
+/* $Id: process.c,v 1.112 2000/09/06 00:45:01 davem Exp $
* arch/sparc64/kernel/process.c
*
* Copyright (C) 1995, 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -573,6 +573,7 @@ barf:
* do_fork().
*/
int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
+ unsigned long unused,
struct task_struct *p, struct pt_regs *regs)
{
struct thread_struct *t = &p->thread;
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index 602ee9ca2..7baebc89e 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -1,4 +1,4 @@
-/* $Id: sbus.c,v 1.11 2000/04/14 09:13:04 davem Exp $
+/* $Id: sbus.c,v 1.12 2000/09/21 06:25:14 anton Exp $
* sbus.c: UltraSparc SBUS controller support.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -18,6 +18,7 @@
#include <asm/cache.h>
#include <asm/dma.h>
#include <asm/irq.h>
+#include <asm/starfire.h>
#include "iommu_common.h"
@@ -1151,15 +1152,10 @@ void __init sbus_iommu_init(int prom_node, struct sbus_bus *sbus)
upa_writeq(control, iommu->sbus_control_reg);
/* Now some Xfire specific grot... */
- {
- extern void *starfire_hookup(int);
- extern int this_is_starfire;
-
- if (this_is_starfire)
- sbus->starfire_cookie = starfire_hookup(sbus->portid);
- else
- sbus->starfire_cookie = NULL;
- }
+ if (this_is_starfire)
+ sbus->starfire_cookie = starfire_hookup(sbus->portid);
+ else
+ sbus->starfire_cookie = NULL;
sysio_register_error_handlers(sbus);
}
diff --git a/arch/sparc64/kernel/setup.c b/arch/sparc64/kernel/setup.c
index 486254fb9..84cc201fd 100644
--- a/arch/sparc64/kernel/setup.c
+++ b/arch/sparc64/kernel/setup.c
@@ -1,4 +1,4 @@
-/* $Id: setup.c,v 1.55 2000/07/24 14:13:13 anton Exp $
+/* $Id: setup.c,v 1.56 2000/09/21 06:29:01 anton Exp $
* linux/arch/sparc64/kernel/setup.c
*
* Copyright (C) 1995,1996 David S. Miller (davem@caip.rutgers.edu)
@@ -37,6 +37,7 @@
#include <asm/pgtable.h>
#include <asm/idprom.h>
#include <asm/head.h>
+#include <asm/starfire.h>
#ifdef CONFIG_IP_PNP
#include <net/ipconfig.h>
@@ -479,6 +480,9 @@ void __init setup_arch(char **cmdline_p)
conswitchp = &prom_con;
#endif
+ /* Work out if we are starfire early on */
+ check_if_starfire();
+
boot_flags_init(*cmdline_p);
idprom_init();
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c
index d1e7e4215..c2a7833fb 100644
--- a/arch/sparc64/kernel/signal.c
+++ b/arch/sparc64/kernel/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.53 2000/07/30 23:12:24 davem Exp $
+/* $Id: signal.c,v 1.54 2000/09/05 21:44:54 davem Exp $
* arch/sparc64/kernel/signal.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -784,7 +784,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
#endif
/* fall through */
default:
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c
index efad55a1c..6d06328dd 100644
--- a/arch/sparc64/kernel/signal32.c
+++ b/arch/sparc64/kernel/signal32.c
@@ -1,4 +1,4 @@
-/* $Id: signal32.c,v 1.66 2000/07/27 01:05:15 davem Exp $
+/* $Id: signal32.c,v 1.67 2000/09/05 21:44:54 davem Exp $
* arch/sparc64/kernel/signal32.c
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -1420,7 +1420,7 @@ asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs * regs,
#endif
/* fall through */
default:
- sigaddset(&current->signal, signr);
+ sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
diff --git a/arch/sparc64/kernel/starfire.c b/arch/sparc64/kernel/starfire.c
index 8ff7ea4d2..dc8f96b7a 100644
--- a/arch/sparc64/kernel/starfire.c
+++ b/arch/sparc64/kernel/starfire.c
@@ -1,7 +1,8 @@
-/* $Id: starfire.c,v 1.5 2000/01/31 04:59:12 davem Exp $
+/* $Id: starfire.c,v 1.7 2000/09/22 23:02:13 davem Exp $
* starfire.c: Starfire/E10000 support.
*
* Copyright (C) 1998 David S. Miller (davem@redhat.com)
+ * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com)
*/
#include <linux/kernel.h>
@@ -11,23 +12,31 @@
#include <asm/oplib.h>
#include <asm/smp.h>
#include <asm/upa.h>
+#include <asm/starfire.h>
-/* A few places around the kernel check this to see if
+/*
+ * A few places around the kernel check this to see if
* they need to call us to do things in a Starfire specific
* way.
*/
int this_is_starfire = 0;
-void starfire_check(void)
+void check_if_starfire(void)
{
int ssnode = prom_finddevice("/ssp-serial");
+ if(ssnode != 0 && ssnode != -1)
+ this_is_starfire = 1;
+}
- if(ssnode != 0 && ssnode != -1) {
+void starfire_cpu_setup(void)
+{
+ if (this_is_starfire) {
+/* We do this in starfire_translate - Anton */
+#if 0
int i;
- this_is_starfire = 1;
-
- /* Now must fixup cpu MIDs. OBP gave us a logical
+ /*
+ * Now must fixup cpu MIDs. OBP gave us a logical
* linear cpuid number, not the real upaid.
*/
for(i = 0; i < linux_num_cpus; i++) {
@@ -39,6 +48,7 @@ void starfire_check(void)
linux_cpus[i].mid = mid;
}
+#endif
}
}
@@ -47,7 +57,8 @@ int starfire_hard_smp_processor_id(void)
return upa_readl(0x1fff40000d0UL);
}
-/* Each Starfire board has 32 registers which perform translation
+/*
+ * Each Starfire board has 32 registers which perform translation
* and delivery of traditional interrupt packets into the extended
* Starfire hardware format. Essentially UPAID's now have 2 more
* bits than in all previous Sun5 systems.
@@ -82,6 +93,9 @@ void *starfire_hookup(int upaid)
for(i = 0; i < 32; i++) {
p->imap_slots[i] = 0UL;
p->tregs[i] = treg_base + (i * 0x10UL);
+ /* Lets play it safe and not overwrite existing mappings */
+ if (upa_readl(p->tregs[i]) != 0)
+ p->imap_slots[i] = 0xdeadbeaf;
}
p->upaid = upaid;
p->next = sflist;
@@ -116,6 +130,12 @@ unsigned int starfire_translate(unsigned long imap,
panic("Lucy in the sky....");
}
p->imap_slots[i] = imap;
+
+ /* map to real upaid */
+ upaid = (((upaid & 0x3c) << 1) |
+ ((upaid & 0x40) >> 4) |
+ (upaid & 0x3));
+
upa_writel(upaid, p->tregs[i]);
return i;
diff --git a/arch/sparc64/kernel/sys_sparc.c b/arch/sparc64/kernel/sys_sparc.c
index e869af4e6..235d34889 100644
--- a/arch/sparc64/kernel/sys_sparc.c
+++ b/arch/sparc64/kernel/sys_sparc.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc.c,v 1.45 2000/07/30 23:12:24 davem Exp $
+/* $Id: sys_sparc.c,v 1.46 2000/08/29 07:01:54 davem Exp $
* linux/arch/sparc64/kernel/sys_sparc.c
*
* This file contains various random system calls that
@@ -398,13 +398,18 @@ asmlinkage int sys_utrap_install(utrap_entry_t type, utrap_handler_t new_p,
return -EINVAL;
if (new_p == (utrap_handler_t)(long)UTH_NOCHANGE) {
if (old_p) {
- if (!current->thread.utraps)
- put_user_ret(NULL, old_p, -EFAULT);
- else
- put_user_ret((utrap_handler_t)(current->thread.utraps[type]), old_p, -EFAULT);
+ if (!current->thread.utraps) {
+ if (put_user(NULL, old_p))
+ return -EFAULT;
+ } else {
+ if (put_user((utrap_handler_t)(current->thread.utraps[type]), old_p))
+ return -EFAULT;
+ }
+ }
+ if (old_d) {
+ if (put_user(NULL, old_d))
+ return -EFAULT;
}
- if (old_d)
- put_user_ret(NULL, old_d, -EFAULT);
return 0;
}
if (!current->thread.utraps) {
@@ -431,11 +436,14 @@ asmlinkage int sys_utrap_install(utrap_entry_t type, utrap_handler_t new_p,
UT_TRAP_INSTRUCTION_31*sizeof(long));
}
}
- if (old_p)
- put_user_ret((utrap_handler_t)(current->thread.utraps[type]),
- old_p, -EFAULT);
- if (old_d)
- put_user_ret(NULL, old_d, -EFAULT);
+ if (old_p) {
+ if (put_user((utrap_handler_t)(current->thread.utraps[type]), old_p))
+ return -EFAULT;
+ }
+ if (old_d) {
+ if (put_user(NULL, old_d))
+ return -EFAULT;
+ }
current->thread.utraps[type] = (long)new_p;
return 0;
diff --git a/arch/sparc64/kernel/sys_sparc32.c b/arch/sparc64/kernel/sys_sparc32.c
index 8683b87d7..071510bbc 100644
--- a/arch/sparc64/kernel/sys_sparc32.c
+++ b/arch/sparc64/kernel/sys_sparc32.c
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.163 2000/08/22 10:09:10 jj Exp $
+/* $Id: sys_sparc32.c,v 1.164 2000/09/14 10:42:47 davem Exp $
* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -1621,7 +1621,7 @@ struct ncp_mount_data32 {
static void *do_ncp_super_data_conv(void *raw_data)
{
- struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;
+ struct ncp_mount_data news, *n = &news;
struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;
n->dir_mode = n32->dir_mode;
@@ -1631,6 +1631,7 @@ static void *do_ncp_super_data_conv(void *raw_data)
memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));
n->wdog_pid = n32->wdog_pid;
n->mounted_uid = low2highuid(n32->mounted_uid);
+ memcpy(raw_data, n, sizeof(struct ncp_mount_data));
return raw_data;
}
@@ -1645,7 +1646,7 @@ struct smb_mount_data32 {
static void *do_smb_super_data_conv(void *raw_data)
{
- struct smb_mount_data *s = (struct smb_mount_data *)raw_data;
+ struct smb_mount_data news, *s = &news;
struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;
s->version = s32->version;
@@ -1654,6 +1655,7 @@ static void *do_smb_super_data_conv(void *raw_data)
s->gid = low2highgid(s32->gid);
s->file_mode = s32->file_mode;
s->dir_mode = s32->dir_mode;
+ memcpy(raw_data, s, sizeof(struct smb_mount_data));
return raw_data;
}
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
index f229ea988..0264f9418 100644
--- a/arch/sparc64/kernel/time.c
+++ b/arch/sparc64/kernel/time.c
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.28 2000/07/11 02:21:12 davem Exp $
+/* $Id: time.c,v 1.32 2000/09/22 23:02:13 davem Exp $
* time.c: UltraSparc timer and TOD clock support.
*
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -30,6 +30,7 @@
#include <asm/fhc.h>
#include <asm/pbm.h>
#include <asm/ebus.h>
+#include <asm/starfire.h>
extern rwlock_t xtime_lock;
@@ -177,37 +178,6 @@ void timer_tick_interrupt(struct pt_regs *regs)
}
#endif
-/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
- * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
- * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
- *
- * [For the Julian calendar (which was used in Russia before 1917,
- * Britain & colonies before 1752, anywhere else before 1582,
- * and is still in use by some communities) leave out the
- * -year/100+year/400 terms, and add 10.]
- *
- * This algorithm was first published by Gauss (I think).
- *
- * WARNING: this function will overflow on 2106-02-07 06:28:16 on
- * machines were long is 32-bit! (However, as time_t is signed, we
- * will already get problems at other places on 2038-01-19 03:14:08)
- */
-static inline unsigned long mktime(unsigned int year, unsigned int mon,
- unsigned int day, unsigned int hour,
- unsigned int min, unsigned int sec)
-{
- if (0 >= (int) (mon -= 2)) { /* 1..12 -> 11,12,1..10 */
- mon += 12; /* Puts Feb last since it has leap day */
- year -= 1;
- }
- return (((
- (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
- year*365 - 719499
- )*24 + hour /* now have hours */
- )*60 + min /* now have minutes */
- )*60 + sec; /* finally seconds */
-}
-
/* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
static void __init kick_start_clock(void)
{
@@ -336,6 +306,20 @@ void __init clock_probe(void)
struct linux_ebus *ebus = NULL;
#endif
+
+ if (this_is_starfire) {
+ /* davem suggests we keep this within the 4M locked kernel image */
+ static char obp_gettod[256];
+ static u32 unix_tod;
+
+ sprintf(obp_gettod, "h# %08x unix-gettod",
+ (unsigned int) (long) &unix_tod);
+ prom_feval(obp_gettod);
+ xtime.tv_sec = unix_tod;
+ xtime.tv_usec = 0;
+ return;
+ }
+
__save_and_cli(flags);
if(central_bus != NULL) {
@@ -504,6 +488,9 @@ static __inline__ unsigned long do_gettimeoffset(void)
void do_settimeofday(struct timeval *tv)
{
+ if (this_is_starfire)
+ return;
+
write_lock_irq(&xtime_lock);
tv->tv_usec -= do_gettimeoffset();
@@ -527,7 +514,10 @@ static int set_rtc_mmss(unsigned long nowtime)
unsigned long regs = mstk48t02_regs;
u8 tmp;
- /* Not having a register set can lead to trouble. */
+ /*
+ * Not having a register set can lead to trouble.
+ * Also starfire doesnt have a tod clock.
+ */
if (!regs)
return -1;
diff --git a/arch/sparc64/lib/rwlock.S b/arch/sparc64/lib/rwlock.S
index 03f3bfe59..56edad121 100644
--- a/arch/sparc64/lib/rwlock.S
+++ b/arch/sparc64/lib/rwlock.S
@@ -1,4 +1,4 @@
-/* $Id: rwlock.S,v 1.3 2000/03/16 16:44:38 davem Exp $
+/* $Id: rwlock.S,v 1.4 2000/09/09 00:00:34 davem Exp $
* rwlocks.S: These things are too big to do inline.
*
* Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -30,54 +30,38 @@ __read_unlock: /* %o0 = lock_ptr */
cmp %g5, %g7
be,pt %xcc, 99b
membar #StoreLoad | #StoreStore
- b,a,pt %xcc, __read_unlock
+ ba,a,pt %xcc, __read_unlock
__read_wait_for_writer:
ldsw [%o0], %g5
brlz,pt %g5, __read_wait_for_writer
membar #LoadLoad
- b,a,pt %xcc, 4b
-__write_wait_for_writer:
- ldsw [%o0], %g5
- brlz,pt %g5, __write_wait_for_writer
+ ba,a,pt %xcc, 4b
+__write_wait_for_any:
+ lduw [%o0], %g5
+ brnz,pt %g5, __write_wait_for_any
membar #LoadLoad
- b,a,pt %xcc, 4f
-
- /* Similarly, 2 cache lines for non-contention write locks. */
+ ba,a,pt %xcc, 4f
.align 64
.globl __write_unlock
__write_unlock: /* %o0 = lock_ptr */
- sethi %hi(0x80000000), %g2
-1: lduw [%o0], %g5
- andn %g5, %g2, %g7
- cas [%o0], %g5, %g7
- cmp %g5, %g7
- be,pt %icc, 99b
- membar #StoreLoad | #StoreStore
- b,a,pt %xcc, 1b
+ membar #LoadStore | #StoreStore
+ retl
+ stw %g0, [%o0]
.globl __write_lock
__write_lock: /* %o0 = lock_ptr */
sethi %hi(0x80000000), %g2
-1: ldsw [%o0], %g5
-4: brnz,pn %g5, 5f
- or %g5, %g2, %g7
+
+1: lduw [%o0], %g5
+ brnz,pn %g5, __write_wait_for_any
+4: or %g5, %g2, %g7
cas [%o0], %g5, %g7
+
cmp %g5, %g7
be,pt %icc, 99b
membar #StoreLoad | #StoreStore
-
- b,a,pt %xcc, 1b
-5: brlz %g5, __write_wait_for_writer
- or %g5, %g2, %g7
- cas [%o0], %g5, %g7
- cmp %g5, %g7
- bne,pn %icc, 5b
-8: ldsw [%o0], %g5
- cmp %g5, %g2
- be,pn %icc, 99b
- membar #LoadLoad
- b,a,pt %xcc, 99b
+ ba,a,pt %xcc, 1b
rwlock_impl_end:
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 9ebe1f494..12006b58a 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -1,4 +1,4 @@
-/* $Id: fault.c,v 1.50 2000/08/11 03:00:13 davem Exp $
+/* $Id: fault.c,v 1.51 2000/09/14 06:22:32 anton Exp $
* arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc.
*
* Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -145,7 +145,7 @@ static void do_kernel_fault(struct pt_regs *regs, int si_code, int fault_code,
if (!insn) {
if (regs->tstate & TSTATE_PRIV) {
- if (regs->tpc & 0x3)
+ if (!regs->tpc || (regs->tpc & 0x3))
goto cannot_handle;
insn = *(unsigned int *)regs->tpc;
} else {
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index 7eef97836..d694e40f9 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1,4 +1,4 @@
-/* $Id: init.c,v 1.154 2000/08/09 00:00:15 davem Exp $
+/* $Id: init.c,v 1.156 2000/09/21 06:34:48 anton Exp $
* arch/sparc64/mm/init.c
*
* Copyright (C) 1996-1999 David S. Miller (davem@caip.rutgers.edu)
@@ -29,6 +29,7 @@
#include <asm/mmu_context.h>
#include <asm/vaddrs.h>
#include <asm/dma.h>
+#include <asm/starfire.h>
extern void device_scan(void);
@@ -200,7 +201,7 @@ static void inherit_prom_mappings(void)
for (i = 0; i < n; i++) {
unsigned long vaddr;
-
+
if (trans[i].virt >= 0xf0000000 && trans[i].virt < 0x100000000) {
for (vaddr = trans[i].virt;
vaddr < trans[i].virt + trans[i].size;
@@ -808,7 +809,6 @@ unsigned long __init bootmem_init(unsigned long *pages_avail)
unsigned long bootmap_pfn, bytes_avail, size;
int i;
-
bytes_avail = 0UL;
for (i = 0; sp_banks[i].num_bytes != 0; i++) {
end_of_phys_memory = sp_banks[i].base_addr +
@@ -999,12 +999,7 @@ void __init paging_init(void)
*/
{
extern void setup_tba(int);
- int is_starfire = prom_finddevice("/ssp-serial");
- if (is_starfire != 0 && is_starfire != -1)
- is_starfire = 1;
- else
- is_starfire = 0;
- setup_tba(is_starfire);
+ setup_tba(this_is_starfire);
}
inherit_locked_prom_mappings(1);
@@ -1029,7 +1024,7 @@ void __init paging_init(void)
zones_size[ZONE_DMA] = npages;
zholes_size[ZONE_DMA] = npages - pages_avail;
- free_area_init_node(0, NULL, zones_size,
+ free_area_init_node(0, NULL, NULL, zones_size,
phys_base, zholes_size);
}
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c
index 3cf5b6883..e80d6b13f 100644
--- a/arch/sparc64/solaris/fs.c
+++ b/arch/sparc64/solaris/fs.c
@@ -1,4 +1,4 @@
-/* $Id: fs.c,v 1.22 2000/07/28 12:15:02 davem Exp $
+/* $Id: fs.c,v 1.23 2000/08/29 07:01:54 davem Exp $
* fs.c: fs related syscall emulation for Solaris
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -612,20 +612,25 @@ asmlinkage int solaris_fcntl(unsigned fd, unsigned cmd, u32 arg)
case SOL_F_SETLKW: cmd = F_SETLKW; break;
}
- get_user_ret (f.l_type, &((struct sol_flock *)A(arg))->l_type, -EFAULT);
- __get_user_ret (f.l_whence, &((struct sol_flock *)A(arg))->l_whence, -EFAULT);
- __get_user_ret (f.l_start, &((struct sol_flock *)A(arg))->l_start, -EFAULT);
- __get_user_ret (f.l_len, &((struct sol_flock *)A(arg))->l_len, -EFAULT);
- __get_user_ret (f.l_pid, &((struct sol_flock *)A(arg))->l_sysid, -EFAULT);
+ if (get_user (f.l_type, &((struct sol_flock *)A(arg))->l_type) ||
+ __get_user (f.l_whence, &((struct sol_flock *)A(arg))->l_whence) ||
+ __get_user (f.l_start, &((struct sol_flock *)A(arg))->l_start) ||
+ __get_user (f.l_len, &((struct sol_flock *)A(arg))->l_len) ||
+ __get_user (f.l_pid, &((struct sol_flock *)A(arg))->l_sysid))
+ return -EFAULT;
+
set_fs(KERNEL_DS);
ret = sys_fcntl(fd, cmd, (unsigned long)&f);
set_fs(old_fs);
- __put_user_ret (f.l_type, &((struct sol_flock *)A(arg))->l_type, -EFAULT);
- __put_user_ret (f.l_whence, &((struct sol_flock *)A(arg))->l_whence, -EFAULT);
- __put_user_ret (f.l_start, &((struct sol_flock *)A(arg))->l_start, -EFAULT);
- __put_user_ret (f.l_len, &((struct sol_flock *)A(arg))->l_len, -EFAULT);
- __put_user_ret (f.l_pid, &((struct sol_flock *)A(arg))->l_pid, -EFAULT);
- __put_user_ret (0, &((struct sol_flock *)A(arg))->l_sysid, -EFAULT);
+
+ if (__put_user (f.l_type, &((struct sol_flock *)A(arg))->l_type) ||
+ __put_user (f.l_whence, &((struct sol_flock *)A(arg))->l_whence) ||
+ __put_user (f.l_start, &((struct sol_flock *)A(arg))->l_start) ||
+ __put_user (f.l_len, &((struct sol_flock *)A(arg))->l_len) ||
+ __put_user (f.l_pid, &((struct sol_flock *)A(arg))->l_pid) ||
+ __put_user (0, &((struct sol_flock *)A(arg))->l_sysid))
+ return -EFAULT;
+
return ret;
}
case SOL_F_FREESP:
@@ -634,7 +639,9 @@ asmlinkage int solaris_fcntl(unsigned fd, unsigned cmd, u32 arg)
int (*sys_newftruncate)(unsigned int, unsigned long)=
(int (*)(unsigned int, unsigned long))SYS(ftruncate);
- get_user_ret(length, &((struct sol_flock*)A(arg))->l_start, -EFAULT);
+ if (get_user(length, &((struct sol_flock*)A(arg))->l_start))
+ return -EFAULT;
+
return sys_newftruncate(fd, length);
}
};
diff --git a/arch/sparc64/solaris/misc.c b/arch/sparc64/solaris/misc.c
index a7edd1876..ca8bf25f3 100644
--- a/arch/sparc64/solaris/misc.c
+++ b/arch/sparc64/solaris/misc.c
@@ -1,4 +1,4 @@
-/* $Id: misc.c,v 1.29 2000/08/14 23:50:31 anton Exp $
+/* $Id: misc.c,v 1.30 2000/08/29 07:01:54 davem Exp $
* misc.c: Miscelaneous syscall emulation for Solaris
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -139,12 +139,14 @@ asmlinkage int solaris_brk(u32 brk)
int i, len = (countfrom) ? \
((sizeof(to) > sizeof(from) ? \
sizeof(from) : sizeof(to))) : sizeof(to); \
- copy_to_user_ret(to, from, len, -EFAULT); \
+ if (copy_to_user(to, from, len)) \
+ return -EFAULT; \
if (dotchop) \
for (p=from,i=0; *p && *p != '.' && --len; p++,i++); \
else \
i = len - 1; \
- __put_user_ret('\0', (char *)(to+i), -EFAULT); \
+ if (__put_user('\0', (char *)(to+i))) \
+ return -EFAULT; \
}
struct sol_uname {
@@ -297,10 +299,13 @@ asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count)
}
len = strlen(r) + 1;
if (count < len) {
- copy_to_user_ret((char *)A(buf), r, count - 1, -EFAULT);
- __put_user_ret(0, (char *)A(buf) + count - 1, -EFAULT);
- } else
- copy_to_user_ret((char *)A(buf), r, len, -EFAULT);
+ if (copy_to_user((char *)A(buf), r, count - 1) ||
+ __put_user(0, (char *)A(buf) + count - 1))
+ return -EFAULT;
+ } else {
+ if (copy_to_user((char *)A(buf), r, len))
+ return -EFAULT;
+ }
return len;
}
diff --git a/arch/sparc64/solaris/signal.c b/arch/sparc64/solaris/signal.c
index 7105bc05c..8a6ecd916 100644
--- a/arch/sparc64/solaris/signal.c
+++ b/arch/sparc64/solaris/signal.c
@@ -1,4 +1,4 @@
-/* $Id: signal.c,v 1.5 1997/12/15 15:04:59 jj Exp $
+/* $Id: signal.c,v 1.7 2000/09/05 21:44:54 davem Exp $
* signal.c: Signal emulation for Solaris
*
* Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -311,7 +311,7 @@ asmlinkage int solaris_sigpending(int which, u32 set)
switch (which) {
case 1: /* sigpending */
spin_lock_irq(&current->sigmask_lock);
- sigandsets(&s, &current->blocked, &current->signal);
+ sigandsets(&s, &current->blocked, &current->pending.signal);
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
break;
@@ -368,9 +368,13 @@ asmlinkage int solaris_waitid(int idtype, s32 pid, u32 info, int options)
if (info) {
struct sol_siginfo *s = (struct sol_siginfo *)A(info);
- if (get_user (status, (unsigned int *)A(info))) return -EFAULT;
- __put_user_ret (SOLARIS_SIGCLD, &s->si_signo, -EFAULT);
- __put_user_ret (ret, &s->_data._proc._pid, -EFAULT);
+ if (get_user (status, (unsigned int *)A(info)))
+ return -EFAULT;
+
+ if (__put_user (SOLARIS_SIGCLD, &s->si_signo) ||
+ __put_user (ret, &s->_data._proc._pid))
+ return -EFAULT;
+
switch (status & 0xff) {
case 0: ret = SOLARIS_CLD_EXITED;
status = (status >> 8) & 0xff;
@@ -390,8 +394,10 @@ asmlinkage int solaris_waitid(int idtype, s32 pid, u32 info, int options)
status = linux_to_solaris_signals[status & 0x7f];
break;
}
- __put_user_ret (ret, &s->si_code, -EFAULT);
- __put_user_ret (status, &s->_data._proc._pdata._cld._status, -EFAULT);
+
+ if (__put_user (ret, &s->si_code) ||
+ __put_user (status, &s->_data._proc._pdata._cld._status))
+ return -EFAULT;
}
return 0;
}