# This is a BitKeeper generated patch for the following project: # Project Name: Linux 2.4 # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet v2.4.6-pre3 -> 1.140 # arch/ppc/kernel/ppc4xx_pic.h 1.1.1.1 -> 1.8 # arch/ppc/boot/chrp/main.c 1.1.1.1 -> 1.9 # include/asm-ppc/ptrace.h 1.1.1.1 -> 1.7 # include/asm-ppc/unaligned.h 1.1.1.1 -> 1.7 # include/asm-ppc/system.h 1.1.1.3 -> 1.12 # arch/ppc/kernel/head_8xx.S 1.1.1.3 -> 1.14 # arch/ppc/lib/locks.c 1.1.1.2 -> 1.11 # arch/ppc/math-emu/fsqrt.c 1.1.1.1 -> 1.8 # arch/ppc/math-emu/mtfsf.c 1.1.1.1 -> 1.8 # drivers/char/tty_io.c 1.1.1.4 -> 1.8 # CREDITS 1.1.1.17 -> 1.21 # arch/sparc64/kernel/ioctl32.c 1.4.1.5 -> 1.10 # arch/ppc/boot/lib/zlib.c 1.1.1.1 -> 1.8 # include/asm-ppc/traps.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/pci.h 1.1.1.2 -> 1.9 # arch/ppc/boot/mbx/head_8260.S 1.1.1.1 -> 1.8 # include/asm-ppc/mc146818rtc.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/chrp_pci.c 1.1.1.4 -> 1.16 # arch/ppc/kernel/i8259.h 1.1.1.1 -> 1.7 # arch/ppc/math-emu/fneg.c 1.1.1.1 -> 1.8 # BitKeeper/etc/COPYING 1.1 -> (deleted) # drivers/ide/ide-features.c 1.1.1.1 -> 1.3 # drivers/video/controlfb.c 1.1.1.1 -> 1.4 # include/asm-ppc/bootinfo.h 1.1.1.2 -> 1.9 # arch/ppc/boot/utils/addnote.c 1.1.1.1 -> 1.8 # include/asm-ppc/dbdma.h 1.1.1.1 -> 1.7 # include/asm-ppc/m48t35.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/pmac_pic.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/sleep.S 1.1.1.2 -> 1.10 # arch/ppc/configs/mbx_defconfig 1.1.1.3 -> 1.9 # arch/ppc/xmon/subr_prf.c 1.1.1.1 -> 1.7 # arch/ppc/math-emu/fnmsub.c 1.1.1.1 -> 1.8 # include/asm-ppc/param.h 1.1.1.1 -> 1.7 # arch/ppc/configs/apus_defconfig 1.1.1.4 -> 1.10 # arch/ppc/amiga/config.c 1.1.1.2 -> 1.9 # include/asm-ppc/poll.h 1.1.1.1 -> 1.7 # include/asm-ppc/msgbuf.h 1.1.1.1 -> 1.7 # arch/ppc/xmon/nonstdio.h 1.1.1.1 -> 1.7 # arch/ppc/xmon/xmon.c 1.1.1.4 -> 1.14 # arch/ppc/kernel/time.c 1.1.1.5 -> 1.19 # arch/ppc/boot/tree/ld.script 1.1.2.1 -> 1.4 # include/asm-ppc/pgtable.h 1.1.1.3 -> 1.13 # include/asm-ppc/est8260.h 1.1.1.1 -> 1.7 # drivers/macintosh/mac_hid.c 1.1 -> 1.4 # arch/ppc/boot/common/Makefile 1.1 -> (deleted) # arch/ppc/boot/utils/mkevimg 1.1.1.2 -> 1.10 # drivers/char/keyboard.c 1.1 -> 1.2 # include/asm-ppc/ioctls.h 1.1.1.2 -> 1.9 # arch/ppc/configs/bseip_defconfig 1.1.1.3 -> 1.9 # arch/ppc/8260_io/enet.c 1.1.1.3 -> 1.8 # drivers/net/3c515.c 1.3.1.3 -> 1.7 # drivers/sound/dmasound/dmasound_atari.c 1.1 -> 1.2 # arch/ppc/boot/prep/misc.c 1.1.1.2 -> 1.12 # include/asm-ppc/machdep.h 1.1.1.3 -> 1.13 # include/asm-ppc/mmu_context.h 1.1.1.3 -> 1.12 # arch/ppc/kernel/mk_defs.c 1.1.1.1 -> 1.9 # include/asm-ppc/ohare.h 1.1.1.1 -> 1.7 # drivers/ide/ide-pmac.c 1.1.1.1 -> 1.4 # drivers/ide/sl82c105.c 1.1 -> 1.2 # include/asm-ppc/8xx_immap.h 1.1.1.1 -> 1.7 # include/asm-ppc/raven.h 1.1.1.2 -> 1.9 # include/asm-ppc/vc_ioctl.h 1.1.1.1 -> 1.7 # include/asm-ppc/immap_8260.h 1.1.1.1 -> 1.7 # arch/ppc/mm/mem_pieces.c 1.1.1.1 -> 1.7 # arch/ppc/kernel/indirect_pci.c 1.1.1.2 -> 1.9 # arch/ppc/math-emu/fmsub.c 1.1.1.1 -> 1.8 # arch/ppc/boot/include/zlib.h 1.1.1.1 -> 1.8 # arch/ppc/boot/prep/head.S 1.1.1.1 -> 1.8 # include/asm-ppc/scatterlist.h 1.1.1.1 -> 1.7 # include/asm-ppc/div64.h 1.1.1.1 -> 1.7 # arch/ppc/mm/init.c 1.1.2.6 -> 1.34 # arch/ppc/kernel/proc_rtas.c 1.1.1.1 -> (deleted) # arch/ppc/amiga/Makefile 1.1.1.2 -> 1.7 # arch/ppc/boot/include/nonstdio.h 1.1.1.1 -> 1.8 # include/asm-ppc/termbits.h 1.1.1.1 -> 1.7 # include/asm-ppc/pgalloc.h 1.1.1.4 -> 1.11 # arch/ppc/math-emu/mcrfs.c 1.1.1.1 -> 1.8 # include/asm-ppc/heathrow.h 1.1.1.2 -> 1.9 # include/asm-ppc/vga.h 1.1.1.1 -> 1.7 # include/asm-ppc/hdreg.h 1.1.1.1 -> 1.7 # arch/ppc/math-emu/mtfsb1.c 1.1.1.1 -> 1.8 # include/asm-ppc/irq.h 1.1.1.3 -> 1.11 # arch/ppc/kernel/oak_setup.c 1.1.1.1 -> 1.7 # arch/ppc/amiga/bootinfo.c 1.1.1.1 -> 1.7 # arch/ppc/config.in 1.1.2.7 -> 1.37 # include/asm-ppc/elf.h 1.1.1.3 -> 1.13 # include/asm-ppc/timex.h 1.1.1.1 -> 1.8 # arch/ppc/kernel/align.c 1.1.1.1 -> 1.7 # arch/ppc/math-emu/fnmadd.c 1.1.1.1 -> 1.8 # include/linux/blkdev.h 1.2.1.2 -> 1.5 # arch/ppc/boot/chrp/start.c 1.1.1.1 -> 1.7 # arch/ppc/kernel/prep_nvram.c 1.1.1.3 -> 1.11 # arch/ppc/8xx_io/fec.c 1.1.1.5 -> 1.14 # include/linux/proc_fs.h 1.1.1.4 -> 1.6 # arch/ppc/defconfig 1.1.1.4 -> 1.10 # include/asm-ppc/mbx.h 1.1.1.2 -> 1.10 # include/asm-ppc/resource.h 1.1.1.1 -> 1.7 # include/asm-ppc/mk48t59.h 1.1.1.1 -> 1.7 # fs/dcache.c 1.5.1.6 -> 1.12 # arch/ppc/boot/mbx/embed_config.c 1.1.1.1 -> 1.9 # arch/ppc/boot/mbx/rdimage.c 1.1.1.1 -> 1.7 # include/asm-ppc/serial.h 1.1.1.3 -> 1.18 # include/asm-ppc/rwsem.h 1.1.1.1 -> (deleted) # arch/ppc/boot/utils/mkprep.c 1.1.1.1 -> 1.8 # include/asm-ppc/init.h 1.1.1.1 -> 1.7 # include/asm-ppc/amigayle.h 1.1.1.1 -> 1.7 # drivers/net/ncr885e.c 1.1 -> (deleted) # include/asm-ppc/posix_types.h 1.1.1.1 -> 1.7 # include/asm-ppc/amigappc.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/chrp_time.c 1.1.1.2 -> 1.9 # arch/ppc/math-emu/fcmpo.c 1.1.1.1 -> 1.8 # include/asm-ppc/amipcmcia.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/pmac_setup.c 1.1.1.6 -> 1.24 # arch/ppc/kernel/smp.c 1.1.2.5 -> 1.26 # include/linux/dcache.h 1.3.1.3 -> 1.7 # arch/ppc/kernel/pmac_pic.c 1.1.1.4 -> 1.16 # arch/ppc/8xx_io/uart.c 1.2.1.3 -> 1.13 # arch/ppc/math-emu/Makefile 1.1.1.1 -> 1.5 # drivers/input/keybdev.c 1.1.1.4 -> 1.10 # arch/ppc/boot/common/ns16550.c 1.1.1.1 -> 1.9 # include/asm-ppc/backlight.h 1.1.1.1 -> 1.7 # drivers/block/swim3.c 1.1.1.1 -> 1.4 # arch/ppc/xmon/start.c 1.1.1.3 -> 1.16 # include/asm-ppc/linux_logo.h 1.1.1.3 -> 1.10 # arch/ppc/xmon/ppc-dis.c 1.1.1.1 -> 1.7 # arch/ppc/math-emu/stfiwx.c 1.1.1.1 -> 1.8 # drivers/ide/ide-pnp.c 1.1.1.1 -> 1.10 # fs/smbfs/cache.c 1.3.1.2 -> 1.6 # arch/ppc/boot/utils/Makefile 1.1 -> (deleted) # include/asm-ppc/uninorth.h 1.1.1.2 -> 1.9 # drivers/char/serial.c 1.1.1.7 -> 1.11 # arch/ppc/configs/gemini_defconfig 1.1.1.1 -> (deleted) # include/asm-ppc/mpc8xx.h 1.1.1.3 -> 1.12 # include/asm-ppc/gg2.h 1.1.1.1 -> 1.7 # include/asm-ppc/pci-bridge.h 1.1.1.4 -> 1.13 # arch/ppc/kernel/apus_setup.c 1.1.1.3 -> 1.13 # arch/ppc/kernel/ppc8xx_pic.c 1.1.1.3 -> 1.12 # drivers/macintosh/via-pmu.c 1.1.1.2 -> 1.5 # arch/ppc/amiga/amiga_ksyms.c 1.1.1.1 -> 1.7 # drivers/video/aty128.h 1.1 -> 1.2 # include/asm-ppc/page.h 1.1.1.1 -> 1.8 # include/asm-ppc/prep_nvram.h 1.1.1.2 -> 1.9 # include/asm-ppc/sembuf.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/bitops.c 1.1.1.2 -> 1.9 # arch/ppc/amiga/chipram.c 1.1.1.2 -> 1.9 # BitKeeper/etc/ignore 1.1 -> 1.8 # arch/ppc/boot/common/crt0.S 1.1.2.1 -> 1.12 # arch/ppc/kernel/i8259.c 1.1.1.2 -> 1.9 # arch/ppc/configs/SM850_defconfig 1.1.2.1 -> (deleted) # drivers/net/Config.in 1.1.1.11 -> 1.18 # arch/ppc/boot/tree/main.c 1.1.1.1 -> 1.9 # Documentation/sysrq.txt 1.2.1.1 -> 1.4 # drivers/ide/Config.in 1.1.1.1 -> 1.3 # drivers/i2c/Config.in 1.1 -> 1.2 # arch/ppc/boot/common/misc-simple.c 1.1 -> (deleted) # arch/ppc/mm/4xx_tlb.h 1.1.1.1 -> 1.7 # drivers/scsi/aic7xxx/aicasm/Makefile 1.1.1.2 -> 1.5 # include/asm-ppc/feature.h 1.1.1.3 -> 1.11 # arch/ppc/math-emu/types.c 1.1.1.1 -> 1.7 # arch/ppc/boot/utils/offset 1.1.2.1 -> 1.4 # include/asm-ppc/setup.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/error_log.h 1.1.1.1 -> (deleted) # arch/ppc/math-emu/fadds.c 1.1.1.1 -> 1.8 # arch/ppc/boot/pmac/coffmain.c 1.1.1.1 -> (deleted) # arch/ppc/boot/pmac/misc.S 1.1.1.1 -> 1.7 # arch/ppc/kernel/pmac_backlight.c 1.1.1.1 -> 1.7 # arch/ppc/configs/rpxcllf_defconfig 1.1.1.3 -> 1.9 # include/video/macmodes.h 1.1 -> 1.2 # include/asm-ppc/ipcbuf.h 1.1.1.1 -> 1.7 # include/asm-ppc/mpc8260.h 1.1.1.1 -> 1.9 # arch/ppc/kernel/open_pic.h 1.1.1.3 -> 1.12 # arch/ppc/kernel/gemini_pci.c 1.1.1.1 -> (deleted) # kernel/ksyms.c 1.14.1.1 -> 1.17 # include/asm-ppc/siginfo.h 1.1.1.1 -> 1.7 # arch/ppc/amiga/time.c 1.1.1.1 -> 1.7 # arch/ppc/configs/common_defconfig 1.1.1.3 -> 1.8 # arch/ppc/kernel/setup.c 1.1.2.6 -> 1.44 # drivers/video/chipsfb.c 1.1.1.2 -> 1.6 # drivers/net/bmac.c 1.1.1.2 -> 1.10 # drivers/net/ne2k-pci.c 1.1.1.3 -> 1.8 # MAINTAINERS 1.1.1.15 -> 1.20 # (new) -> 1.11 arch/ppc/boot/pmac/coffmain.c # arch/ppc/boot/mbx/gzimage.c 1.1.1.1 -> 1.7 # include/asm-ppc/shmparam.h 1.1.1.1 -> 1.7 # arch/ppc/8xx_io/Makefile 1.1.1.1 -> 1.5 # arch/ppc/math-emu/fcmpu.c 1.1.1.1 -> 1.8 # arch/ppc/math-emu/fsubs.c 1.1.1.1 -> 1.8 # include/asm-ppc/atomic.h 1.1.1.2 -> 1.10 # include/asm-ppc/pci.h 1.1.1.5 -> 1.15 # include/asm-ppc/shmbuf.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/oak_setup.h 1.1.1.1 -> 1.7 # include/asm-ppc/smplock.h 1.1.1.2 -> 1.9 # arch/ppc/kernel/idle.c 1.1.1.4 -> 1.14 # arch/ppc/kernel/walnut_setup.c 1.1.1.1 -> 1.7 # arch/ppc/configs/rpxlite_defconfig 1.1.1.3 -> 1.9 # arch/ppc/vmlinux.lds 1.1 -> 1.2 # include/asm-ppc/unistd.h 1.1.1.2 -> 1.9 # drivers/ide/ide-pci.c 1.4.1.1 -> 1.6 # drivers/video/macmodes.c 1.2 -> 1.3 # drivers/macintosh/mac_keyb.c 1.1 -> 1.2 # include/asm-ppc/processor.h 1.1.2.5 -> 1.31 # drivers/md/md.c 1.5.1.6 -> 1.12 # arch/ppc/kernel/signal.c 1.1.1.2 -> 1.9 # fs/nfsd/nfsproc.c 1.2.1.2 -> 1.5 # arch/ppc/kernel/pci-dma.c 1.1.1.1 -> 1.7 # arch/ppc/math-emu/fmuls.c 1.1.1.1 -> 1.8 # include/asm-ppc/mediabay.h 1.1.1.1 -> 1.7 # include/asm-ppc/ppc4xx.h 1.1.1.1 -> (deleted) # arch/ppc/8xx_io/commproc.c 1.1.1.2 -> 1.11 # scripts/mkdep.c 1.1.1.1 -> 1.4 # include/asm-ppc/nvram.h 1.1.1.1 -> 1.7 # include/asm-ppc/gemini_serial.h 1.1.1.1 -> (deleted) # arch/ppc/configs/IVMS8_defconfig 1.1.2.1 -> (deleted) # arch/ppc/math-emu/frsp.c 1.1.1.1 -> 1.8 # drivers/net/ncr885_debug.h 1.1 -> (deleted) # include/asm-ppc/termios.h 1.1.1.4 -> 1.11 # include/asm-ppc/checksum.h 1.1.1.2 -> 1.10 # arch/ppc/xmon/ppc-opc.c 1.1.1.1 -> 1.7 # arch/ppc/math-emu/fmul.c 1.1.1.1 -> 1.8 # arch/ppc/math-emu/lfd.c 1.1.1.1 -> 1.8 # include/asm-ppc/io.h 1.1.1.2 -> 1.9 # include/asm-ppc/socket.h 1.2.1.1 -> 1.8 # arch/i386/kernel/pci-pc.c 1.3.1.4 -> 1.8 # include/asm-ppc/smp.h 1.1.1.3 -> 1.11 # arch/ppc/kernel/process.c 1.1.1.4 -> 1.21 # Documentation/powerpc/00-INDEX 1.1 -> 1.3 # include/asm-ppc/ipc.h 1.1.1.1 -> 1.7 # arch/ppc/math-emu/op-common.h 1.1.1.1 -> 1.7 # arch/ppc/boot/tree/misc.S 1.1.1.1 -> 1.8 # include/asm-ppc/ide.h 1.1.1.3 -> 1.12 # arch/ppc/lib/Makefile 1.1.1.3 -> 1.9 # arch/ppc/amiga/cia.c 1.1.1.2 -> 1.9 # Documentation/powerpc/ppc_htab.txt 1.1.1.1 -> 1.3 # arch/ppc/boot/prep/of1275.h 1.1.1.1 -> 1.7 # include/asm-ppc/bootx.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/open_pic_defs.h 1.1.2.1 -> (deleted) # arch/ppc/boot/common/no_initrd.c 1.1.1.1 -> 1.8 # include/asm-ppc/amigahw.h 1.1.1.1 -> 1.7 # arch/ppc/math-emu/mtfsfi.c 1.1.1.1 -> 1.8 # Documentation/Configure.help 1.1.2.13 -> 1.34 # arch/ppc/boot/images/Makefile 1.1 -> (deleted) # include/asm-ppc/walnut.h 1.1.1.2 -> 1.9 # arch/ppc/kernel/semaphore.c 1.1.1.3 -> 1.13 # arch/ppc/xmon/start_8xx.c 1.1.1.2 -> 1.9 # arch/ppc/boot/mbx/misc.c 1.1.1.1 -> 1.9 # arch/ppc/amiga/amiints.c 1.2.1.2 -> 1.10 # fs/nfsd/vfs.c 1.2.1.2 -> 1.5 # include/asm-ppc/time.h 1.1.1.3 -> 1.12 # arch/ppc/kernel/gemini_prom.S 1.1.1.1 -> (deleted) # fs/proc/root.c 1.1.1.2 -> 1.4 # arch/ppc/boot/utils/piggyback.c 1.1.1.1 -> 1.8 # include/asm-ppc/mmu.h 1.1.1.2 -> 1.10 # drivers/net/gmac.c 1.1.1.2 -> 1.12 # arch/ppc/boot/tree/Makefile 1.1.3.1 -> 1.8 # include/asm-ppc/fads.h 1.1.1.2 -> 1.10 # arch/ppc/kernel/local_irq.h 1.1.1.2 -> 1.9 # arch/ppc/amiga/pcmcia.c 1.1.1.1 -> 1.7 # Makefile 1.19.1.23 -> 1.45 # arch/ppc/kernel/irq.c 1.1.1.6 -> 1.27 # include/asm-ppc/uaccess.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/prep_time.c 1.1.1.2 -> 1.9 # arch/ppc/8xx_io/enet.c 1.1.1.4 -> 1.12 # arch/ppc/kernel/Makefile 1.1.2.6 -> 1.30 # arch/ppc/mm/fault.c 1.1.1.4 -> 1.13 # arch/ppc/boot/mbx/head.S 1.1.1.1 -> 1.9 # include/asm-ppc/kgdb.h 1.1.1.1 -> 1.7 # arch/ppc/8260_io/commproc.c 1.1.1.1 -> 1.9 # arch/ppc/math-emu/mffs.c 1.1.1.1 -> 1.8 # arch/ppc/kernel/chrp_setup.c 1.1.1.8 -> 1.22 # include/asm-ppc/semaphore.h 1.1.1.5 -> 1.17 # arch/ppc/kernel/misc.S 1.1.1.3 -> 1.21 # arch/ppc/8260_io/Makefile 1.1.1.1 -> 1.5 # arch/ppc/math-emu/fnmadds.c 1.1.1.1 -> 1.8 # drivers/net/Makefile 1.1.1.7 -> 1.13 # arch/ppc/kernel/entry.S 1.1.1.4 -> 1.18 # arch/ppc/boot/mbx/Makefile 1.1.3.2 -> 1.9 # arch/ppc/boot/prep/of1275.c 1.1.1.1 -> 1.7 # arch/ppc/kernel/prep_setup.c 1.1.1.6 -> 1.24 # arch/ppc/kernel/xics.h 1.1.1.1 -> 1.7 # arch/ppc/math-emu/math.c 1.1.1.1 -> 1.8 # drivers/net/3c509.c 1.3.1.3 -> 1.7 # drivers/sound/dmasound/dmasound.h 1.1 -> 1.2 # arch/ppc/boot/mbx/pci.c 1.1.1.1 -> 1.7 # include/asm-ppc/stat.h 1.1.1.1 -> 1.7 # arch/ppc/math-emu/fdiv.c 1.1.1.1 -> 1.8 # arch/ppc/math-emu/fres.c 1.1.1.1 -> 1.8 # drivers/video/aty128fb.c 1.1.1.1 -> 1.6 # arch/ppc/xmon/ansidecl.h 1.1.1.1 -> 1.7 # arch/ppc/math-emu/op-1.h 1.1.1.1 -> 1.7 # arch/ppc/math-emu/fdivs.c 1.1.1.1 -> 1.8 # include/asm-ppc/keylargo.h 1.1.1.3 -> 1.11 # include/asm-ppc/prom.h 1.1.1.3 -> 1.15 # arch/ppc/math-emu/fmadd.c 1.1.1.1 -> 1.8 # arch/ppc/boot/lib/Makefile 1.1 -> (deleted) # arch/ppc/boot/prep/vreset.c 1.1.1.2 -> 1.10 # include/asm-ppc/spd8xx.h 1.1.1.1 -> (deleted) # drivers/video/offb.c 1.1.1.1 -> 1.6 # arch/ppc/kernel/ppc_ksyms.c 1.1.1.6 -> 1.39 # arch/ppc/boot/prep/kbd.c 1.1.1.1 -> 1.9 # include/asm-ppc/floppy.h 1.1.1.1 -> 1.7 # arch/ppc/boot/include/rs6000.h 1.1.1.1 -> 1.8 # include/asm-ppc/fcntl.h 1.1.1.1 -> 1.7 # arch/ppc/xmon/setjmp.c 1.1.1.1 -> 1.7 # drivers/video/clgenfb.c 1.1.1.2 -> 1.5 # drivers/video/atyfb.c 1.1.1.4 -> 1.7 # arch/ppc/boot/mbx/m8260_tty.c 1.1.1.1 -> 1.9 # include/asm-ppc/rpxhiox.h 1.1.1.1 -> (deleted) # arch/ppc/kernel/open_pic.c 1.1.2.4 -> 1.23 # arch/ppc/kernel/error_log.c 1.1.1.1 -> (deleted) # arch/ppc/math-emu/fmsubs.c 1.1.1.1 -> 1.8 # arch/ppc/math-emu/soft-fp.h 1.1.1.1 -> 1.7 # arch/ppc/boot/utils/elf.pl 1.1.2.1 -> 1.6 # arch/ppc/8xx_io/commproc.h 1.2.1.2 -> 1.13 # arch/ppc/math-emu/fctiw.c 1.1.1.1 -> 1.8 # include/asm-ppc/amigaints.h 1.1.1.1 -> 1.7 # include/asm-ppc/md.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/find_name.c 1.1.1.1 -> 1.7 # arch/ppc/math-emu/mtfsb0.c 1.1.1.1 -> 1.8 # include/asm-ppc/bitops.h 1.1.1.3 -> 1.10 # arch/ppc/boot/pmac/ld.script 1.1.2.1 -> 1.4 # include/asm-ppc/sockios.h 1.1.1.1 -> 1.7 # arch/ppc/lib/string.S 1.1.1.1 -> 1.7 # arch/ppc/configs/TQM850L_defconfig 1.1.2.1 -> (deleted) # include/asm-ppc/signal.h 1.1.1.1 -> 1.7 # include/asm-ppc/hw_irq.h 1.1.1.3 -> 1.12 # arch/ppc/lib/strcase.c 1.1.1.1 -> 1.7 # arch/ppc/configs/TQM860L_defconfig 1.1.2.1 -> (deleted) # drivers/scsi/sym53c8xx_defs.h 1.2 -> 1.3 # drivers/usb/hid.c 1.1.1.4 -> 1.6 # arch/ppc/boot/pmac/chrpmain.c 1.1.1.2 -> 1.11 # arch/ppc/boot/utils/hack-coff.c 1.1.1.1 -> 1.9 # arch/ppc/kernel/ppc8xx_pic.h 1.1.1.2 -> 1.9 # arch/ppc/lib/checksum.S 1.1.1.1 -> 1.7 # arch/ppc/math-emu/sfp-machine.h 1.1.1.1 -> 1.7 # include/asm-ppc/board.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/ptrace.c 1.1.1.1 -> 1.8 # arch/ppc/math-emu/fsqrts.c 1.1.1.1 -> 1.8 # arch/ppc/kernel/head.S 1.1.2.5 -> 1.24 # arch/ppc/boot/mbx/m8xx_tty.c 1.1.1.1 -> 1.9 # include/asm-ppc/hydra.h 1.1.1.1 -> 1.7 # arch/ppc/configs/oak_defconfig 1.1.1.3 -> 1.8 # arch/ppc/kernel/pmac_time.c 1.1.1.2 -> 1.10 # arch/ppc/math-emu/fmadds.c 1.1.1.1 -> 1.8 # fs/binfmt_elf.c 1.4.1.1 -> 1.7 # arch/ppc/kernel/prom.c 1.1.2.6 -> 1.26 # arch/ppc/kernel/hashtable.S 1.1.1.3 -> (deleted) # arch/ppc/math-emu/fnabs.c 1.1.1.1 -> 1.8 # arch/ppc/8260_io/uart.c 1.2.1.1 -> 1.10 # drivers/pci/pci.c 1.9.1.2 -> 1.13 # arch/ppc/boot/pmac/dummy.c 1.1.1.1 -> 1.7 # arch/ppc/kernel/ppc4xx_pic.c 1.1.1.1 -> 1.7 # drivers/macintosh/macserial.c 1.1.1.1 -> 1.8 # include/asm-ppc/statfs.h 1.1.1.1 -> 1.7 # arch/ppc/boot/utils/mknote.c 1.1.1.1 -> 1.8 # arch/ppc/kernel/apus_pci.h 1.1.1.1 -> (deleted) # arch/ppc/math-emu/fsub.c 1.1.1.1 -> 1.8 # include/asm-ppc/ppc4xx_serial.h 1.1.1.1 -> (deleted) # arch/ppc/math-emu/single.h 1.1.1.1 -> 1.7 # drivers/scsi/sym53c8xx.c 1.1.1.6 -> 1.10 # drivers/net/mace.c 1.1.1.5 -> 1.9 # arch/ppc/math-emu/fmr.c 1.1.1.1 -> 1.8 # drivers/pci/pci.ids 1.2.1.2 -> 1.5 # drivers/net/gmac.h 1.1.1.1 -> 1.6 # Documentation/powerpc/zImage_layout.txt 1.1.1.1 -> 1.4 # arch/ppc/boot/chrp/Makefile 1.1.1.2 -> 1.10 # arch/ppc/boot/utils/sisize 1.1.1.1 -> (deleted) # arch/ppc/kernel/checks.c 1.2.1.1 -> 1.8 # arch/ppc/kernel/apus_pci.c 1.1.1.1 -> (deleted) # include/linux/pci_ids.h 1.1.1.6 -> 1.12 # arch/ppc/boot/pmac/Makefile 1.1.1.3 -> 1.10 # arch/ppc/kernel/residual.c 1.2.1.1 -> 1.9 # arch/ppc/amiga/amisound.c 1.1.1.1 -> 1.7 # arch/ppc/math-emu/stfs.c 1.1.1.1 -> 1.8 # BitKeeper/etc/logging_ok 1.1.1.9 -> 1.30 # arch/ppc/boot/tree/irSect.h 1.1.1.1 -> 1.7 # include/asm-ppc/bugs.h 1.1.1.1 -> 1.7 # include/asm-ppc/tqm8xx.h 1.1.2.1 -> (deleted) # net/sunrpc/svcsock.c 1.2.1.3 -> 1.6 # include/asm-ppc/softirq.h 1.1.1.3 -> 1.11 # include/asm-ppc/dma.h 1.1.2.2 -> 1.10 # drivers/Makefile 1.1.1.2 -> 1.4 # include/asm-ppc/kmap_types.h 1.1.1.2 -> 1.8 # include/asm-ppc/module.h 1.1.1.1 -> 1.7 # include/asm-ppc/gemini.h 1.1.1.1 -> (deleted) # arch/ppc/kernel/m8260_setup.c 1.1.1.6 -> 1.19 # include/linux/rwsem.h 1.4.1.2 -> 1.7 # include/asm-ppc/sigcontext.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/traps.c 1.1.1.4 -> 1.14 # arch/ppc/kernel/gemini_setup.c 1.1.1.1 -> (deleted) # arch/ppc/configs/ibmchrp_defconfig 1.1.1.1 -> (deleted) # kernel/ptrace.c 1.1.1.1 -> 1.5 # Documentation/powerpc/sound.txt 1.1.1.1 -> 1.3 # arch/ppc/kernel/ppc-stub.c 1.1.1.1 -> 1.8 # arch/ppc/kernel/qspan_pci.c 1.1.1.1 -> 1.7 # arch/ppc/configs/walnut_defconfig 1.1.1.3 -> 1.8 # drivers/block/ll_rw_blk.c 1.1.1.13 -> 1.16 # include/asm-ppc/errno.h 1.1.1.1 -> 1.9 # include/asm-ppc/string.h 1.1.1.1 -> 1.7 # arch/ppc/8260_io/fcc_enet.c 1.1.1.4 -> 1.11 # arch/ppc/math-emu/frsqrte.c 1.1.1.1 -> 1.8 # arch/ppc/boot/prep/Makefile 1.1 -> (deleted) # arch/ppc/xmon/Makefile 1.1.1.1 -> 1.5 # drivers/pci/Makefile 1.1.1.3 -> 1.6 # arch/ppc/math-emu/lfs.c 1.1.1.1 -> 1.8 # fs/ncpfs/dir.c 1.3.1.1 -> 1.5 # drivers/macintosh/Makefile 1.1.1.1 -> 1.4 # arch/ppc/kernel/feature.c 1.1.1.4 -> 1.13 # include/asm-ppc/bseip.h 1.1.1.2 -> 1.9 # include/asm-ppc/parport.h 1.1.1.1 -> (deleted) # arch/ppc/kernel/ppc_asm.h 1.1.1.3 -> 1.13 # arch/ppc/kernel/ppc8260_pic.c 1.1.1.1 -> 1.7 # arch/ppc/math-emu/fsel.c 1.1.1.1 -> 1.8 # include/asm-ppc/segment.h 1.1.1.2 -> 1.9 # arch/ppc/kernel/pmac_nvram.c 1.1.1.1 -> 1.7 # arch/ppc/xmon/ppc.h 1.1.1.1 -> 1.7 # arch/ppc/boot/tree/irSect.c 1.1.1.1 -> 1.7 # include/asm-ppc/byteorder.h 1.1.1.1 -> 1.7 # include/asm-ppc/namei.h 1.1.1.1 -> 1.7 # include/asm-ppc/xor.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/pci.c 1.1.1.6 -> 1.24 # arch/ppc/math-emu/double.h 1.1.1.1 -> 1.7 # drivers/i2c/Makefile 1.1 -> 1.2 # arch/ppc/math-emu/fnmsubs.c 1.1.1.1 -> 1.8 # drivers/net/ncr885e.h 1.1 -> (deleted) # (new) -> 1.9 arch/ppc/boot/common/string.S # arch/ppc/boot/common/string.S 1.1.1.1 -> (deleted) # arch/ppc/boot/utils/mkirimg 1.1.2.1 -> 1.7 # arch/ppc/mm/mem_pieces.h 1.1.1.1 -> 1.7 # include/asm-ppc/hardirq.h 1.1.1.3 -> 1.11 # arch/ppc/kernel/galaxy_pci.c 1.1.1.2 -> 1.9 # arch/ppc/configs/est8260_defconfig 1.1.1.3 -> 1.8 # arch/ppc/math-emu/stfd.c 1.1.1.1 -> 1.8 # drivers/sound/dmasound/dmasound_awacs.c 1.1.1.1 -> 1.6 # arch/ppc/amiga/ints.c 1.1.1.1 -> 1.7 # arch/ppc/xmon/privinst.h 1.1.1.1 -> 1.7 # arch/ppc/8xx_io/Config.in 1.1.1.2 -> 1.5 # arch/ppc/boot/mbx/qspan_pci.c 1.1.1.1 -> 1.7 # include/asm-ppc/cpm_8260.h 1.1.1.2 -> 1.11 # include/asm-ppc/mman.h 1.1.1.2 -> 1.9 # include/asm-ppc/keyboard.h 1.1.1.1 -> 1.7 # arch/ppc/boot/prep/iso_font.h 1.1.1.1 -> 1.7 # arch/ppc/mm/4xx_tlb.c 1.1.1.1 -> 1.7 # arch/ppc/Makefile 1.1.1.5 -> 1.18 # arch/ppc/boot/chrp/misc.S 1.1.1.1 -> 1.7 # arch/ppc/boot/utils/mksimage.c 1.1.1.1 -> (deleted) # drivers/net/pcnet32.c 1.1.1.6 -> 1.9 # include/asm-ppc/cache.h 1.1.1.1 -> 1.9 # arch/ppc/math-emu/op-4.h 1.1.1.1 -> 1.7 # drivers/sound/dmasound/Makefile 1.1 -> 1.2 # arch/ppc/boot/utils/sioffset 1.1.1.1 -> (deleted) # arch/ppc/kernel/ppc_htab.c 1.1.1.2 -> 1.14 # arch/ppc/math-emu/op-2.h 1.1.1.1 -> 1.7 # drivers/scsi/sr.c 1.3.1.2 -> 1.6 # arch/ppc/8260_io/Config.in 1.1 -> 1.3 # include/asm-ppc/ioctl.h 1.1.1.1 -> 1.7 # arch/ppc/mm/extable.c 1.1.1.1 -> 1.7 # arch/ppc/kernel/head_4xx.S 1.1.1.1 -> 1.8 # Documentation/powerpc/smp.txt 1.1.1.1 -> 1.3 # drivers/sound/dmasound/dmasound_core.c 1.1.1.1 -> 1.5 # include/asm-ppc/a.out.h 1.1.1.1 -> 1.7 # include/asm-ppc/pnp.h 1.1.1.1 -> 1.7 # include/asm-ppc/ivms8.h 1.1.1.1 -> (deleted) # arch/ppc/kernel/prep_pci.c 1.1.1.5 -> 1.22 # arch/ppc/math-emu/fabs.c 1.1.1.1 -> 1.8 # arch/ppc/boot/utils/size 1.1.2.1 -> 1.4 # include/asm-ppc/residual.h 1.1.1.1 -> 1.7 # include/asm-ppc/rpxlite.h 1.1.1.2 -> 1.10 # arch/ppc/kernel/ppc8260_pic.h 1.1.1.2 -> 1.9 # arch/ppc/math-emu/udivmodti4.c 1.1.1.1 -> 1.7 # arch/ppc/configs/power3_defconfig 1.1.1.1 -> (deleted) # include/asm-ppc/spinlock.h 1.1.1.1 -> 1.9 # include/asm-ppc/tlb.h 1.1.1.1 -> (deleted) # arch/ppc/mm/Makefile 1.1.1.1 -> 1.6 # arch/ppc/kernel/m8xx_setup.c 1.1.1.6 -> 1.19 # arch/ppc/kernel/pmac_pci.c 1.1.1.4 -> 1.16 # arch/ppc/configs/SPD823TS_defconfig 1.1.2.1 -> (deleted) # arch/ppc/configs/TQM823L_defconfig 1.1.2.1 -> (deleted) # arch/ppc/math-emu/fadd.c 1.1.1.1 -> 1.8 # arch/ppc/math-emu/fctiwz.c 1.1.1.1 -> 1.8 # include/linux/highmem.h 1.2 -> 1.3 # arch/ppc/boot/Makefile 1.1.2.3 -> 1.17 arch/ppc/boot/prep/Makefile (moved) # arch/ppc/boot/mbx/iic.c 1.1.1.1 -> 1.9 # include/asm-ppc/current.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/xics.c 1.1.1.1 -> 1.7 # arch/ppc/kernel/walnut_setup.h 1.1.1.1 -> 1.7 # arch/ppc/xmon/adb.c 1.1.1.1 -> 1.7 # arch/ppc/boot/common/misc-common.c 1.1.1.1 -> (deleted) # include/linux/mmzone.h 1.1.1.3 -> 1.5 # include/asm-ppc/user.h 1.1.1.1 -> 1.7 # include/asm-ppc/highmem.h 1.1.1.2 -> 1.10 # include/asm-ppc/oak.h 1.1.1.2 -> 1.9 # include/asm-ppc/ucontext.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/softemu8xx.c 1.1.1.3 -> 1.10 # arch/ppc/kernel/syscalls.c 1.2.1.2 -> 1.10 # drivers/i2c/i2c-core.c 1.2 -> 1.4 # arch/ppc/boot/pmac/start.c 1.1.1.2 -> 1.9 # include/asm-ppc/delay.h 1.1.1.2 -> 1.9 # include/asm-ppc/types.h 1.1.1.1 -> 1.7 # include/asm-ppc/rpxclassic.h 1.1.1.2 -> 1.10 # drivers/macintosh/macserial.h 1.1.1.1 -> 1.4 # drivers/net/bmac.h 1.1 -> 1.3 # (new) -> 1.3 arch/ppc/boot/utils/sioffset # (new) -> 1.1 include/asm-ppc/iSeries/HvCallEvent.h # (new) -> 1.1 include/asm-ppc/iSeries/ItLpRegSave.h # (new) -> 1.1 include/asm-ppc/iSeries/HvCall.h # (new) -> 1.2 arch/ppc/kernel/mcpn765_setup.c # (new) -> 1.1 arch/ppc/kernel/pci_auto.c # (new) -> 1.5 include/asm-ppc/tlb.h # (new) -> 1.3 arch/ppc/configs/gemini_defconfig # (new) -> 1.1 arch/ppc/configs/menf1_defconfig # (new) -> 1.1 arch/ppc/iSeries/iSeries_pci.h # (new) -> 1.1 arch/ppc/iSeries/rtc.c # (new) -> 1.1 arch/ppc/boot/zx4500/head.S # (new) -> 1.1 arch/ppc/kernel/mvme5100_pci.c # (new) -> 1.1 arch/ppc/iSeries/iSeries_FlightRecorder.c # (new) -> 1.1 arch/ppc/boot/lib/Makefile # (new) -> 1.1 arch/ppc/iSeries/ItLpQueue.c # (new) -> 1.1 arch/ppc/iSeries/mf_proc.c # (new) -> 1.1 arch/ppc/kernel/prpmc750_pci.c # (new) -> 1.1 arch/ppc/kernel/pcore_setup.c # (new) -> 1.1 include/asm-ppc/iSeries/iSeries_pci.h # (new) -> 1.2 arch/ppc/configs/power3_defconfig # (new) -> 1.1 arch/ppc/boot/spruce/Makefile # (new) -> 1.1 BitKeeper/etc/COPYING # (new) -> 1.1 arch/ppc/iSeries/pmc_proc.c # (new) -> 1.1 include/asm-ppc/iSeries/mf.h # (new) -> 1.1 arch/ppc/boot/utils/mkpmon.c # (new) -> 1.1 include/asm-ppc/iSeries/ItLpQueue.h # (new) -> 1.1 include/asm-ppc/iSeries/iSeries_dma.h # (new) -> 1.1 arch/ppc/boot/utils/mkbugboot.c # (new) -> 1.1 include/asm-ppc/spruce.h # (new) -> 1.1 arch/ppc/kernel/cpc710.h # (new) -> 1.2 arch/ppc/configs/ibmchrp_defconfig # (new) -> 1.3 drivers/net/ncr885e.h # (new) -> 1.1 arch/ppc/kernel/mcpn765.h # (new) -> 1.1 include/asm-ppc/iSeries/IoHriProcessorVpd.h # (new) -> 1.1 arch/ppc/kernel/iSeries_head.S # (new) -> 1.1 arch/ppc/kernel/cpc700.h # (new) -> 1.1 include/asm-ppc/iSeries/HvCallPci.h # (new) -> 1.1 arch/ppc/iSeries/HvLpConfig.c # (new) -> 1.4 arch/ppc/configs/SPD823TS_defconfig # (new) -> 1.1 arch/ppc/boot/menf1/Makefile # (new) -> 1.2 arch/ppc/boot/pp3/Makefile # (new) -> 1.1 include/asm-ppc/iSeries/iSeries_proc.h # (new) -> 1.1 arch/ppc/configs/k2_defconfig # (new) -> 1.1 arch/ppc/iSeries/iSeries_fixup.c # (new) -> 1.1 arch/ppc/kernel/prpmc750_setup.c # (new) -> 1.1 arch/ppc/boot/utils/Makefile # (new) -> 1.1 include/asm-ppc/iSeries/iSeries_io.h # (new) -> 1.1 arch/ppc/kernel/zx4500.h # (new) -> 1.1 arch/ppc/configs/mcpn765_defconfig # (new) -> 1.3 arch/ppc/kernel/apus_pci.c # (new) -> 1.1 arch/ppc/boot/sandpoint/Makefile # (new) -> 1.3 arch/ppc/boot/utils/sisize # (new) -> 1.6 BitKeeper/triggers/post-incoming # (new) -> 1.1 Documentation/powerpc/todc.txt # (new) -> 1.1 arch/ppc/iSeries/LparData.c # (new) -> 1.1 arch/ppc/configs/prpmc750_defconfig # (new) -> 1.1 arch/ppc/iSeries/iSeries_IoMmTable.h # (new) -> 1.4 drivers/i2c/i2c-rpx.c # (new) -> 1.1 arch/ppc/configs/mvme5100_defconfig # (new) -> 1.2 BitKeeper/etc/gone # (new) -> 1.5 include/asm-ppc/spd8xx.h # (new) -> 1.1 include/asm-ppc/iSeries/veth-proc.h # (new) -> 1.1 arch/ppc/iSeries/XmPciLpEvent.c # (new) -> 1.1 include/asm-ppc/cputable.h # (new) -> 1.5 arch/ppc/kernel/gemini_prom.S # (new) -> 1.1 arch/ppc/configs/spruce_defconfig # (new) -> 1.1 arch/ppc/iSeries/iSeries_VpdInfo.c # (new) -> 1.1 include/asm-ppc/iSeries.h # (new) -> 1.1 include/asm-ppc/iSeries/HvCallCfg.h # (new) -> 1.1 include/asm-ppc/mvme5100_serial.h # (new) -> 1.1 arch/ppc/kernel/iSeries_dma.c # (new) -> 1.1 include/asm-ppc/iSeries/HvLpEvent.h # (new) -> 1.1 arch/ppc/boot/iSeries/addRamDisk.c # (new) -> 1.4 arch/ppc/configs/TQM860L_defconfig # (new) -> 1.1 arch/ppc/kernel/menf1_pci.c # (new) -> 1.1 arch/ppc/boot/pp3/head.S # (new) -> 1.1 arch/ppc/kernel/spruce_pci.c # (new) -> 1.1 include/asm-ppc/iSeries/iSeries_VpdInfo.h # (new) -> 1.1 arch/ppc/kernel/mpc10x_common.c # (new) -> 1.1 arch/ppc/boot/spruce/head.S # (new) -> 1.1 arch/ppc/kernel/iSeries_hashtable.c # (new) -> 1.2 arch/ppc/kernel/spruce_setup.c # (new) -> 1.1 arch/ppc/kernel/sandpoint.h # (new) -> 1.1 arch/ppc/kernel/todc_time.c # (new) -> 1.1 include/asm-ppc/iSeries/HvCallSm.h # (new) -> 1.1 include/asm-ppc/iSeries/Paca.h # (new) -> 1.2 arch/ppc/kernel/temp.c # (new) -> 1.1 arch/ppc/kernel/m1543c.h # (new) -> 1.1 arch/ppc/boot/common/misc-simple.c # (new) -> 1.1 Documentation/powerpc/host_bridge.txt # (new) -> 1.1 arch/ppc/kernel/mpc10x.h # (new) -> 1.1 arch/ppc/kernel/cputable.c # (new) -> 1.2 arch/ppc/kernel/zx4500_setup.c # (new) -> 1.1 arch/ppc/kernel/prpmc750.h # (new) -> 1.1 include/asm-ppc/iSeries/HvCallSc.h # (new) -> 1.1 include/asm-ppc/iSeries/iSeries_fixup.h # (new) -> 1.1 arch/ppc/boot/iSeries/addSystemMap.c # (new) -> 1.1 arch/ppc/iSeries/iSeries_pci_proc.c # (new) -> 1.1 include/asm-ppc/zx4500_serial.h # (new) -> 1.1 arch/ppc/boot/menf1/head.S # (new) -> 1.1 arch/ppc/iSeries/iSeries_IoMmTable.c # (new) -> 1.1 arch/ppc/iSeries/iSeries_pci.c # (new) -> 1.1 arch/ppc/boot/pcore/Makefile # (new) -> 1.2 include/linux/i2c-algo-8xx.h # (new) -> 1.4 arch/ppc/configs/SM850_defconfig # (new) -> 1.3 include/asm-ppc/ppc4xx.h # (new) -> 1.1 arch/ppc/kernel/menf1.h # (new) -> 1.1 arch/ppc/kernel/mcpn765_pci.c # (new) -> 1.1 include/asm-ppc/prpmc750_serial.h # (new) -> 1.5 include/asm-ppc/gemini_serial.h # (new) -> 1.1 arch/ppc/kernel/spruce_pic.c # (new) -> 1.1 include/asm-ppc/iSeries/ItLpPaca.h # (new) -> 1.1 include/asm-ppc/iSeries/ItVpdAreas.h # (new) -> 1.3 drivers/net/ncr885e.c # (new) -> 1.5 include/asm-ppc/parport.h # (new) -> 1.1 include/asm-ppc/iSeries/Naca.h # (new) -> 1.5 include/asm-ppc/gemini.h # (new) -> 1.1 arch/ppc/boot/sandpoint/head.S # (new) -> 1.1 include/asm-ppc/iSeries/iSeries_irq.h # (new) -> 1.5 arch/ppc/kernel/error_log.h # (new) -> 1.1 arch/ppc/iSeries/Makefile # (new) -> 1.1 drivers/sgi/char/linux_logo.h # (new) -> 1.1 arch/ppc/iSeries/iSeries_proc.c # (new) -> 1.1 arch/ppc/boot/zx4500/Makefile # (new) -> 1.1 arch/ppc/boot/pcore/head.S # (new) -> 1.1 arch/ppc/iSeries/mf.c # (new) -> 1.4 arch/ppc/configs/TQM823L_defconfig # (new) -> 1.1 arch/ppc/boot/spruce/misc.c # (new) -> 1.1 include/asm-ppc/iSeries/HvLpConfig.h # (new) -> 1.1 include/asm-ppc/spruce_serial.h # (new) -> 1.1 arch/ppc/configs/sandpoint_defconfig # (new) -> 1.1 arch/ppc/configs/iSeries_defconfig # (new) -> 1.1 arch/ppc/kernel/mvme5100.h # (new) -> 1.1 include/asm-ppc/iSeries/LparData.h # (new) -> 1.1 arch/ppc/kernel/menf1_setup.c # (new) -> 1.3 arch/ppc/configs/IVMS8_defconfig # (new) -> 1.6 arch/ppc/boot/utils/mksimage.c # (new) -> 1.1 arch/ppc/iSeries/HvCall.c # (new) -> 1.3 drivers/net/ncr885_debug.h # (new) -> 1.1 include/asm-ppc/iSeries/IoHriMainStore.h # (new) -> 1.3 arch/ppc/mm/hashtable.S # (new) -> 1.1 arch/ppc/iSeries/createReleaseData # (new) -> 1.1 arch/ppc/iSeries/iSeries_reset_device.c # (new) -> 1.1 include/asm-ppc/iSeries/XmPciLpEvent.h # (new) -> 1.2 arch/ppc/kernel/ppc_stubs.c # (new) -> 1.1 arch/ppc/boot/common/Makefile # (new) -> 1.1 arch/ppc/kernel/iSeries_setup.c # (new) -> 1.1 arch/ppc/kernel/iSeries_setup.h # (new) -> 1.1 arch/ppc/iSeries/HvLpEvent.c # (new) -> 1.6 arch/ppc/kernel/error_log.c # (new) -> 1.5 include/asm-ppc/ivms8.h # (new) -> 1.12 arch/ppc/boot/Makefile # (new) -> 1.1 arch/ppc/kernel/mvme5100_setup.c # (new) -> 1.6 include/asm-ppc/rwsem.h # (new) -> 1.1 include/asm-ppc/iSeries/LparMap.h # (new) -> 1.1 include/asm-ppc/iSeries/mf_proc.h # (new) -> 1.1 include/asm-ppc/iSeries/HvCallHpt.h # (new) -> 1.1 include/asm-ppc/iSeries/HvReleaseData.h # (new) -> 1.1 arch/ppc/iSeries/iSeries_irq.c # (new) -> 1.1 arch/ppc/configs/pcore_defconfig # (new) -> 1.1 include/asm-ppc/mcpn765_serial.h # (new) -> 1.1 arch/ppc/kernel/k2_pic.c # (new) -> 1.5 arch/ppc/kernel/proc_rtas.c # (new) -> 1.3 include/asm-ppc/ppc4xx_serial.h # (new) -> 1.1 include/asm-ppc/iSeries/ItIplParmsReal.h # (new) -> 1.5 arch/ppc/kernel/gemini_pci.c # (new) -> 1.1 arch/ppc/kernel/pplus.h # (new) -> 1.1 arch/ppc/iSeries/iSeries_ksyms.c # (new) -> 1.1 arch/ppc/kernel/k2.h # (new) -> 1.1 arch/ppc/kernel/k2_pci.c # (new) -> 1.1 include/asm-ppc/iSeries/HvTypes.h # (new) -> 1.1 arch/ppc/configs/zx4500_defconfig # (new) -> 1.1 arch/ppc/kernel/pcore.h # (new) -> 1.1 arch/ppc/kernel/pci_auto.h # (new) -> 1.1 include/asm-ppc/iSeries/ItSpCommArea.h # (new) -> 1.1 arch/ppc/kernel/todc.h # (new) -> 1.1 include/asm-ppc/iSeries/pmc_proc.h # (new) -> 1.1 arch/ppc/iSeries/viopath.c # (new) -> 1.6 include/asm-ppc/tqm8xx.h # (new) -> 1.1 arch/ppc/kernel/pplus_common.c # (new) -> 1.1 include/asm-ppc/iSeries/vio.h # (new) -> 1.3 include/asm-ppc/rpxhiox.h # (new) -> 1.1 arch/ppc/boot/pmon/head.S # (new) -> 1.8 arch/ppc/kernel/open_pic_defs.h # (new) -> 1.7 arch/ppc/kernel/gemini_setup.c # (new) -> 1.2 arch/ppc/kernel/sandpoint_setup.c # (new) -> 1.4 arch/ppc/configs/TQM850L_defconfig # (new) -> 1.1 arch/ppc/kernel/zx4500_pci.c # (new) -> 1.4 drivers/i2c/i2c-algo-8xx.c # (new) -> 1.4 arch/ppc/kernel/apus_pci.h # (new) -> 1.1 arch/ppc/kernel/sandpoint_pci.c # (new) -> 1.2 arch/ppc/boot/pmon/Makefile # (new) -> 1.3 arch/ppc/boot/common/misc-common.c # (new) -> 1.1 arch/ppc/boot/images/Makefile # (new) -> 1.1 arch/ppc/kernel/pcore_pci.c # (new) -> 1.1 include/asm-ppc/iSeries/HvCallXm.h # (new) -> 1.1 include/asm-ppc/iSeries/ItLpNaca.h # (new) -> 1.1 include/asm-ppc/iSeries/iSeries_FlightRecorder.h # (new) -> 1.1 arch/ppc/kernel/k2_setup.c # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 01/06/15 paulus@tango.paulus.ozlabs.org 1.2.2.24 # bk-work-patch-pre3.8622.new # -------------------------------------------- # 01/06/15 paulus@tango.paulus.ozlabs.org 1.118.1.17 # merge to 2.4.6-pre3 # -------------------------------------------- # 01/06/15 paulus@cargo.(none) 1.133 # Merge cargo.(none):/home/paulus/kernel/linuxppc_2_4 # into cargo.(none):/home/paulus/kernel/linuxppc_2_4_devel # -------------------------------------------- # 01/06/15 paulus@cargo.(none) 1.134 # Ben's cpu features stuff, with some minor modifications by paulus. # It would be good if the 8xx/4xx folks could chip in with whatever # extra bits are needed for those chips. # -------------------------------------------- # 01/06/15 paulus@cargo.(none) 1.135 # Changes to allow us to use devices behind a PCI-PCI bridge # on the 2nd or subsequent host bridge successfully - the particular # example I had was a 4-port ethernet card. # -------------------------------------------- # 01/06/15 paulus@cargo.(none) 1.118.1.18 # Patches 02-printbt.patch, 03-sysrq.patch and 04-prepboot.patch # from Tom Rini # -------------------------------------------- # 01/06/15 paulus@cargo.(none) 1.118.1.19 # 4xx boot patch from Tom Rini (05-4xxboot.patch) # -------------------------------------------- # 01/06/15 paulus@cargo.(none) 1.118.1.20 # 4xx update from Montavista via Tom Rini # -------------------------------------------- # 01/06/15 paulus@cargo.(none) 1.136 # merge recent _2_4 changes into _2_4_devel # -------------------------------------------- # 01/06/15 paulus@cargo.(none) 1.137 # Add colormap changing support for the IBM GXT2000P card # Fix the bug with blanking where the colormap would get # trashed on unblank # -------------------------------------------- # 01/06/16 paulus@cargo.(none) 1.118.1.21 # update rs/6000 and PPP entries # -------------------------------------------- # 01/06/16 paulus@cargo.(none) 1.118.1.22 # Add support for changing the colormap on the IBM GXT2000P card # Fix the bug where unblank would trash the colormap # -------------------------------------------- # 01/06/16 benh@zion.wanadoo.fr 1.136.1.1 # Fix macserial as a module, fix hashtable.S compile # -------------------------------------------- # 01/06/16 paulus@cargo.(none) 1.118.1.23 # use module_init to initialize macserial # -------------------------------------------- # 01/06/16 paulus@cargo.(none) 1.138 # Merge hq.fsmlabs.com:/home/bk/linuxppc_2_4_devel # into cargo.(none):/home/paulus/kernel/linuxppc_2_4_devel # -------------------------------------------- # 01/06/16 paulus@cargo.(none) 1.139 # merge recent changes from _2_4 # -------------------------------------------- # 01/06/16 paulus@cargo.(none) 1.140 # Since some platforms set up BAT mappings above ioremap_base that # don't have virtual == physical, add a new variable ioremap_1to1_end # and use it to stop ioremap thinking it should use virtual == physical # in those areas. # -------------------------------------------- # diff -Nru a/BitKeeper/etc/gone b/BitKeeper/etc/gone --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/BitKeeper/etc/gone Sat Jun 16 06:00:30 2001 @@ -0,0 +1,2 @@ +include/linux/openpic.h +arch/ppc/coffboot/main.c diff -Nru a/BitKeeper/etc/ignore b/BitKeeper/etc/ignore --- a/BitKeeper/etc/ignore Sat Jun 16 06:00:18 2001 +++ b/BitKeeper/etc/ignore Sat Jun 16 06:00:18 2001 @@ -1 +1,82 @@ -BitKeeper/*/* +*.a +*.o +*.stamp +*.ver +.*.a.flags +.*.o.flags +.config +.config.old +.depend +.hdepend +.version +BitKeeper/etc/.cached_proxy +BitKeeper/etc/csets-in +BitKeeper/etc/csets-out +BitKeeper/etc/level +PENDING/* +System.map +arch/ppc/boot/images/miboot.* +arch/ppc/boot/images/miboot.image +arch/ppc/boot/images/sImage +arch/ppc/boot/images/vmlinux* +arch/ppc/boot/images/vmlinux.* +arch/ppc/boot/images/zImage* +arch/ppc/boot/images/zImage.* +arch/ppc/boot/images/zvmlinux* +arch/ppc/boot/mkprep +arch/ppc/boot/mksimage +arch/ppc/boot/sImage +arch/ppc/boot/utils/addnote +arch/ppc/boot/utils/coffboot +arch/ppc/boot/utils/hack-coff +arch/ppc/boot/utils/mkbugboot +arch/ppc/boot/utils/mknote +arch/ppc/boot/utils/mkprep +arch/ppc/boot/utils/mksimage +arch/ppc/boot/utils/note +arch/ppc/boot/utils/piggyback +arch/ppc/boot/zImage +arch/ppc/boot/zvmlinux +arch/ppc/chrpboot/addnote +arch/ppc/chrpboot/piggyback +arch/ppc/chrpboot/zImage +arch/ppc/chrpboot/zImage.rs6k +arch/ppc/coffboot/coffboot +arch/ppc/coffboot/hack-coff +arch/ppc/coffboot/miboot.image +arch/ppc/coffboot/mknote +arch/ppc/coffboot/note +arch/ppc/coffboot/piggyback +arch/ppc/coffboot/vmlinux.coff +arch/ppc/coffboot/vmlinux.elf +arch/ppc/coffboot/vmlinux.gz +arch/ppc/coffboot/zImage +arch/ppc/kernel/checks +arch/ppc/kernel/ppc_defs.h +drivers/char/conmakehash +drivers/char/consolemap_deftbl.c +drivers/net/hamradio/soundmodem/gentbl +drivers/net/hamradio/soundmodem/sm_tbl_afsk1200.h +drivers/net/hamradio/soundmodem/sm_tbl_afsk2400_7.h +drivers/net/hamradio/soundmodem/sm_tbl_afsk2400_8.h +drivers/net/hamradio/soundmodem/sm_tbl_afsk2666.h +drivers/net/hamradio/soundmodem/sm_tbl_fsk9600.h +drivers/net/hamradio/soundmodem/sm_tbl_hapn4800.h +drivers/net/hamradio/soundmodem/sm_tbl_psk4800.h +drivers/pci/classlist.h +drivers/pci/devlist.h +drivers/pci/gen-devlist +drivers/scsi/aic7xxx/aicasm/aicasm +drivers/scsi/aic7xxx/aicasm/aicasm_gram.c +drivers/scsi/aic7xxx/aicasm/aicasm_scan.c +drivers/scsi/aic7xxx/aicasm/y.tab.h +include/asm +include/config/* +include/linux/autoconf.h +include/linux/compile.h +include/linux/modversions.h +include/linux/version.h +scripts/lxdialog/lxdialog +scripts/mkdep +scripts/split-include +vmlinux diff -Nru a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok --- a/BitKeeper/etc/logging_ok Sat Jun 16 06:00:24 2001 +++ b/BitKeeper/etc/logging_ok Sat Jun 16 06:00:24 2001 @@ -1,10 +1,29 @@ +benh@sawtooth.wanadoo.fr +benh@streumon.mipsys.com +benh@zion.wanadoo.fr +cort@cort. +cort@cort.fsmlabs.com +cort@f50.fsmlabs.com cort@ftsoj.fsmlabs.com -paulus@diego.linuxcare.com.au -paulus@argo.linuxcare.com.au -paulus@tango.linuxcare.com.au cort@hq.fsmlabs.com +danc@phong.az.mvista.com +dmalek@dp500.netx4.com +geert@callisto.of.borg +geert@tux.home +geert@tux.of.borg +geert@tux.sonytel.be +hozer@narn.drgw.net +hozer@narn.local.drgw.net +mporter@beef.az.mvista.com +paulus@argo.canberra.net.au +paulus@argo.linuxcare.com.au +paulus@argo.ozlabs.ibm.com paulus@argo.ozlabs.ibm.com.au -cort@cort.fsmlabs.com -cort@f50.fsmlabs.com -cort@cort. +paulus@cargo.(none) +paulus@diego.linuxcare.com.au +paulus@tango.linuxcare.com.au paulus@tango.paulus.ozlabs.org +tgall@vorlon.rchland.ibm.com +trini@bill-the-cat.bloom.county +trini@entropy.crashing.org +trini@opus.bloom.county diff -Nru a/BitKeeper/triggers/post-incoming b/BitKeeper/triggers/post-incoming --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/BitKeeper/triggers/post-incoming Sat Jun 16 06:00:30 2001 @@ -0,0 +1,12 @@ +#!/bin/sh + +REPO=`bk gethost`:`pwd` +if [ "$BK_STATUS" = OK -a -f BitKeeper/etc/csets-in -a `hostname` = "hq.fsmlabs.com" ] +then ( + echo ${USER} + echo "" + bk changes -v - < BitKeeper/etc/csets-in + bk prs -d ":KEY:\n" -r+ ChangeSet + ) | mail -s "Incoming to $REPO" linuxppc-commit@fsmlabs.com +fi + diff -Nru a/CREDITS b/CREDITS --- a/CREDITS Sat Jun 16 06:00:15 2001 +++ b/CREDITS Sat Jun 16 06:00:15 2001 @@ -1136,13 +1136,11 @@ S: USA N: Benjamin Herrenschmidt -E: bh40@calva.net +E: benh@kernel.crashing.org E: benh@mipsys.com -D: PowerMac booter (BootX) -D: Additional PowerBook support -D: Apple "Core99" machines support (ibook,g4,...) -S: 22, rue des Marguettes -S: 75012 Paris +D: Various parts of PPC & PowerMac +S: 122, boulevard Baille +S: 13005 Marseille S: France N: Sebastian Hetze @@ -1755,6 +1753,8 @@ N: Paul Mackerras E: paulus@samba.org +D: PPP driver +D: Linux for PowerPC D: Linux port for PCI Power Macintosh N: Pat Mackinlay diff -Nru a/Documentation/Configure.help b/Documentation/Configure.help --- a/Documentation/Configure.help Sat Jun 16 06:00:20 2001 +++ b/Documentation/Configure.help Sat Jun 16 06:00:20 2001 @@ -13094,6 +13094,15 @@ If unsure, say N. +Use a non standard baud rate on serial console +CONFIG_SERIAL_CONSOLE_NONSTD + By default the serial console code assumes that all of the registers + for setting up the baud rate are set. In some cases, such as the IBM + Spruce boards, this is not the case. If you answer Y here, you can fill + in the desired baud rate to use at console (eg 9600). + + If unsure, say N. + Support for PowerMac serial ports CONFIG_MAC_SERIAL If you have Macintosh style serial ports (8 pin mini-DIN), say Y @@ -16697,11 +16706,24 @@ CONFIG_ALL_PPC Linux currently supports several different kinds of PowerPC-based machines: Apple Power Macintoshes and clones (such as the Motorola - Starmax series), PReP (PowerPC Reference Platform) machines such as - the Motorola PowerStack, CHRP (Common Hardware Reference Platform), - the embedded MBX boards from Motorola and many others. Currently, - the default option is to build a kernel which works on the first - three. Support for other machines is currently incomplete. + Starmax series), PReP (PowerPC Reference Platform) machines (such + as the Motorola PowerStacks, Motorola cPCI/VME embedded systems, + and some IBM RS/6000 systems), CHRP (Common Hardware Reference + Platform), and several embedded PowerPC systems containing 4xx, 6xx, + 7xx, 8xx, 74xx, and 82xx processors. Currently, the default option + is to build a kernel which works on the first three. + +MVME5100 configured with an IPMC761 +CONFIG_MVME5100_IPMC761_PRESENT + The MVME5100 supports a special IPMC761 PMC module in PMC site 1. + This option enables the use of the onboard i8259 PIC and ISA I/O + to support the legacy peripherals on the module. + +Carrier Type +CONFIG_PRPMC_BASE + The PrPMC750 PPMC module is only a complete system if placed in + an appropriate PPMC carrier. This option selects one of two + COTS carriers offered for PPMCs. Power management support for PowerBooks CONFIG_PMAC_PBOOK diff -Nru a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX --- a/Documentation/powerpc/00-INDEX Sat Jun 16 06:00:20 2001 +++ b/Documentation/powerpc/00-INDEX Sat Jun 16 06:00:20 2001 @@ -7,11 +7,16 @@ - this file ppc_htab.txt - info about the Linux/PPC /proc/ppc_htab entry +host_bridge.txt + - info on common support of some common embedded host bridges smp.txt - use and state info about Linux/PPC on MP machines SBC8260_memory_mapping.txt - EST SBC8260 board info sound.txt - info on sound support under Linux/PPC +todc.txt + - documentation for common support of mk48txx and mc146818 family of + realtime clocks zImage_layout.txt - info on the kernel images for Linux/PPC diff -Nru a/Documentation/powerpc/host_bridge.txt b/Documentation/powerpc/host_bridge.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/powerpc/host_bridge.txt Sat Jun 16 06:00:31 2001 @@ -0,0 +1,52 @@ + Documentation for arch/ppc/kernel/*_common.c + ============================================ + +Author: Mark A. Greer (mgreer@mvista.com) +Date: 3.5.2001 + +Last Change: 3.5.2001 + +To make board ports easier and less error prone, some common host bridge files +have been developed. So far, these files have been developed: + - pplus_common.c + - mpc10x_common.c + +pplus_common.c +-------------- + +The routines in this file are for the Motorola MCG PowerPlus architecture +boards which have a Falcon/Raven or Hawk memory controller/host bridge. + +- 'pplus_init()' completely reconfigures the PCI and MPIC physical mappings + and maps the MPIC registers into virtual memory. +- 'pplus_mpic_init()' simply maps the MPIC registers into virtual memory from + where they are currently mapped in the physical address space. +- 'pplus_get_mem_size()' reads the memory controller's registers to determine + the amount of main memory in the system. This assumes that the firmware has + correctly initialized the memory controller. + +For examples, look at arch/ppc/kernel/mcpn765_*.c and prpmc750_setup.c. + + +mpc10x_common.c +-------------- + +The routines in this file are board using the Motorola SPS MPC106/107/8240 +host bridges (the MPC8240 is a 603e processor core with a MPC170-like host +bridge). + +- 'mpc10x_bridge_init()' allows you to switch memory maps (e.g, switch from MAP + A to MAP B), automatically initializes many variables with the proper values, + moves the EUMB to a reasonable place in physical memory (assuming that + 'ioremap_base' is correct), and maps the EPIC registers into virtual memory. +- 'mpc10x_get_mem_size(()' reads the memory controller's registers to determine + the amount of main memory in the system. This assumes that the firmware has + correctly initialized the memory controller. + +For examples, look at arch/ppc/kernel/sandpoint_*.c and menf1_*.c. + + +Before calling any of the routines listed above, you must ensure that there is +a 1-to-1 BAT mapping for the areas of physical memory that will be accessed. + +If you encounter problems, please email me at mgreer@mvista.com diff -Nru a/Documentation/powerpc/todc.txt b/Documentation/powerpc/todc.txt --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/Documentation/powerpc/todc.txt Sat Jun 16 06:00:30 2001 @@ -0,0 +1,53 @@ + Documentation for arch/ppc/kernel/todc_time.c + ============================================= + +Author: Mark A. Greer (mgreer@mvista.com) +Date: 3.5.2001 + +Last Change: 3.5.2001 + +arch/ppc/kernel/todc_time.c supports the mk48txx and mc146818 family of +Time-of-Day (todc)/RealTime Clocks (rtc). Its intent is to replace most or all +of the *_time.c files in arch/ppc/kernel that have very similar code. + +To hook into the routines of this file, do the following: + +- Add '#include "todc.h"' to your *_setup.c file. +- In your *_init() routine, set the 'todc_info' global to the address of the + 'todc_info_t' structure that matches your RTC chip. +- Set 'todc_info->nvram_as0', 'todc_info->nvram_as1' to the address of the + address strobe registers. If you have an MC146818 RTC on an ISA bus, the + default values should work fine. +- Set 'todc_info->nvram_data' to the address of the RTC data register. If you + have an MC146818 RTC on an ISA bus, the default value should work fine. +- Set 'ppc_md.time_init', 'ppc_md.set_rtc_time', and 'ppc_md.get_rtc_time' to + 'todc_time_init', 'todc_set_rtc_time', and 'todc_get_rtc_time', respectively. +- If you want to use the RTC to calibrate you decrementer, set + 'ppc_md.calibrate_decr' to 'todc_calibrate_decr'. + +There are 3 sets of pre-defined todc access register routines: +- 'todc_direct_read_val' and 'todc_direct_write_val' for direct access + (e.g., mk48txx whose NVRAM & RTC registers are directly mapped into the + physical address space of the processor); +- 'todc_m48txx_read_val' and 'todc_m48txx_write_val' for an mk48txx whose NVRAM + & RTC registers are accessed via address strobe & data registers; +- 'todc_mc146818_read_val' and 'todc_mc146818_write_val' for mc146818 RTC whose + registers are accessed via an address/data registers pair. + +To use one of these sets of access routines, set 'ppc_md.nvram_read_val' and +'ppc_md.nvram_write_val' to the appropriate values for your RTC and board +combination. + +For an example using a mk48txx, look at arch/ppc/kernel/mcpn765_setup.c; +for an example using a mc146818, look at arch/ppc/kernel/sandpoint_setup.c. + +If your board doesn't have a full 8 bits wired to AS0, you can change the +'as0_bits' in the 'todc_info_t' structure. See arch/ppc/kernel/menf1_setup.c +for an example. + +Adding support for other closely related RTC chips should be easy. To do so, +you simply add another 'todc_info_t' structure to the the beginning of +arch/ppc/kernel/todc_time.c and add another TODC_TYPE_xxx in +arch/ppc/kernel/todc.h. + +If you encounter problems, please email me at mgreer@mvista.com diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS Sat Jun 16 06:00:19 2001 +++ b/MAINTAINERS Sat Jun 16 06:00:19 2001 @@ -784,15 +784,23 @@ L: linux-x25@vger.kernel.org S: Maintained +LINUX FOR IBM pSERIES (RS/6000) +P: Paul Mackerras +M: paulus@au.ibm.com +W: http://www.ibm.com/linux/ltc/projects/ppc +S: Supported + LINUX FOR POWERPC P: Cort Dougan M: cort@fsmlabs.com +P: Paul Mackerras +M: paulus@samba.org W: http://www.fsmlabs.com/linuxppcbk.html -S: Maintained +S: Supported LINUX FOR POWER MACINTOSH -P: Paul Mackerras -M: paulus@samba.org +P: Benjamin Herrenschmidt +M: benh@kernel.crashing.org W: http://www.linuxppc.org/ L: linuxppc-dev@lists.linuxppc.org S: Maintained diff -Nru a/Makefile b/Makefile --- a/Makefile Sat Jun 16 06:00:20 2001 +++ b/Makefile Sat Jun 16 06:00:20 2001 @@ -162,7 +162,7 @@ DRIVERS-$(CONFIG_SBUS) += drivers/sbus/sbus_all.o DRIVERS-$(CONFIG_ZORRO) += drivers/zorro/driver.o DRIVERS-$(CONFIG_FC4) += drivers/fc4/fc4.a -DRIVERS-$(CONFIG_ALL_PPC) += drivers/macintosh/macintosh.o +DRIVERS-$(CONFIG_PPC) += drivers/macintosh/macintosh.o DRIVERS-$(CONFIG_MAC) += drivers/macintosh/macintosh.o DRIVERS-$(CONFIG_ISAPNP) += drivers/pnp/pnp.o DRIVERS-$(CONFIG_SGI_IP22) += drivers/sgi/sgi.a diff -Nru a/arch/ppc/8260_io/Makefile b/arch/ppc/8260_io/Makefile --- a/arch/ppc/8260_io/Makefile Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/8260_io/Makefile Sat Jun 16 06:00:22 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:19 cort +# BK Id: %F% %I% %G% %U% %#% # # # Makefile for the linux MPC8xx ppc-specific parts of comm processor diff -Nru a/arch/ppc/8260_io/commproc.c b/arch/ppc/8260_io/commproc.c --- a/arch/ppc/8260_io/commproc.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/8260_io/commproc.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.commproc.c 1.5 05/17/01 18:14:19 cort + * BK Id: %F% %I% %G% %U% %#% */ /* diff -Nru a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c --- a/arch/ppc/8260_io/enet.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/8260_io/enet.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.enet.c 1.6 05/17/01 18:14:19 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Ethernet driver for Motorola MPC8260. diff -Nru a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c --- a/arch/ppc/8260_io/fcc_enet.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/8260_io/fcc_enet.c Sat Jun 16 06:00:24 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fcc_enet.c 1.7 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Fast Ethernet Controller (FCC) driver for Motorola MPC8260. diff -Nru a/arch/ppc/8260_io/uart.c b/arch/ppc/8260_io/uart.c --- a/arch/ppc/8260_io/uart.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/8260_io/uart.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.uart.c 1.6 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * UART driver for MPC8260 CPM SCC or SMC diff -Nru a/arch/ppc/8xx_io/Makefile b/arch/ppc/8xx_io/Makefile --- a/arch/ppc/8xx_io/Makefile Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/8xx_io/Makefile Sat Jun 16 06:00:19 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:20 cort +# BK Id: %F% %I% %G% %U% %#% # # # Makefile for the linux MPC8xx ppc-specific parts of comm processor diff -Nru a/arch/ppc/8xx_io/commproc.c b/arch/ppc/8xx_io/commproc.c --- a/arch/ppc/8xx_io/commproc.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/8xx_io/commproc.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.commproc.c 1.8 05/18/01 07:54:04 patch + * BK Id: %F% %I% %G% %U% %#% */ /* @@ -47,12 +47,12 @@ /* CPM interrupt vector functions. */ struct cpm_action { - void (*handler)(void *); + void (*handler)(void *, struct pt_regs * regs); void *dev_id; }; static struct cpm_action cpm_vecs[CPMVEC_NR]; static void cpm_interrupt(int irq, void * dev, struct pt_regs * regs); -static void cpm_error_interrupt(void *); +static void cpm_error_interrupt(void *, struct pt_regs * regs); void m8xx_cpm_reset(uint host_page_addr) @@ -129,7 +129,7 @@ vec >>= 11; if (cpm_vecs[vec].handler != 0) - (*cpm_vecs[vec].handler)(cpm_vecs[vec].dev_id); + (*cpm_vecs[vec].handler)(cpm_vecs[vec].dev_id, regs); else ((immap_t *)IMAP_ADDR)->im_cpic.cpic_cimr &= ~(1 << vec); @@ -146,14 +146,15 @@ * tests in the interrupt handler. */ static void -cpm_error_interrupt(void *dev) +cpm_error_interrupt(void *dev, struct pt_regs *regs) { } /* Install a CPM interrupt handler. */ void -cpm_install_handler(int vec, void (*handler)(void *), void *dev_id) +cpm_install_handler(int vec, void (*handler)(void *, struct pt_regs *regs), + void *dev_id) { /* If null handler, assume we are trying to free the IRQ. diff -Nru a/arch/ppc/8xx_io/commproc.h b/arch/ppc/8xx_io/commproc.h --- a/arch/ppc/8xx_io/commproc.h Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/8xx_io/commproc.h Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.commproc.h 1.8 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ /* @@ -789,7 +789,8 @@ #define CICR_IEN ((uint)0x00000080) /* Int. enable */ #define CICR_SPS ((uint)0x00000001) /* SCC Spread */ -extern void cpm_install_handler(int vec, void (*handler)(void *), void *dev_id); +extern void cpm_install_handler(int vec, + void (*handler)(void *, struct pt_regs *regs), void *dev_id); extern void cpm_free_handler(int vec); #endif /* __CPM_8XX__ */ diff -Nru a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c --- a/arch/ppc/8xx_io/enet.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/8xx_io/enet.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.enet.c 1.10 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Ethernet driver for Motorola MPC8xx. diff -Nru a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c --- a/arch/ppc/8xx_io/fec.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/8xx_io/fec.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fec.c 1.12 05/18/01 07:54:04 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. diff -Nru a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c --- a/arch/ppc/8xx_io/uart.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/8xx_io/uart.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.uart.c 1.10 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * UART driver for MPC860 CPM SCC or SMC @@ -44,6 +44,9 @@ #include #include #include "commproc.h" +#ifdef CONFIG_MAGIC_SYSRQ +#include +#endif #ifdef CONFIG_KGDB extern void breakpoint(void); @@ -91,6 +94,15 @@ static int serial_refcount; static int serial_console_setup(struct console *co, char *options); +static int serial_console_wait_key(struct console *co); +static void serial_console_write(struct console *c, const char *s, + unsigned count); +static kdev_t serial_console_device(struct console *c); + +#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) +static unsigned long break_pressed; /* break, really ... */ +#endif + /* * Serial driver configuration section. Here are the various options: */ @@ -202,6 +214,16 @@ cbd_t *tx_cur; } ser_info_t; +static struct console sercons = { + name: "ttyS", + write: serial_console_write, + device: serial_console_device, + wait_key: serial_console_wait_key, + setup: serial_console_setup, + flags: CON_PRINTBUFFER, + index: CONFIG_SERIAL_CONSOLE_PORT, +}; + static void change_speed(ser_info_t *info); static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout); @@ -325,7 +347,7 @@ mark_bh(SERIAL_BH); } -static _INLINE_ void receive_chars(ser_info_t *info) +static _INLINE_ void receive_chars(ser_info_t *info, struct pt_regs *regs) { struct tty_struct *tty = info->tty; unsigned char ch, *cp; @@ -413,7 +435,7 @@ } */ status &= info->read_status_mask; - + if (status & (BD_SC_BR)) { #ifdef SERIAL_DEBUG_INTR printk("handling break...."); @@ -440,6 +462,17 @@ } } } +#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (break_pressed && info->line == sercons.index) { + if (ch != 0 && time_before(jiffies, + break_pressed + HZ*5)) { + handle_sysrq(ch, regs, NULL, NULL); + break_pressed = 0; + goto ignore_char; + } else + break_pressed = 0; + } +#endif if (tty->flip.count >= TTY_FLIPBUF_SIZE) break; @@ -448,6 +481,7 @@ tty->flip.count++; } + ignore_char: /* This BD is ready to be used again. Clear status. * Get next BD. */ @@ -459,17 +493,27 @@ else bdp++; } - info->rx_cur = (cbd_t *)bdp; queue_task(&tty->flip.tqueue, &tq_timer); } -static _INLINE_ void receive_break(ser_info_t *info) +static _INLINE_ void receive_break(ser_info_t *info, struct pt_regs *regs) { struct tty_struct *tty = info->tty; info->state->icount.brk++; + +#if defined(CONFIG_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) + if (info->line == sercons.index) { + if (!break_pressed) { + break_pressed = jiffies; + return; + } else + break_pressed = 0; + } +#endif + /* Check to see if there is room in the tty buffer for * the break. If not, we exit now, losing the break. FIXME */ @@ -482,7 +526,7 @@ queue_task(&tty->flip.tqueue, &tq_timer); } -static _INLINE_ void transmit_chars(ser_info_t *info) +static _INLINE_ void transmit_chars(ser_info_t *info, struct pt_regs *regs) { if ((info->flags & TX_WAKEUP) || @@ -571,7 +615,7 @@ /* * This is the serial driver's interrupt routine for a single port */ -static void rs_8xx_interrupt(void *dev_id) +static void rs_8xx_interrupt(void *dev_id, struct pt_regs *regs) { u_char events; int idx; @@ -585,21 +629,23 @@ if (info->state->smc_scc_num & NUM_IS_SCC) { sccp = &cpmp->cp_scc[idx]; events = sccp->scc_scce; + if (events & SMCM_BRKE) + receive_break(info, regs); if (events & SCCM_RX) - receive_chars(info); + receive_chars(info, regs); if (events & SCCM_TX) - transmit_chars(info); + transmit_chars(info, regs); sccp->scc_scce = events; } else { smcp = &cpmp->cp_smc[idx]; events = smcp->smc_smce; if (events & SMCM_BRKE) - receive_break(info); + receive_break(info, regs); if (events & SMCM_RX) - receive_chars(info); + receive_chars(info, regs); if (events & SMCM_TX) - transmit_chars(info); + transmit_chars(info, regs); smcp->smc_smce = events; } @@ -2427,17 +2473,6 @@ { return MKDEV(TTY_MAJOR, 64 + c->index); } - - -static struct console sercons = { - name: "ttyS", - write: serial_console_write, - device: serial_console_device, - wait_key: serial_console_wait_key, - setup: serial_console_setup, - flags: CON_PRINTBUFFER, - index: CONFIG_SERIAL_CONSOLE_PORT, -}; /* * Register console. diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile --- a/arch/ppc/Makefile Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/Makefile Sat Jun 16 06:00:25 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.13 05/21/01 00:48:24 cort +# BK Id: %F% %I% %G% %U% %#% # # This file is included by the global makefile so that you can add your own # architecture-specific flags and dependencies. Remember to do have actions @@ -91,6 +91,10 @@ $(BOOT_TARGETS): $(CHECKS) vmlinux @$(MAKEBOOT) $@ + +.PHONY: clean_config +clean_config: + rm -f .config arch/ppc/defconfig %_config: arch/ppc/configs/%_defconfig rm -f .config arch/ppc/defconfig diff -Nru a/arch/ppc/amiga/Makefile b/arch/ppc/amiga/Makefile --- a/arch/ppc/amiga/Makefile Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/amiga/Makefile Sat Jun 16 06:00:16 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.5 05/21/01 00:48:24 cort +# BK Id: %F% %I% %G% %U% %#% # # # Makefile for Linux arch/m68k/amiga source directory diff -Nru a/arch/ppc/amiga/amiga_ksyms.c b/arch/ppc/amiga/amiga_ksyms.c --- a/arch/ppc/amiga/amiga_ksyms.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/amiga/amiga_ksyms.c Sat Jun 16 06:00:18 2001 @@ -1,4 +1,4 @@ /* - * BK Id: SCCS/s.amiga_ksyms.c 1.5 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ #include "../../m68k/amiga/amiga_ksyms.c" diff -Nru a/arch/ppc/amiga/amiints.c b/arch/ppc/amiga/amiints.c --- a/arch/ppc/amiga/amiints.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/amiga/amiints.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.amiints.c 1.8 05/21/01 00:48:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code diff -Nru a/arch/ppc/amiga/amisound.c b/arch/ppc/amiga/amisound.c --- a/arch/ppc/amiga/amisound.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/amiga/amisound.c Sat Jun 16 06:00:24 2001 @@ -1,4 +1,4 @@ /* - * BK Id: SCCS/s.amisound.c 1.5 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ #include "../../m68k/amiga/amisound.c" diff -Nru a/arch/ppc/amiga/bootinfo.c b/arch/ppc/amiga/bootinfo.c --- a/arch/ppc/amiga/bootinfo.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/amiga/bootinfo.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.bootinfo.c 1.5 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/amiga/bootinfo.c diff -Nru a/arch/ppc/amiga/chipram.c b/arch/ppc/amiga/chipram.c --- a/arch/ppc/amiga/chipram.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/amiga/chipram.c Sat Jun 16 06:00:18 2001 @@ -1,4 +1,4 @@ /* - * BK Id: SCCS/s.chipram.c 1.7 05/21/01 00:49:49 cort + * BK Id: %F% %I% %G% %U% %#% */ #include "../../m68k/amiga/chipram.c" diff -Nru a/arch/ppc/amiga/cia.c b/arch/ppc/amiga/cia.c --- a/arch/ppc/amiga/cia.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/amiga/cia.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.cia.c 1.7 05/21/01 00:48:24 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/m68k/amiga/cia.c - CIA support diff -Nru a/arch/ppc/amiga/config.c b/arch/ppc/amiga/config.c --- a/arch/ppc/amiga/config.c Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/amiga/config.c Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.config.c 1.7 05/21/01 00:48:24 cort + * BK Id: %F% %I% %G% %U% %#% */ #define m68k_debug_device debug_device diff -Nru a/arch/ppc/amiga/ints.c b/arch/ppc/amiga/ints.c --- a/arch/ppc/amiga/ints.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/amiga/ints.c Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ints.c 1.5 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/amiga/ints.c diff -Nru a/arch/ppc/amiga/pcmcia.c b/arch/ppc/amiga/pcmcia.c --- a/arch/ppc/amiga/pcmcia.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/amiga/pcmcia.c Sat Jun 16 06:00:20 2001 @@ -1,4 +1,4 @@ /* - * BK Id: SCCS/s.pcmcia.c 1.5 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ #include "../../m68k/amiga/pcmcia.c" diff -Nru a/arch/ppc/amiga/time.c b/arch/ppc/amiga/time.c --- a/arch/ppc/amiga/time.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/amiga/time.c Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.time.c 1.5 05/17/01 18:14:20 cort + * BK Id: %F% %I% %G% %U% %#% */ #include /* CONFIG_HEARTBEAT */ #include diff -Nru a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile --- a/arch/ppc/boot/Makefile Sat Jun 16 06:00:28 2001 +++ b/arch/ppc/boot/Makefile Sat Jun 16 06:00:31 2001 @@ -62,6 +62,30 @@ ifdef CONFIG_4xx $(MAKE) -C tree $@ endif +ifdef CONFIG_K2 + $(MAKE) -C utils mkpmon + $(MAKE) -C pmon $@ +endif +ifdef CONFIG_MENF1 + $(MAKE) -C utils mkprep + $(MAKE) -C menf1 $@ +endif +ifneq ("xx$(CONFIG_MVME5100)$(CONFIG_PRPMC750)$(CONFIG_MCPN765)","xx") + $(MAKE) -C utils mkbugboot mkprep + $(MAKE) -C pp3 $@ +endif +ifdef CONFIG_PCORE + $(MAKE) -C pcore $@ +endif +ifdef CONFIG_SANDPOINT + $(MAKE) -C sandpoint $@ +endif +ifdef CONFIG_SPRUCE + $(MAKE) -C spruce $@ +endif +ifdef CONFIG_ZX4500 + $(MAKE) -C zx4500 $@ +endif sImage: $(TOPDIR)/vmlinux ifdef CONFIG_GEMINI @@ -82,15 +106,24 @@ # Do the dirs clean: $(MAKE) -C images clean + $(MAKE) -C spruce clean $(MAKE) -C tree clean $(MAKE) -C utils clean dep: - $(MAKE) -C mbx fastdep $(MAKE) -C chrp fastdep $(MAKE) -C common fastdep + $(MAKE) -C lib fastdep + $(MAKE) -C mbx fastdep + $(MAKE) -C menf1 fastdep + $(MAKE) -C pcore fastdep $(MAKE) -C pmac fastdep + $(MAKE) -C pmon fastdep + $(MAKE) -C pp3 fastdep $(MAKE) -C prep fastdep - $(MAKE) -C common fastdep + $(MAKE) -C sandpoint fastdep + $(MAKE) -C spruce fastdep + $(MAKE) -C tree fastdep + $(MAKE) -C zx4500 fastdep include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/chrp/Makefile b/arch/ppc/boot/chrp/Makefile --- a/arch/ppc/boot/chrp/Makefile Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/boot/chrp/Makefile Sat Jun 16 06:00:24 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.8 05/18/01 06:20:29 patch +# BK Id: %F% %I% %G% %U% %#% # # Makefile for making ELF bootable images for booting on CHRP # using Open Firmware. diff -Nru a/arch/ppc/boot/chrp/main.c b/arch/ppc/boot/chrp/main.c --- a/arch/ppc/boot/chrp/main.c Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/boot/chrp/main.c Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.main.c 1.7 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Paul Mackerras 1997. @@ -100,13 +100,13 @@ rec->tag = BI_MACHTYPE; rec->data[0] = _MACH_chrp; rec->data[1] = 1; - rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); rec = (struct bi_record *)((unsigned long)rec + rec->size); #if 0 rec->tag = BI_SYSMAP; rec->data[0] = (unsigned long)sysmap_data; rec->data[1] = sysmap_len; - rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); rec = (struct bi_record *)((unsigned long)rec + rec->size); #endif rec->tag = BI_LAST; diff -Nru a/arch/ppc/boot/chrp/misc.S b/arch/ppc/boot/chrp/misc.S --- a/arch/ppc/boot/chrp/misc.S Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/boot/chrp/misc.S Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.misc.S 1.6 05/18/01 15:16:59 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Paul Mackerras 1997. diff -Nru a/arch/ppc/boot/chrp/start.c b/arch/ppc/boot/chrp/start.c --- a/arch/ppc/boot/chrp/start.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/boot/chrp/start.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.start.c 1.6 05/18/01 15:16:59 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Paul Mackerras 1997. diff -Nru a/arch/ppc/boot/common/crt0.S b/arch/ppc/boot/common/crt0.S --- a/arch/ppc/boot/common/crt0.S Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/boot/common/crt0.S Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.crt0.S 1.10 05/21/01 00:49:49 cort + * BK Id: %F% %I% %G% %U% %#% */ /* Copyright (c) 1997 Paul Mackerras * Initial Power Macintosh COFF version. diff -Nru a/arch/ppc/boot/common/misc-common.c b/arch/ppc/boot/common/misc-common.c --- a/arch/ppc/boot/common/misc-common.c Sat Jun 16 06:00:28 2001 +++ b/arch/ppc/boot/common/misc-common.c Sat Jun 16 06:00:32 2001 @@ -38,7 +38,7 @@ /* If we're on a ALL_PPC, assume we have a keyboard controller * Also note, if we're not ALL_PPC, we assume you are a serial * console - Tom */ -#ifdef CONFIG_ALL_PPC +#if defined(CONFIG_ALL_PPC) && defined(CONFIG_VGA_CONSOLE) extern void cursor(int x, int y); extern void scroll(void); extern char *vidmem; diff -Nru a/arch/ppc/boot/common/no_initrd.c b/arch/ppc/boot/common/no_initrd.c --- a/arch/ppc/boot/common/no_initrd.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/boot/common/no_initrd.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.no_initrd.c 1.7 05/18/01 15:17:23 cort + * BK Id: %F% %I% %G% %U% %#% */ char initrd_data[1]; int initrd_len = 0; diff -Nru a/arch/ppc/boot/common/ns16550.c b/arch/ppc/boot/common/ns16550.c --- a/arch/ppc/boot/common/ns16550.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/boot/common/ns16550.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ns16550.c 1.7 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * COM1 NS16550 support diff -Nru a/arch/ppc/boot/common/string.S b/arch/ppc/boot/common/string.S --- a/arch/ppc/boot/common/string.S Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/boot/common/string.S Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.string.S 1.8 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * String handling functions for PowerPC. diff -Nru a/arch/ppc/boot/iSeries/addRamDisk.c b/arch/ppc/boot/iSeries/addRamDisk.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/iSeries/addRamDisk.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#include +#include +#include + +#define ElfHeaderSize (64 * 1024) +#define ElfPages (ElfHeaderSize / 4096) +#define KERNELBASE (0xc0000000) + +void get4k(FILE *file, char *buf ) +{ + unsigned j; + unsigned num = fread(buf, 1, 4096, file); + for ( j=num; j<4096; ++j ) + buf[j] = 0; +} + +void put4k(FILE *file, char *buf ) +{ + fwrite(buf, 1, 4096, file); +} + +void death(const char *msg, FILE *fdesc, const char *fname) +{ + printf(msg); + fclose(fdesc); + unlink(fname); + exit(1); +} + +int main(int argc, char **argv) +{ + char inbuf[4096]; + FILE *ramDisk = NULL; + FILE *inputVmlinux = NULL; + FILE *outputVmlinux = NULL; + unsigned i = 0; + u_int32_t ramFileLen = 0; + u_int32_t ramLen = 0; + u_int32_t roundR = 0; + u_int32_t kernelLen = 0; + u_int32_t actualKernelLen = 0; + u_int32_t round = 0; + u_int32_t roundedKernelLen = 0; + u_int32_t ramStartOffs = 0; + u_int32_t ramPages = 0; + u_int32_t roundedKernelPages = 0; + u_int32_t hvReleaseData = 0; + u_int32_t eyeCatcher = 0xc8a5d9c4; + u_int32_t naca = 0; + u_int32_t xRamDisk = 0; + u_int32_t xRamDiskSize = 0; + if ( argc < 2 ) { + printf("Name of RAM disk file missing.\n"); + exit(1); + } + + if ( argc < 3 ) { + printf("Name of vmlinux file missing.\n"); + exit(1); + } + + if ( argc < 4 ) { + printf("Name of vmlinux output file missing.\n"); + exit(1); + } + + ramDisk = fopen(argv[1], "r"); + if ( ! ramDisk ) { + printf("RAM disk file \"%s\" failed to open.\n", argv[1]); + exit(1); + } + inputVmlinux = fopen(argv[2], "r"); + if ( ! inputVmlinux ) { + printf("vmlinux file \"%s\" failed to open.\n", argv[2]); + exit(1); + } + outputVmlinux = fopen(argv[3], "w+"); + if ( ! outputVmlinux ) { + printf("output vmlinux file \"%s\" failed to open.\n", argv[3]); + exit(1); + } + fseek(ramDisk, 0, SEEK_END); + ramFileLen = ftell(ramDisk); + fseek(ramDisk, 0, SEEK_SET); + printf("%s file size = %d\n", argv[1], ramFileLen); + + ramLen = ramFileLen; + + roundR = 4096 - (ramLen % 4096); + if ( roundR ) { + printf("Rounding RAM disk file up to a multiple of 4096, adding %d\n", roundR); + ramLen += roundR; + } + + printf("Rounded RAM disk size is %d\n", ramLen); + fseek(inputVmlinux, 0, SEEK_END); + kernelLen = ftell(inputVmlinux); + fseek(inputVmlinux, 0, SEEK_SET); + printf("kernel file size = %d\n", kernelLen); + if ( kernelLen == 0 ) { + printf("You must have a linux kernel specified as argv[2]\n"); + exit(1); + } + + actualKernelLen = kernelLen - ElfHeaderSize; + + printf("actual kernel length (minus ELF header) = %d\n", actualKernelLen); + + round = actualKernelLen % 4096; + roundedKernelLen = actualKernelLen; + if ( round ) + roundedKernelLen += (4096 - round); + + printf("actual kernel length rounded up to a 4k multiple = %d\n", roundedKernelLen); + + ramStartOffs = roundedKernelLen; + ramPages = ramLen / 4096; + + printf("RAM disk pages to copy = %d\n", ramPages); + + // Copy 64K ELF header + for (i=0; i<(ElfPages); ++i) { + get4k( inputVmlinux, inbuf ); + put4k( outputVmlinux, inbuf ); + } + + roundedKernelPages = roundedKernelLen / 4096; + + fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); + + for ( i=0; i +#include +#include +#include +#include + +void xlate( char * inb, char * trb, unsigned len ) +{ + unsigned i; + for ( i=0; i> 4; + char c2 = c & 0xf; + if ( c1 > 9 ) + c1 = c1 + 'A' - 10; + else + c1 = c1 + '0'; + if ( c2 > 9 ) + c2 = c2 + 'A' - 10; + else + c2 = c2 + '0'; + *trb++ = c1; + *trb++ = c2; + } + *trb = 0; +} + +#define ElfHeaderSize (64 * 1024) +#define ElfPages (ElfHeaderSize / 4096) +#define KERNELBASE (0xc0000000) + +void get4k( /*istream *inf*/FILE *file, char *buf ) +{ + unsigned j; + unsigned num = fread(buf, 1, 4096, file); + for ( j=num; j<4096; ++j ) + buf[j] = 0; +} + +void put4k( /*ostream *outf*/FILE *file, char *buf ) +{ + fwrite(buf, 1, 4096, file); +} + +int main(int argc, char **argv) +{ + char inbuf[4096]; + FILE *ramDisk = NULL; + FILE *inputVmlinux = NULL; + FILE *outputVmlinux = NULL; + unsigned i = 0; + unsigned long ramFileLen = 0; + unsigned long ramLen = 0; + unsigned long roundR = 0; + unsigned long kernelLen = 0; + unsigned long actualKernelLen = 0; + unsigned long round = 0; + unsigned long roundedKernelLen = 0; + unsigned long ramStartOffs = 0; + unsigned long ramPages = 0; + unsigned long roundedKernelPages = 0; + if ( argc < 2 ) { + printf("Name of System Map file missing.\n"); + exit(1); + } + + if ( argc < 3 ) { + printf("Name of vmlinux file missing.\n"); + exit(1); + } + + if ( argc < 4 ) { + printf("Name of vmlinux output file missing.\n"); + exit(1); + } + + ramDisk = fopen(argv[1], "r"); + if ( ! ramDisk ) { + printf("System Map file \"%s\" failed to open.\n", argv[1]); + exit(1); + } + inputVmlinux = fopen(argv[2], "r"); + if ( ! inputVmlinux ) { + printf("vmlinux file \"%s\" failed to open.\n", argv[2]); + exit(1); + } + outputVmlinux = fopen(argv[3], "w"); + if ( ! outputVmlinux ) { + printf("output vmlinux file \"%s\" failed to open.\n", argv[3]); + exit(1); + } + fseek(ramDisk, 0, SEEK_END); + ramFileLen = ftell(ramDisk); + fseek(ramDisk, 0, SEEK_SET); + printf("%s file size = %ld\n", argv[1], ramFileLen); + + ramLen = ramFileLen; + + roundR = 4096 - (ramLen % 4096); + if ( roundR ) { + printf("Rounding System Map file up to a multiple of 4096, adding %ld\n", roundR); + ramLen += roundR; + } + + printf("Rounded System Map size is %ld\n", ramLen); + fseek(inputVmlinux, 0, SEEK_END); + kernelLen = ftell(inputVmlinux); + fseek(inputVmlinux, 0, SEEK_SET); + printf("kernel file size = %ld\n", kernelLen); + if ( kernelLen == 0 ) { + printf("You must have a linux kernel specified as argv[2]\n"); + exit(1); + } + + actualKernelLen = kernelLen - ElfHeaderSize; + + printf("actual kernel length (minus ELF header) = %ld\n", actualKernelLen); + + round = actualKernelLen % 4096; + roundedKernelLen = actualKernelLen; + if ( round ) + roundedKernelLen += (4096 - round); + + printf("actual kernel length rounded up to a 4k multiple = %ld\n", roundedKernelLen); + + ramStartOffs = roundedKernelLen; + ramPages = ramLen / 4096; + + printf("System map pages to copy = %ld\n", ramPages); + + // Copy 64K ELF header + for (i=0; i<(ElfPages); ++i) { + get4k( inputVmlinux, inbuf ); + put4k( outputVmlinux, inbuf ); + } + + + + roundedKernelPages = roundedKernelLen / 4096; + + fseek(inputVmlinux, ElfHeaderSize, SEEK_SET); + + { + for ( i=0; i #include "../../kernel/ppc_defs.h" diff -Nru a/arch/ppc/boot/mbx/head_8260.S b/arch/ppc/boot/mbx/head_8260.S --- a/arch/ppc/boot/mbx/head_8260.S Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/boot/mbx/head_8260.S Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.head_8260.S 1.8 05/18/01 07:54:04 patch + * BK Id: %F% %I% %G% %U% %#% */ #include "../../kernel/ppc_defs.h" #include "../../kernel/ppc_asm.tmpl" diff -Nru a/arch/ppc/boot/mbx/iic.c b/arch/ppc/boot/mbx/iic.c --- a/arch/ppc/boot/mbx/iic.c Sat Jun 16 06:00:28 2001 +++ b/arch/ppc/boot/mbx/iic.c Sat Jun 16 06:00:28 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.iic.c 1.8 05/18/01 07:54:04 patch + * BK Id: %F% %I% %G% %U% %#% */ /* Minimal support functions to read configuration from IIC EEPROMS diff -Nru a/arch/ppc/boot/mbx/m8260_tty.c b/arch/ppc/boot/mbx/m8260_tty.c --- a/arch/ppc/boot/mbx/m8260_tty.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/boot/mbx/m8260_tty.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.m8260_tty.c 1.7 05/18/01 07:54:04 patch + * BK Id: %F% %I% %G% %U% %#% */ diff -Nru a/arch/ppc/boot/mbx/m8xx_tty.c b/arch/ppc/boot/mbx/m8xx_tty.c --- a/arch/ppc/boot/mbx/m8xx_tty.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/boot/mbx/m8xx_tty.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.m8xx_tty.c 1.8 05/18/01 07:54:04 patch + * BK Id: %F% %I% %G% %U% %#% */ diff -Nru a/arch/ppc/boot/mbx/misc.c b/arch/ppc/boot/mbx/misc.c --- a/arch/ppc/boot/mbx/misc.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/boot/mbx/misc.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.misc.c 1.9 05/18/01 07:54:04 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * Adapted for PowerPC by Gary Thomas diff -Nru a/arch/ppc/boot/mbx/pci.c b/arch/ppc/boot/mbx/pci.c --- a/arch/ppc/boot/mbx/pci.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/boot/mbx/pci.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pci.c 1.6 05/18/01 15:17:06 cort + * BK Id: %F% %I% %G% %U% %#% */ /* Stand alone funtions for QSpan Tundra support. */ diff -Nru a/arch/ppc/boot/mbx/qspan_pci.c b/arch/ppc/boot/mbx/qspan_pci.c --- a/arch/ppc/boot/mbx/qspan_pci.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/boot/mbx/qspan_pci.c Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.qspan_pci.c 1.6 05/18/01 15:17:06 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * LinuxPPC arch/ppc/kernel/qspan_pci.c Dan Malek (dmalek@jlc.net) diff -Nru a/arch/ppc/boot/mbx/rdimage.c b/arch/ppc/boot/mbx/rdimage.c --- a/arch/ppc/boot/mbx/rdimage.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/boot/mbx/rdimage.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.rdimage.c 1.6 05/18/01 15:17:06 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * rdimage.c diff -Nru a/arch/ppc/boot/menf1/Makefile b/arch/ppc/boot/menf1/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/menf1/Makefile Sat Jun 16 06:00:30 2001 @@ -0,0 +1,93 @@ +# arch/ppc/boot/menf1/Makefile +# +# Makefile for MEN F1 bootloader +# +# Author: Matt Porter +# +# Copyright 2001 MontaVista Software Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. + +.c.s: + $(CC) $(CFLAGS) -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) -c -o $*.o $< +.S.s: + $(CPP) $(AFLAGS) -traditional -o $*.o $< +.S.o: + $(CC) $(AFLAGS) -traditional -c -o $*.o $< + +ZLINKFLAGS = -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00800000 + +OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o ns16550.o \ + ../common/string.o +OBJCOPY_ARGS = -O elf32-powerpc +LIBS := ../lib/zlib.a + +OFFSET := ../utils/offset +SIZE := ../utils/size +MKPREP := ../utils/mkprep + +all: zImage + +../common/misc-simple.o: ../common/misc-simple.c + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ + -DZIMAGE_SIZE=0 -c -o $@ $*.c + +ns16550.o: ../common/ns16550.c + $(CC) $(CFLAGS) -DIOOFFSET=0x80000000 -c -o $@ ../common/$*.c + +zvmlinux.initrd: $(OBJECTS) $(LIBS) ../images/vmlinux.gz + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ initrd` \ + -DINITRD_SIZE=`sh $(SIZE) $(OBJDUMP) $@ initrd` \ + -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ + -c -o ../common/misc-simple.o ../common/misc-simple.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +zImage: zvmlinux + $(MKPREP) -pbp zvmlinux ../images/$@.menf1 + rm -f zvmlinux + +zImage.initrd: zvmlinux.initrd + $(MKPREP) -pbp zvmlinux.initrd ../images/$@.menf1 + rm -f zvmlinux.initrd + +zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz +# +# build the boot loader image and then compute the offset into it +# for the kernel image +# + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ +# +# then with the offset rebuild the bootloader so we know where the kernel is +# + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ + -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ + -c -o ../common/misc-simple.o ../common/misc-simple.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/menf1/head.S b/arch/ppc/boot/menf1/head.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/menf1/head.S Sat Jun 16 06:00:31 2001 @@ -0,0 +1,315 @@ +/* + * arch/ppc/boot/menf1/head.S + * + * Initial board bringup code for MEN F1 boards + * + * Author: Matt Porter + * Derived from arch/ppc/boot/prep/head.S + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include "../../kernel/ppc_defs.h" +#include "../../kernel/ppc_asm.tmpl" +#include +#include + + .text + +/* + * + * Begin at some arbitrary location in RAM or Flash + * Initialize core registers + * Configure memory controller (Not executing from RAM) + * Move the boot code to the link address (8M) + * Setup C stack + * Initialize UART + * Decompress the kernel to 0x0 + * Jump to the kernel entry + * + */ + + .globl start +start: + bl start_ + +start_: +/* + * Configure core registers + */ + + /* Establish default MSR value, exception prefix 0xFFF */ + li r3,MSR_IP|MSR_FP + mtmsr r3 + + /* Clear BATS */ + li r8,0 + mtspr DBAT0U,r8 + mtspr DBAT0L,r8 + mtspr DBAT1U,r8 + mtspr DBAT1L,r8 + mtspr DBAT2U,r8 + mtspr DBAT2L,r8 + mtspr DBAT3U,r8 + mtspr DBAT3L,r8 + mtspr IBAT0U,r8 + mtspr IBAT0L,r8 + mtspr IBAT1U,r8 + mtspr IBAT1L,r8 + mtspr IBAT2U,r8 + mtspr IBAT2L,r8 + mtspr IBAT3U,r8 + mtspr IBAT3L,r8 + isync + sync + sync + + /* Set segment registers */ + lis r8, 0x8000 + isync + mtsr SR0,r8 + mtsr SR1,r8 + mtsr SR2,r8 + mtsr SR3,r8 + mtsr SR4,r8 + mtsr SR5,r8 + mtsr SR6,r8 + mtsr SR7,r8 + mtsr SR8,r8 + mtsr SR9,r8 + mtsr SR10,r8 + mtsr SR11,r8 + mtsr SR12,r8 + mtsr SR13,r8 + mtsr SR14,r8 + mtsr SR15,r8 + isync + sync + sync + + /* Disable L1 icache/dcache */ + li r4,0x0000 + isync + mtspr HID0,r4 + sync + isync + + /* Flash Invalidate L1 icache/dcache */ + ori r4,r4,0x8000 + ori r8,r4,0x0800 + isync + mtspr HID0,r8 + sync + isync + + /* Older cores need to manually clear ICFI bit */ + mtspr HID0,r4 + sync + isync + +/* check if we need to relocate ourselves to the link addr or were we + loaded there to begin with -- Cort */ + lis r4,start@h + ori r4,r4,start@l + mflr r3 + subi r3,r3,4 /* we get the nip, not the ip of the branch */ + mr r8,r3 + cmp 0,r3,r4 + bne 1010f +/* compute size of whole image in words. this should be moved to + * start_ldr() -- Cort + */ + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* round up */ + sub r5,r5,r4 + srwi r5,r5,2 + mr r7,r5 + b start_ldr +1010: +/* + * no matter where we're loaded, move ourselves to -Ttext address + */ +relocate: + mflr r3 /* Compute code bias */ + subi r3,r3,4 + mr r8,r3 + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* Round up - just in case */ + sub r5,r5,r4 /* Compute # longwords to move */ + srwi r5,r5,2 + mtctr r5 + mr r7,r5 + li r6,0 + subi r3,r3,4 /* Set up for loop */ + subi r4,r4,4 +00: lwzu r5,4(r3) + stwu r5,4(r4) + xor r6,r6,r5 + bdnz 00b + lis r3,start_ldr@h + ori r3,r3,start_ldr@l + mtlr r3 /* Easiest way to do an absolute jump */ + blr +start_ldr: +/* Clear all of BSS and set up stack for C calls */ + lis r3,edata@h + ori r3,r3,edata@l + lis r4,end@h + ori r4,r4,end@l + subi r3,r3,4 + subi r4,r4,4 + li r0,0 +50: stwu r0,4(r3) + cmp 0,r3,r4 + bne 50b +90: mr r9,r1 /* Save old stack pointer (in case it matters) */ + lis r1,.stack@h + ori r1,r1,.stack@l + addi r1,r1,4096*2 + subi r1,r1,256 + li r2,0x000F /* Mask pointer to 16-byte boundary */ + andc r1,r1,r2 + +/* + * Exec kernel loader + */ + mr r3,r8 /* Load point */ + mr r4,r7 /* Program length */ + mr r5,r6 /* Checksum */ + bl decompress_kernel + + lis r6,cmd_line@h + ori r6,r6,cmd_line@l + lwz r6, 0(r6) + subi r7,r6,1 +00: lbzu r2,1(r7) + cmpi 0,r2,0 + bne 00b + + /* r4,r5 have initrd_start, size */ + lis r2,initrd_start@h + ori r2,r2,initrd_start@l + lwz r4,0(r2) + lis r2,initrd_end@h + ori r2,r2,initrd_end@l + lwz r5,0(r2) + + li r9,0x4 + mtlr r9 + li r9,0 + + /* + * Jump to kernel start + */ + blr + +hang: + b hang + +/* + * Delay for a number of microseconds + * -- Use the BUS timer (assumes 66MHz) + */ + .globl udelay +udelay: + mfspr r4,PVR + srwi r4,r4,16 + cmpi 0,r4,1 /* 601 ? */ + bne .udelay_not_601 +00: li r0,86 /* Instructions / microsecond? */ + mtctr r0 +10: addi r0,r0,0 /* NOP */ + bdnz 10b + subic. r3,r3,1 + bne 00b + blr + +.udelay_not_601: + mulli r4,r3,1000 /* nanoseconds */ + addi r4,r4,59 + li r5,60 + divw r4,r4,r5 /* BUS ticks */ +1: mftbu r5 + mftb r6 + mftbu r7 + cmp 0,r5,r7 + bne 1b /* Get [synced] base time */ + addc r9,r6,r4 /* Compute end time */ + addze r8,r5 +2: mftbu r5 + cmp 0,r5,r8 + blt 2b + bgt 3f + mftb r6 + cmp 0,r6,r9 + blt 2b +3: blr + +.globl _get_HID0 +_get_HID0: + mfspr r3,HID0 + blr + +.globl _put_HID0 +_put_HID0: + mtspr HID0,r3 + blr + +.globl _get_MSR +_get_MSR: + mfmsr r3 + blr + +.globl _put_MSR +_put_MSR: + mtmsr r3 + blr + +/* + * Flush instruction cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_instruction_cache) + mflr r5 + bl flush_data_cache + mfspr r3,HID0 /* Caches are controlled by this register */ + li r4,0 + ori r4,r4,(HID0_ICE|HID0_ICFI) + or r3,r3,r4 /* Need to enable+invalidate to clear */ + mtspr HID0,r3 + andc r3,r3,r4 + ori r3,r3,HID0_ICE /* Enable cache */ + mtspr HID0,r3 + mtlr r5 + blr + +#define NUM_CACHE_LINES 128*8 +#define CACHE_LINE_SIZE 32 +#define cache_flush_buffer 0x1000 + +/* + * Flush data cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_data_cache) + lis r3,cache_flush_buffer@h + ori r3,r3,cache_flush_buffer@l + li r4,NUM_CACHE_LINES + mtctr r4 +00: lwz r4,0(r3) + addi r3,r3,CACHE_LINE_SIZE /* Next line, please */ + bdnz 00b +10: blr + .comm .stack,4096*2,4 + diff -Nru a/arch/ppc/boot/pcore/Makefile b/arch/ppc/boot/pcore/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pcore/Makefile Sat Jun 16 06:00:31 2001 @@ -0,0 +1,91 @@ +# arch/ppc/boot/pcore/Makefile +# +# Makefile for Force PowerCore bootloader +# +# Author: Matt Porter +# +# Copyright 2001 MontaVista Software Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. + +.c.s: + $(CC) $(CFLAGS) -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) -c -o $*.o $< +.S.s: + $(CPP) $(AFLAGS) -traditional -o $*.o $< +.S.o: + $(CC) $(AFLAGS) -traditional -c -o $*.o $< + +ZLINKFLAGS = -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00800000 + +GZIP_FLAGS = -v9f + +OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \ + ../common/ns16550.o ../common/string.o +OBJCOPY_ARGS = -O elf32-powerpc +LIBS := ../lib/zlib.a + +OFFSET := ../utils/offset +SIZE := ../utils/size + +all: zImage + +../common/misc-simple.o: ../common/misc-simple.c + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ + -DZIMAGE_SIZE=0 -c -o $@ $*.c + +zvmlinux.initrd: $(OBJECTS) $(LIBS) ../images/vmlinux.gz + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ initrd` \ + -DINITRD_SIZE=`sh $(SIZE) $(OBJDUMP) $@ initrd` \ + -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ + -c -o ../common/misc-simple.o ../common/misc-simple.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +zImage: zvmlinux + dd if=zvmlinux of=../images/$@.pcore skip=64 bs=1k + rm -f zvmlinux + +zImage.initrd: zvmlinux.initrd + dd if=zvmlinux.initrd of=../images/$@.pcore skip=64 bs=1k + rm -f zvmlinux.initrd + +zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz +# +# build the boot loader image and then compute the offset into it +# for the kernel image +# + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ +# +# then with the offset rebuild the bootloader so we know where the kernel is +# + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ + -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ + -c -o ../common/misc-simple.o ../common/misc-simple.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/pcore/head.S b/arch/ppc/boot/pcore/head.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pcore/head.S Sat Jun 16 06:00:31 2001 @@ -0,0 +1,310 @@ +/* + * arch/ppc/boot/pcore/head.S + * + * Initial board bringup code for Force PowerCore boards + * + * Author: Matt Porter + * Derived from arch/ppc/boot/prep/head.S + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include "../../kernel/ppc_defs.h" +#include "../../kernel/ppc_asm.tmpl" +#include +#include + + .text + +/* + * + * Begin at some arbitrary location in RAM or Flash + * Initialize core registers + * Configure memory controller (Not executing from RAM) + * Move the boot code to the link address (8M) + * Setup C stack + * Initialize UART + * Decompress the kernel to 0x0 + * Jump to the kernel entry + * + */ + + .globl start +start: + bl start_ + +start_: +/* + * Configure core registers + */ + + /* Establish default MSR value, exception prefix 0xFFF */ + li r3,MSR_IP|MSR_FP + mtmsr r3 + + /* Clear BATS */ + li r8,0 + mtspr DBAT0U,r8 + mtspr DBAT0L,r8 + mtspr DBAT1U,r8 + mtspr DBAT1L,r8 + mtspr DBAT2U,r8 + mtspr DBAT2L,r8 + mtspr DBAT3U,r8 + mtspr DBAT3L,r8 + mtspr IBAT0U,r8 + mtspr IBAT0L,r8 + mtspr IBAT1U,r8 + mtspr IBAT1L,r8 + mtspr IBAT2U,r8 + mtspr IBAT2L,r8 + mtspr IBAT3U,r8 + mtspr IBAT3L,r8 + isync + sync + sync + + /* Set segment registers */ + lis r8, 0x8000 + isync + mtsr SR0,r8 + mtsr SR1,r8 + mtsr SR2,r8 + mtsr SR3,r8 + mtsr SR4,r8 + mtsr SR5,r8 + mtsr SR6,r8 + mtsr SR7,r8 + mtsr SR8,r8 + mtsr SR9,r8 + mtsr SR10,r8 + mtsr SR11,r8 + mtsr SR12,r8 + mtsr SR13,r8 + mtsr SR14,r8 + mtsr SR15,r8 + isync + sync + sync + + /* Disable L1 icache/dcache */ + li r4,0x0000 + isync + mtspr HID0,r4 + sync + isync + + /* Invalidate and enable L1 icache */ + mfspr r4,HID0 + ori r4,r4,0x8800 + isync + mtspr HID0,r4 + sync + isync + +/* check if we need to relocate ourselves to the link addr or were we + loaded there to begin with -- Cort */ + lis r4,start@h + ori r4,r4,start@l + mflr r3 + subi r3,r3,4 /* we get the nip, not the ip of the branch */ + mr r8,r3 + cmp 0,r3,r4 + bne 1010f +/* compute size of whole image in words. this should be moved to + * start_ldr() -- Cort + */ + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* round up */ + sub r5,r5,r4 + srwi r5,r5,2 + mr r7,r5 + b start_ldr +1010: +/* + * no matter where we're loaded, move ourselves to -Ttext address + */ +relocate: + mflr r3 /* Compute code bias */ + subi r3,r3,4 + mr r8,r3 + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* Round up - just in case */ + sub r5,r5,r4 /* Compute # longwords to move */ + srwi r5,r5,2 + mtctr r5 + mr r7,r5 + li r6,0 + subi r3,r3,4 /* Set up for loop */ + subi r4,r4,4 +00: lwzu r5,4(r3) + stwu r5,4(r4) + xor r6,r6,r5 + bdnz 00b + lis r3,start_ldr@h + ori r3,r3,start_ldr@l + mtlr r3 /* Easiest way to do an absolute jump */ + blr +start_ldr: +/* Clear all of BSS and set up stack for C calls */ + lis r3,edata@h + ori r3,r3,edata@l + lis r4,end@h + ori r4,r4,end@l + subi r3,r3,4 + subi r4,r4,4 + li r0,0 +50: stwu r0,4(r3) + cmp 0,r3,r4 + bne 50b +90: mr r9,r1 /* Save old stack pointer (in case it matters) */ + lis r1,.stack@h + ori r1,r1,.stack@l + addi r1,r1,4096*2 + subi r1,r1,256 + li r2,0x000F /* Mask pointer to 16-byte boundary */ + andc r1,r1,r2 + +/* + * Exec kernel loader + */ + mr r3,r8 /* Load point */ + mr r4,r7 /* Program length */ + mr r5,r6 /* Checksum */ + bl decompress_kernel + + lis r6,cmd_line@h + ori r6,r6,cmd_line@l + lwz r6, 0(r6) + subi r7,r6,1 +00: lbzu r2,1(r7) + cmpi 0,r2,0 + bne 00b + + /* r4,r5 have initrd_start, size */ + lis r2,initrd_start@h + ori r2,r2,initrd_start@l + lwz r4,0(r2) + lis r2,initrd_end@h + ori r2,r2,initrd_end@l + lwz r5,0(r2) + + li r9,0x4 + mtlr r9 + li r9,0 + + /* + * Jump to kernel start + */ + blr + +hang: + b hang + +/* + * Delay for a number of microseconds + * -- Use the BUS timer (assumes 66MHz) + */ + .globl udelay +udelay: + mfspr r4,PVR + srwi r4,r4,16 + cmpi 0,r4,1 /* 601 ? */ + bne .udelay_not_601 +00: li r0,86 /* Instructions / microsecond? */ + mtctr r0 +10: addi r0,r0,0 /* NOP */ + bdnz 10b + subic. r3,r3,1 + bne 00b + blr + +.udelay_not_601: + mulli r4,r3,1000 /* nanoseconds */ + addi r4,r4,59 + li r5,60 + divw r4,r4,r5 /* BUS ticks */ +1: mftbu r5 + mftb r6 + mftbu r7 + cmp 0,r5,r7 + bne 1b /* Get [synced] base time */ + addc r9,r6,r4 /* Compute end time */ + addze r8,r5 +2: mftbu r5 + cmp 0,r5,r8 + blt 2b + bgt 3f + mftb r6 + cmp 0,r6,r9 + blt 2b +3: blr + +.globl _get_HID0 +_get_HID0: + mfspr r3,HID0 + blr + +.globl _put_HID0 +_put_HID0: + mtspr HID0,r3 + blr + +.globl _get_MSR +_get_MSR: + mfmsr r3 + blr + +.globl _put_MSR +_put_MSR: + mtmsr r3 + blr + +/* + * Flush instruction cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_instruction_cache) + mflr r5 + bl flush_data_cache + mfspr r3,HID0 /* Caches are controlled by this register */ + li r4,0 + ori r4,r4,(HID0_ICE|HID0_ICFI) + or r3,r3,r4 /* Need to enable+invalidate to clear */ + mtspr HID0,r3 + andc r3,r3,r4 + ori r3,r3,HID0_ICE /* Enable cache */ + mtspr HID0,r3 + mtlr r5 + blr + +#define NUM_CACHE_LINES 128*8 +#define CACHE_LINE_SIZE 32 +#define cache_flush_buffer 0x1000 + +/* + * Flush data cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_data_cache) + lis r3,cache_flush_buffer@h + ori r3,r3,cache_flush_buffer@l + li r4,NUM_CACHE_LINES + mtctr r4 +00: lwz r4,0(r3) + addi r3,r3,CACHE_LINE_SIZE /* Next line, please */ + bdnz 00b +10: blr + .comm .stack,4096*2,4 + diff -Nru a/arch/ppc/boot/pmac/Makefile b/arch/ppc/boot/pmac/Makefile --- a/arch/ppc/boot/pmac/Makefile Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/boot/pmac/Makefile Sat Jun 16 06:00:24 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.10 06/05/01 20:22:51 paulus +# BK Id: %F% %I% %G% %U% %#% # # Makefile for making XCOFF bootable images for booting on PowerMacs # using Open Firmware. diff -Nru a/arch/ppc/boot/pmac/chrpmain.c b/arch/ppc/boot/pmac/chrpmain.c --- a/arch/ppc/boot/pmac/chrpmain.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/boot/pmac/chrpmain.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.chrpmain.c 1.9 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Paul Mackerras 1997. @@ -34,15 +34,6 @@ #define SCRATCH_SIZE (128 << 10) -#ifdef CONFIG_CMDLINE -#define CMDLINE CONFIG_CMDLINE -#else -#define CMDLINE "" -#endif -char cmd_preset[] = CMDLINE; -char cmd_buf[256]; -char *cmd_line = cmd_buf; - char *avail_ram; char *begin_avail, *end_avail; char *avail_high; @@ -98,7 +89,6 @@ } flush_cache(dst, len); - memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); make_bi_recs((unsigned long) dst + len); sa = (unsigned long)PROG_START; @@ -133,19 +123,14 @@ rec->tag = BI_MACHTYPE; rec->data[0] = _MACH_Pmac; rec->data[1] = 1; - rec->size = sizeof(struct bi_record) + sizeof(unsigned long); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_CMD_LINE; - memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); - rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; + rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); rec = (struct bi_record *)((unsigned long)rec + rec->size); #ifdef SYSMAP_OFFSET rec->tag = BI_SYSMAP; rec->data[0] = SYSMAP_OFFSET; rec->data[1] = SYSMAP_SIZE; - rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); rec = (struct bi_record *)((unsigned long)rec + rec->size); #endif /* SYSMAP_OFFSET */ diff -Nru a/arch/ppc/boot/pmac/coffmain.c b/arch/ppc/boot/pmac/coffmain.c --- a/arch/ppc/boot/pmac/coffmain.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/boot/pmac/coffmain.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.coffmain.c 1.9 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Paul Mackerras 1997. @@ -24,7 +24,7 @@ #define get_16be(x) (*(unsigned short *)(x)) #define get_32be(x) (*(unsigned *)(x)) -#define RAM_START 0xc0000000 +#define RAM_START 0 #define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */ #define PROG_START RAM_START @@ -32,15 +32,6 @@ #define SCRATCH_SIZE (128 << 10) -#ifdef CONFIG_CMDLINE -#define CMDLINE CONFIG_CMDLINE -#else -#define CMDLINE "" -#endif -char cmd_preset[] = CMDLINE; -char cmd_buf[256]; -char *cmd_line = cmd_buf; - char *avail_ram; char *begin_avail, *end_avail; char *avail_high; @@ -81,7 +72,7 @@ claim(0, PROG_SIZE, 0); dst = (void *) RAM_START; if (im[0] == 0x1f && im[1] == 0x8b) { - /* claim some memory for scratch space */ + /* set up scratch space */ begin_avail = avail_high = avail_ram = heap; end_avail = heap + sizeof(heap); printf("heap at 0x%x\n", avail_ram); @@ -95,7 +86,6 @@ } flush_cache(dst, len); - memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); make_bi_recs((unsigned long)dst + len); sa = (unsigned long)PROG_START; @@ -127,18 +117,13 @@ sprintf( (char *)rec->data, "coffboot"); rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1; rec = (struct bi_record *)((unsigned long)rec + rec->size); - + rec->tag = BI_MACHTYPE; rec->data[0] = _MACH_Pmac; rec->data[1] = 1; - rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec->size = sizeof(struct bi_record) + 2 * sizeof(unsigned long); rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_CMD_LINE; - memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); - rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; - rec = (struct bi_record *)((unsigned long)rec + rec->size); - + rec->tag = BI_LAST; rec->size = sizeof(struct bi_record); rec = (struct bi_record *)((unsigned long)rec + rec->size); diff -Nru a/arch/ppc/boot/pmac/dummy.c b/arch/ppc/boot/pmac/dummy.c --- a/arch/ppc/boot/pmac/dummy.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/boot/pmac/dummy.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.dummy.c 1.6 05/18/01 15:17:15 cort + * BK Id: %F% %I% %G% %U% %#% */ int main(void) { diff -Nru a/arch/ppc/boot/pmac/misc.S b/arch/ppc/boot/pmac/misc.S --- a/arch/ppc/boot/pmac/misc.S Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/boot/pmac/misc.S Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.misc.S 1.6 05/18/01 15:17:15 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Paul Mackerras 1997. diff -Nru a/arch/ppc/boot/pmac/start.c b/arch/ppc/boot/pmac/start.c --- a/arch/ppc/boot/pmac/start.c Sat Jun 16 06:00:30 2001 +++ b/arch/ppc/boot/pmac/start.c Sat Jun 16 06:00:30 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.start.c 1.8 05/18/01 15:17:15 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Paul Mackerras 1997. diff -Nru a/arch/ppc/boot/pmon/Makefile b/arch/ppc/boot/pmon/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pmon/Makefile Sat Jun 16 06:00:32 2001 @@ -0,0 +1,115 @@ +# arch/ppc/pmonboot/Makefile +# +# Makefile for PMON bootloader +# +# Author: Matt Porter +# Cleanups: Tom Rini +# +# Copyright 2000-2001 MontaVista Software Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. + +.c.s: + $(CC) $(CFLAGS) -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) -c -o $*.o $< +.S.s: + $(CPP) $(AFLAGS) -traditional -o $*.o $< +.S.o: + $(CC) $(AFLAGS) -traditional -c -o $*.o $< + +ZLINKFLAGS = -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00800000 + +OBJECTS := head.o ns16550.o ../common/misc-common.o ../common/misc-simple.o \ + ../common/string.o +LIBS := ../lib/zlib.a +OBJCOPY_ARGS = -O elf32-powerpc +MKPMON := ../utils/mkpmon +SIZE := ../utils/size +OFFSET := ../utils/offset + +TFTPIMAGE := /tftpboot/zImage.pmon + +all: zImage + +../common/misc-simple.o: ../common/misc-simple.c + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ + -DZIMAGE_SIZE=0 -c -o $@ $*.c + +ns16550.o: ../common/ns16550.c + $(CC) $(CFLAGS) -DIOOFFSET=0x80000000 -c -o $@ ../common/$*.c + +zImage.initrd: zvmlinux.initrd $(MKPMON) + $(OBJCOPY) $(OBJCOPY_ARGS) --change-addresses=0x100000 \ + --change-section-address=image=0x0 \ + --change-section-address=initrd=0x0 zvmlinux.initrd ../images/$@.pmon + $(MKPMON) `$(OBJDUMP) -h ../images/$@.pmon | grep " initrd" | awk '{print $$6}'` \ + `$(OBJDUMP) -h ../images/$@.pmon | grep " initrd" | awk '{print $$3}'` \ + ../images/$@.pmon + rm -f zvmlinux.initrd + +zImage: zvmlinux $(MKPMON) + $(OBJCOPY) $(OBJCOPY_ARGS) --change-addresses=0x100000 \ + --change-section-address=image=0x0 zvmlinux ../images/$@.pmon + $(MKPMON) `$(OBJDUMP) -h ../images/$@.pmon | grep " image" | \ + awk '{print $$6}'` \ + `$(OBJDUMP) -h ../images/$@.pmon | grep " image" | \ + awk '{print $$3}'` ../images/$@.pmon + rm -f zvmlinux + +zvmlinux.initrd: zvmlinux + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ initrd` \ + -DINITRD_SIZE=`sh $(SIZE) $(OBJDUMP) $@ initrd` \ + -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ + -c -o ../common/misc-simple.o ../common/misc-simple.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz +# +# build the boot loader image and then compute the offset into it +# for the kernel image +# + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ +# +# then with the offset rebuild the bootloader so we know where the kernel is +# + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ + -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ + -D__BOOTER__ \ + -c -o ../common/misc-simple.o ../common/misc-simple.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +znetboot: zImage + cp ../images/zImage.pmon $(TFTPIMAGE) + +znetboot.initrd: zImage.initrd + cp ../images/zImage.initrd.pmon $(TFTPIMAGE) + +floppy: $(TOPDIR)/vmlinux zImage + dd if=zImage of=/dev/fd0H1440 bs=64b + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/pmon/head.S b/arch/ppc/boot/pmon/head.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pmon/head.S Sat Jun 16 06:00:32 2001 @@ -0,0 +1,652 @@ +/* + * arch/ppc/boot/pmon/head.S + * + * Initial board bringup code for PMON equipped systems + * + * Author: Matt Porter + * Derived from arch/ppc/boot/prep/head.S + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include "../../kernel/ppc_defs.h" +#include "../../kernel/ppc_asm.tmpl" +#include +#include +#include "../../kernel/cpc710.h" +#include "../../kernel/k2.h" + +/* This is a kludge for the bootloader */ +#define _IO_BASE 0x80000000 + +/* + * Board initialization macros + */ + +#define DELAY \ + lis r3,0x000f; \ + ori r3,r3,0xffff; \ +0: subi r3,r3,1; \ + cmpi 0,0,r3,0; \ + bne 0b + +#define WRITE_MEM_32(address, data) \ + lis r3, address@h; \ + ori r3, r3, address@l; \ + lis r4, data@h; \ + ori r4, r4, data@l; \ + stw r4, 0x0000(r3); \ + sync; \ + eieio; \ + DELAY + +#define WRITE_MEM_8(address, data) \ + lis r3, address@h; \ + ori r3, r3, address@l; \ + li r4, data; \ + stb r4, 0(r3); \ + sync; \ + eieio; \ + DELAY + +#define WRITE_PCI64_CONFIG_32(address, data) \ + lis r3, K2_PCI64_CONFIG_ADDR@h; \ + ori r3, r3, K2_PCI64_CONFIG_ADDR@l; \ + lis r4, address@h; \ + ori r4, r4, address@l; \ + stw r4, 0(r3); \ + lis r3, K2_PCI64_CONFIG_DATA@h; \ + ori r3, r3, K2_PCI64_CONFIG_DATA@l; \ + lis r4, data@h; \ + ori r4, r4, data@l; \ + stw r4, 0(r3); \ + sync; \ + eieio; \ + DELAY + +#define WRITE_PCI32_CONFIG_32(address, data) \ + lis r3, K2_PCI32_CONFIG_ADDR@h; \ + ori r3, r3, K2_PCI32_CONFIG_ADDR@l; \ + lis r4, address@h; \ + ori r4, r4, address@l; \ + stw r4, 0(r3); \ + lis r3, K2_PCI32_CONFIG_DATA@h; \ + ori r3, r3, K2_PCI32_CONFIG_DATA@l; \ + lis r4, data@h; \ + ori r4, r4, data@l; \ + stw r4, 0(r3); \ + sync; \ + eieio; \ + DELAY + +#define WRITE_PCI64_CONFIG_16(address, data) \ + lis r3, K2_PCI64_CONFIG_ADDR@h; \ + ori r3, r3, K2_PCI64_CONFIG_ADDR@l; \ + lis r4, address@h; \ + ori r4, r4, address@l; \ + stw r4, 0(r3); \ + lis r3, K2_PCI64_CONFIG_DATA@h; \ + ori r3, r3, K2_PCI64_CONFIG_DATA@l; \ + lis r4, data@h; \ + ori r4, r4, data@l; \ + sth r4, 0(r3); \ + sync; \ + eieio; \ + DELAY + +#define WRITE_PCI32_CONFIG_16(address, data) \ + lis r3, K2_PCI32_CONFIG_ADDR@h; \ + ori r3, r3, K2_PCI32_CONFIG_ADDR@l; \ + lis r4, address@h; \ + ori r4, r4, address@l; \ + stw r4, 0(r3); \ + lis r3, K2_PCI32_CONFIG_DATA@h; \ + ori r3, r3, K2_PCI32_CONFIG_DATA@l; \ + lis r4, data@h; \ + ori r4, r4, data@l; \ + sth r4, 0(r3); \ + sync; \ + eieio; \ + DELAY + + .text + +/* + * + * Begin at some arbitrary location in RAM or Flash + * Initialize core registers + * Configure memory controller (Not executing from RAM) + * Move the boot code to the link address (8M) + * Setup C stack + * Initialize UART + * Decompress the kernel to 0x0 + * Jump to the kernel entry + * + */ + + .globl start +start: + bl start_ + +start_: +/* + * Configure core registers + */ + + /* Establish default MSR value, exception prefix 0xFFF */ + li r3,MSR_IP|MSR_FP + mtmsr r3 + + /* Clear BATS */ + li r8,0 + mtspr DBAT0U,r8 + mtspr DBAT0L,r8 + mtspr DBAT1U,r8 + mtspr DBAT1L,r8 + mtspr DBAT2U,r8 + mtspr DBAT2L,r8 + mtspr DBAT3U,r8 + mtspr DBAT3L,r8 + mtspr IBAT0U,r8 + mtspr IBAT0L,r8 + mtspr IBAT1U,r8 + mtspr IBAT1L,r8 + mtspr IBAT2U,r8 + mtspr IBAT2L,r8 + mtspr IBAT3U,r8 + mtspr IBAT3L,r8 + isync + sync + sync + + /* Set segment registers */ + lis r8, 0x8000 + isync + mtsr SR0,r8 + mtsr SR1,r8 + mtsr SR2,r8 + mtsr SR3,r8 + mtsr SR4,r8 + mtsr SR5,r8 + mtsr SR6,r8 + mtsr SR7,r8 + mtsr SR8,r8 + mtsr SR9,r8 + mtsr SR10,r8 + mtsr SR11,r8 + mtsr SR12,r8 + mtsr SR13,r8 + mtsr SR14,r8 + mtsr SR15,r8 + isync + sync + sync + + /* Disable L1 icache/dcache */ + li r4,0x0000 + isync + mtspr HID0,r4 + sync + isync + + /* Invalidate and enable L1 icache */ + mfspr r4,HID0 + ori r4,r4,0x8800 + isync + mtspr HID0,r4 + sync + isync + + /* + * If we are executing from flash, then do the full init as + * follows. Otherwise, skip the memory controller reset, etc. + */ + lis r4,0xfff0 + ori r4,r4,0x0104 + mflr r3 + cmp 0,r3,r4 + bne brdgcnfg + +/* + * Configure CPC710 bridge, memory controller, and ALI M1543C PIB + */ + /* Initialize CPC710 core registers */ + WRITE_MEM_32(RSTR, 0xf0000000) + + /* Dummy read */ + lis r3, MPSR@h + ori r3, r3, MPSR@l + lwz r4, 0(r3) + sync + eieio + + WRITE_MEM_32(SIOC, 0x00000000) + WRITE_MEM_32(PIDR, 0x00000000) + WRITE_MEM_32(UCTL, 0x00780080) + WRITE_MEM_32(ABCNTL, 0x70000000) + WRITE_MEM_32(SRST, 0x00000000) + WRITE_MEM_32(ERRC, 0x00000000) + WRITE_MEM_32(SESR, 0x00000000) + WRITE_MEM_32(SEAR, 0x00000000) + WRITE_MEM_32(GPDIR, 0x00000000) + WRITE_MEM_32(ATAS, 0x709c2508) + WRITE_MEM_32(AVDG, 0x00000000) + WRITE_MEM_32(MESR, 0x00000000) + WRITE_MEM_32(MEAR, 0x00000000) + WRITE_MEM_32(MCER0, 0x00000000) + WRITE_MEM_32(MCER1, 0x00000000) + WRITE_MEM_32(MCER2, 0x00000000) + WRITE_MEM_32(MCER3, 0x00000000) + WRITE_MEM_32(MCER4, 0x00000000) + WRITE_MEM_32(MCER5, 0x00000000) + WRITE_MEM_32(MCER6, 0x00000000) + WRITE_MEM_32(MCER7, 0x00000000) + WRITE_MEM_32(MCCR, 0x52b06000) + +brdgcnfg: + WRITE_MEM_32(PGCHP, 0x808000e0) /* Set FPHB modes */ + /* Enable and map PCI32 and PCI64 registers to a base address */ + WRITE_MEM_32(CNFR, 0x80000003) /* Activate CNFR - PCI64 */ + WRITE_MEM_32(BAR, K2_PCI64_BAR) /* Set BAR - PCI64_BAR_VALUE */ + WRITE_MEM_32(PCIENB, 0x80000000) /* Enable PCI Control Space */ + WRITE_MEM_32(CNFR, 0x00000000) /* Deactivate CNFR - PCI64 */ + WRITE_MEM_32(CNFR, 0x80000002) /* Activate CNFR - PCI32 */ + WRITE_MEM_32(BAR, K2_PCI32_BAR) /* Set BAR - PCI32_BAR_VALUE */ + WRITE_MEM_32(PCIENB, 0x80000000) /* Enable PCI Control Space */ + WRITE_MEM_32(CNFR, 0x00000000) /* Deactivate CNFR - PCI32 */ + + /* PCI64 Config space init */ + WRITE_PCI64_CONFIG_32(0x04000080,0x07038002) /* SERR,BMAS,I/O,MEM */ + WRITE_PCI64_CONFIG_32(0x68000080,0x0f000000) /* Reset INTA-D */ + WRITE_PCI64_CONFIG_16(0x40000080,0x000f) /* Set BUS_NO */ + + /* PCI32 Config space init */ + WRITE_PCI32_CONFIG_32(0x04000080,0x07038002) /* SERR,BMAS,I/O,MEM */ + WRITE_PCI32_CONFIG_32(0x68000080,0x0f000000) /* Reset INTA-D */ + WRITE_PCI32_CONFIG_16(0x40000080,0x000f) /* Set BUS_NO */ + + /* PCI64 memory mappings */ + + WRITE_MEM_32(0xff4f6110, 0x00000000) /* PSEA */ + WRITE_MEM_32(0xff4f6120, 0xc0000000) /* PCIDG */ + WRITE_MEM_32(0xff4f7800, 0x08000000) /* PIBAR - PCI I/O base */ + WRITE_MEM_32(0xff4f7810, 0x08000000) /* PMBAR - PCI Mem base */ + WRITE_MEM_32(0xff4f7f20, 0x80008000) /* PR - MRU parking,queue on */ + WRITE_MEM_32(0xff4f7f30, 0xff000000) /* ACR - Enable all levels */ + WRITE_MEM_32(0xff4f7f40, 0xf8000000) /* MSIZE - 128MB */ + WRITE_MEM_32(0xff4f7f60, 0xf8000000) /* IOSIZE - 128MB */ + WRITE_MEM_32(0xff4f7f80, 0xc8000000) /* SMBAR - Base@0xc8000000 */ + WRITE_MEM_32(0xff4f7fc0, 0x88000000) /* SIBAR - Base@0x88000000 */ + WRITE_MEM_32(0xff4f7fd0, 0x02000000) /* CTLRW - ISA contiguous */ + WRITE_MEM_32(0xff4f8100, 0x000000c0) /* PSSIZE - 1GB space */ + WRITE_MEM_32(0xff4f8110, 0x000000c0) /* PPSIZE - 1GB space */ + WRITE_MEM_32(0xff4f8120, 0x00000000) /* BARPS - Base@0x00000000 */ + WRITE_MEM_32(0xff4f8130, 0x00000000) /* BARPP - Base@0x00000000 */ + WRITE_MEM_32(0xff4f8310, 0x00000000) /* Init INT_SET */ + + /* PCI32 memory mappings */ + WRITE_MEM_32(0xff5f6110, 0x00000000) /* Clear PSEA */ + WRITE_MEM_32(0xff5f6120, 0x40000000) /* PIDG */ + WRITE_MEM_32(0xff5f7800, 0x00000000) /* PIBAR - PCI I/O Base */ + WRITE_MEM_32(0xff5f7810, 0x00000000) /* PMBAR - PCI Mem Base */ + WRITE_MEM_32(0xff5f7f20, 0xa000c000) /* PR - Enable translation */ + WRITE_MEM_32(0xff5f7f30, 0xfc000000) /* ACR - Enable all levels */ + WRITE_MEM_32(0xff5f7f40, 0xf8000000) /* MSIZE - 128MB */ + WRITE_MEM_32(0xff5f7f60, 0xf8000000) /* IOSIZE - 128MB */ + WRITE_MEM_32(0xff5f7f80, 0xc0000000) /* SMBAR - Base@0xc0000000 */ + WRITE_MEM_32(0xff5f7fc0, 0x80000000) /* SIBAR - Base@0x80000000 */ + WRITE_MEM_32(0xff5f7fd0, 0x00000000) /* CTLRW - ISA contiguous */ + WRITE_MEM_32(0xff5f8100, 0x000000c0) /* PSSIZE - 1GB space */ + WRITE_MEM_32(0xff5f8110, 0x000000c0) /* PPSIZE - 1GB space */ + WRITE_MEM_32(0xff5f8120, 0x00000000) /* BARPS - Base@0x00000000 */ + WRITE_MEM_32(0xff5f8130, 0x00000000) /* BARPP - Base@0x00000000 */ + + /* PCI64 specific memory mappings */ + WRITE_PCI64_CONFIG_32(0x10000080, 0x00000080) /* PSBAR - Base@0x80 */ + + /* PCI32 specific memory mappings */ + WRITE_MEM_32(0xff5f8140, 0x00000080) /* PSBAR - Base@0x80 */ + WRITE_MEM_32(0xff5f8150, 0x00000000) /* PPBAR */ + WRITE_MEM_32(0xff5f8200, 0xcc000000) /* BPMDLK */ + WRITE_MEM_32(0xff5f8210, 0xff000000) /* TPMDLK */ + WRITE_MEM_32(0xff5f8220, 0x81000000) /* BIODLK */ + WRITE_MEM_32(0xff5f8230, 0xc0000000) /* TIODLK */ + + /* Turn off PCI64/PCI32 resets */ + WRITE_MEM_32(0xff4f7ef0, 0xfc000000) + WRITE_MEM_32(0xff5f7ef0, 0xfc000000) + + /* ALI 1543C PCI-ISA bridge config */ + WRITE_PCI32_CONFIG_32(0x40400080, 0x00000230) /* Set PIC,IORC,ISAC */ + WRITE_PCI32_CONFIG_32(0x44400080, 0x00800000) /* Enable PCI polling */ + WRITE_PCI32_CONFIG_32(0x50400080, 0x00000040) /* Disable USB */ + WRITE_PCI32_CONFIG_32(0x54400080, 0x00030800) + WRITE_PCI32_CONFIG_32(0x58400080, 0x000d0e03) + WRITE_PCI32_CONFIG_32(0x5c400080, 0x0000000c) + WRITE_PCI32_CONFIG_32(0x70400080, 0x00000000) + WRITE_PCI32_CONFIG_32(0x78400080, 0x00000000) + + /* Turn on board fail light and turn off other lights */ + WRITE_MEM_8(0x80000804, 0x22); + + /* Turn off board fail light and turn on User1 light */ + WRITE_MEM_8(0x80000804, 0x24) + + /* Turn on hotswap light and unmask ENUM */ + WRITE_MEM_8(0x8000080c, 0x00); + + /* Enable ALI 1543C UARTs */ + WRITE_MEM_8(K2_ISAPNP_CONFIG, 0x51) /* Write config key */ + WRITE_MEM_8(K2_ISAPNP_CONFIG, 0x23) /* Write config key */ + WRITE_MEM_8(K2_ISAPNP_INDEX, 0x22) /* Access powerdown control */ + WRITE_MEM_8(K2_ISAPNP_DATA, 0x00) /* Wake up UARTs */ + WRITE_MEM_8(K2_ISAPNP_INDEX, 0x07) /* Access logical device reg */ + WRITE_MEM_8(K2_ISAPNP_DATA, 0x04) /* Point to UART1 */ + WRITE_MEM_8(K2_ISAPNP_INDEX, 0x30) /* Access reg 30 */ + WRITE_MEM_8(K2_ISAPNP_DATA, 0x01) /* Enable UART1 */ + WRITE_MEM_8(K2_ISAPNP_INDEX, 0x07) /* Access logical device reg */ + WRITE_MEM_8(K2_ISAPNP_DATA, 0x05) /* Point to UART3 */ + WRITE_MEM_8(K2_ISAPNP_INDEX, 0x30) /* Access reg 30 */ + WRITE_MEM_8(K2_ISAPNP_DATA, 0x01) /* Enable UART3 */ + WRITE_MEM_8(K2_ISAPNP_CONFIG, 0xbb) /* Exit config mode */ + + /* + * Configure CPC710 memory controller + */ + andi. r4,r4,0x00e0 + + /* + * If we are executing from flash, then do the full init as + * follows. Otherwise, skip the memory size configuration. + */ + lis r4,0xfff0 + ori r4,r4,0x0104 + mflr r3 + cmp 0,r3,r4 + bne endmemcfg + + cmpli 0,0,r4,0x0040 + beq config_512x2 + + cmpli 0,0,r4,0x0060 + beq config_512x1 + + cmpli 0,0,r4,0x0080 + beq config_256x2 + + cmpli 0,0,r4,0x00a0 + beq config_256x1 + + cmpli 0,0,r4,0x00c0 + beq config_128x2 + + b config_128x1 /* 0x00e0 or others default to 128x1 */ + +config_512x2: + WRITE_MEM_32(MCER0, 0x80000080) /* Bank 0 MER - 512MB */ + WRITE_MEM_32(MCER1, 0x82000080) /* Bank 1 MER - 512MB */ + b mccr + +config_512x1: + WRITE_MEM_32(MCER0, 0x80000080) /* Bank 0 MER - 512MB */ + b mccr + +config_256x2: + WRITE_MEM_32(MCER0, 0x800000d4) /* Bank 0 MER - 256MB */ + WRITE_MEM_32(MCER1, 0x810000d4) /* Bank 1 MER - 256MB */ + b mccr + +config_256x1: + WRITE_MEM_32(MCER0, 0x800000d4) /* Bank 0 MER - 256MB */ + b mccr + +config_128x2: + WRITE_MEM_32(MCER0, 0x800080c0) /* Bank 0 MER - 128MB */ + WRITE_MEM_32(MCER1, 0x808080c0) /* Bank 1 MER - 128MB */ + b mccr + +config_128x1: + WRITE_MEM_32(MCER0, 0x800080c0) /* Bank 0 MER - 128MB */ + +mccr: + /* Enable memory controller configuration */ + WRITE_MEM_32(MCCR, 0xf2b06000) + +sdwait: + /* Wait until SDRAM initialization is complete */ + nop + lis r3, MCCR@h + ori r3, r3, MCCR@l + lwz r4, 0(r3) + lis r5, 0x2000 + ori r5, r5, 0x0000 + and r4, r4, r5 + cmpl 0, 0, r5, r4 + bne sdwait + +endmemcfg: + /* Configure M5229 IDE PIB settings */ + WRITE_PCI32_CONFIG_32(0x40400080, 0x00000233) /* 3 wait states */ + WRITE_PCI32_CONFIG_32(0x48400080, 0x580731b9) /* PCI IRQ routes */ + WRITE_PCI32_CONFIG_32(0x4c400080, 0x00000000) /* Disable SIRQ maps */ + WRITE_PCI32_CONFIG_32(0x44400080, 0x0d800000) /* primary IDE->14 */ + WRITE_PCI32_CONFIG_32(0x74400080, 0x000d0000) /* secondary IDE->14 */ + + /* Configure PIC level/edge settings */ + WRITE_MEM_8(0x800004d0, 0x62) + WRITE_MEM_8(0x800004d1, 0xde) + + /* Configure M5229 IDE settings */ + WRITE_PCI32_CONFIG_32(0x58400080, 0x480d0e03) /* Enable IDE */ + WRITE_PCI32_CONFIG_32(0x50880080, 0x03000000) /* Enable IDE */ + WRITE_PCI32_CONFIG_32(0x04880080, 0x04008002) /* I/O accesses on */ + WRITE_PCI32_CONFIG_32(0x08880080, 0xc1df0101) /* Native, sec only */ + + /* Turn on User2 LED */ + WRITE_MEM_8(0x80000804, 0x21) + +/* check if we need to relocate ourselves to the link addr or were we + loaded there to begin with -- Cort */ + lis r4,start@h + ori r4,r4,start@l + mflr r3 + subi r3,r3,4 /* we get the nip, not the ip of the branch */ + mr r8,r3 + cmp 0,r3,r4 + bne 1010f +/* compute size of whole image in words. this should be moved to + * start_ldr() -- Cort + */ + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* round up */ + sub r5,r5,r4 + srwi r5,r5,2 + mr r7,r5 + b start_ldr +1010: +/* + * no matter where we're loaded, move ourselves to -Ttext address + */ +relocate: + mflr r3 /* Compute code bias */ + subi r3,r3,4 + mr r8,r3 + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* Round up - just in case */ + sub r5,r5,r4 /* Compute # longwords to move */ + srwi r5,r5,2 + mtctr r5 + mr r7,r5 + li r6,0 + subi r3,r3,4 /* Set up for loop */ + subi r4,r4,4 +00: lwzu r5,4(r3) + stwu r5,4(r4) + xor r6,r6,r5 + bdnz 00b + lis r3,start_ldr@h + ori r3,r3,start_ldr@l + mtlr r3 /* Easiest way to do an absolute jump */ + blr +start_ldr: +/* Clear all of BSS and set up stack for C calls */ + lis r3,edata@h + ori r3,r3,edata@l + lis r4,end@h + ori r4,r4,end@l + subi r3,r3,4 + subi r4,r4,4 + li r0,0 +50: stwu r0,4(r3) + cmp 0,r3,r4 + bne 50b +90: mr r9,r1 /* Save old stack pointer (in case it matters) */ + lis r1,.stack@h + ori r1,r1,.stack@l + addi r1,r1,4096*2 + subi r1,r1,256 + li r2,0x000F /* Mask pointer to 16-byte boundary */ + andc r1,r1,r2 + +/* + * Exec kernel loader + */ + mr r3,r8 /* Load point */ + mr r4,r7 /* Program length */ + mr r5,r6 /* Checksum */ + bl decompress_kernel + + lis r6,cmd_line@h + ori r6,r6,cmd_line@l + lwz r6, 0(r6) + subi r7,r6,1 +00: lbzu r2,1(r7) + cmpi 0,r2,0 + bne 00b + + /* r4,r5 have initrd_start, size */ + lis r2,initrd_start@h + ori r2,r2,initrd_start@l + lwz r4,0(r2) + lis r2,initrd_end@h + ori r2,r2,initrd_end@l + lwz r5,0(r2) + + li r9,0x4 + mtlr r9 + + /* + * Jump to kernel start + */ + blr + +hang: + b hang + +/* + * Delay for a number of microseconds + * -- Use the BUS timer (assumes 66MHz) + */ + .globl udelay +udelay: + mfspr r4,PVR + srwi r4,r4,16 + cmpi 0,r4,1 /* 601 ? */ + bne .udelay_not_601 +00: li r0,86 /* Instructions / microsecond? */ + mtctr r0 +10: addi r0,r0,0 /* NOP */ + bdnz 10b + subic. r3,r3,1 + bne 00b + blr + +.udelay_not_601: + mulli r4,r3,1000 /* nanoseconds */ + addi r4,r4,59 + li r5,60 + divw r4,r4,r5 /* BUS ticks */ +1: mftbu r5 + mftb r6 + mftbu r7 + cmp 0,r5,r7 + bne 1b /* Get [synced] base time */ + addc r9,r6,r4 /* Compute end time */ + addze r8,r5 +2: mftbu r5 + cmp 0,r5,r8 + blt 2b + bgt 3f + mftb r6 + cmp 0,r6,r9 + blt 2b +3: blr + +.globl _get_HID0 +_get_HID0: + mfspr r3,HID0 + blr + +.globl _put_HID0 +_put_HID0: + mtspr HID0,r3 + blr + +.globl _get_MSR +_get_MSR: + mfmsr r3 + blr + +.globl _put_MSR +_put_MSR: + mtmsr r3 + blr + +/* + * Flush instruction cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_instruction_cache) + mflr r5 + bl flush_data_cache + mfspr r3,HID0 /* Caches are controlled by this register */ + li r4,0 + ori r4,r4,(HID0_ICE|HID0_ICFI) + or r3,r3,r4 /* Need to enable+invalidate to clear */ + mtspr HID0,r3 + andc r3,r3,r4 + ori r3,r3,HID0_ICE /* Enable cache */ + mtspr HID0,r3 + mtlr r5 + blr + +#define NUM_CACHE_LINES 128*8 +#define CACHE_LINE_SIZE 32 +#define cache_flush_buffer 0x1000 + +/* + * Flush data cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_data_cache) + lis r3,cache_flush_buffer@h + ori r3,r3,cache_flush_buffer@l + li r4,NUM_CACHE_LINES + mtctr r4 +00: lwz r4,0(r3) + addi r3,r3,CACHE_LINE_SIZE /* Next line, please */ + bdnz 00b +10: blr + .comm .stack,4096*2,4 + diff -Nru a/arch/ppc/boot/pp3/Makefile b/arch/ppc/boot/pp3/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pp3/Makefile Sat Jun 16 06:00:30 2001 @@ -0,0 +1,96 @@ +# arch/ppc/pp3boot/Makefile +# +# Makefile for PowerPlus III bootloader +# +# Author: Matt Porter +# +# Copyright 2001 MontaVista Software Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. + +.c.s: + $(CC) $(CFLAGS) -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $< +.S.s: + $(CPP) $(AFLAGS) -traditional -o $*.o $< +.S.o: + $(CC) $(AFLAGS) -traditional -c -o $*.o $< + +ZLINKFLAGS = -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00800000 + +GZIP_FLAGS = -v9f + +OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \ + ../common/ns16550.o ../common/string.o +OBJCOPY_ARGS = -O elf32-powerpc +LIBS := ../lib/zlib.a + +OFFSET := ../utils/offset +SIZE := ../utils/size +MKPREP := ../utils/mkprep +MKBUGBOOT := ../utils/mkbugboot + +all: zImage + +../common/misc-simple.o: ../common/misc-simple.c + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ + -DZIMAGE_SIZE=0 -c -o $@ $*.c + +zvmlinux.initrd: $(OBJECTS) $(LIBS) ../images/vmlinux.gz + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ initrd` \ + -DINITRD_SIZE=`sh $(SIZE) $(OBJDUMP) $@ initrd` \ + -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ + -c -o ../common/misc-simple.o ../common/misc-simple.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +zImage: zvmlinux $(MKPREP) $(MKBUGBOOT) + $(MKPREP) -pbp zvmlinux ../images/$@.pp3 + $(MKBUGBOOT) zvmlinux ../images/$@.bugboot + rm -f zvmlinux + +zImage.initrd: zvmlinux.initrd $(MKPREP) $(MKBUGBOOT) + $(MKPREP) -pbp zvmlinux.initrd ../images/$@.pp3 + $(MKBUGBOOT) zvmlinux.initrd ../images/$@.bugboot + rm -f zvmlinux.initrd + +zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz +# +# build the boot loader image and then compute the offset into it +# for the kernel image +# + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ +# +# then with the offset rebuild the bootloader so we know where the kernel is +# + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ + -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ + -D__BOOTER__ \ + -c -o ../common/misc-simple.o ../common/misc-simple.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/pp3/head.S b/arch/ppc/boot/pp3/head.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pp3/head.S Sat Jun 16 06:00:31 2001 @@ -0,0 +1,310 @@ +/* + * arch/ppc/boot/pp3/head.S + * + * Initial board bringup code for the PrPMC750 + * + * Author: Matt Porter + * Derived from arch/ppc/boot/prep/head.S + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include "../../kernel/ppc_defs.h" +#include "../../kernel/ppc_asm.tmpl" +#include +#include + + .text + +/* + * + * Begin at some arbitrary location in RAM or Flash + * Initialize core registers + * Configure memory controller (Not executing from RAM) + * Move the boot code to the link address (8M) + * Setup C stack + * Initialize UART + * Decompress the kernel to 0x0 + * Jump to the kernel entry + * + */ + + .globl start +start: + bl start_ + +start_: +/* + * Configure core registers + */ + + /* Establish default MSR value, exception prefix 0xFFF */ + li r3,MSR_IP|MSR_FP + mtmsr r3 + + /* Clear BATS */ + li r8,0 + mtspr DBAT0U,r8 + mtspr DBAT0L,r8 + mtspr DBAT1U,r8 + mtspr DBAT1L,r8 + mtspr DBAT2U,r8 + mtspr DBAT2L,r8 + mtspr DBAT3U,r8 + mtspr DBAT3L,r8 + mtspr IBAT0U,r8 + mtspr IBAT0L,r8 + mtspr IBAT1U,r8 + mtspr IBAT1L,r8 + mtspr IBAT2U,r8 + mtspr IBAT2L,r8 + mtspr IBAT3U,r8 + mtspr IBAT3L,r8 + isync + sync + sync + + /* Set segment registers */ + lis r8, 0x8000 + isync + mtsr SR0,r8 + mtsr SR1,r8 + mtsr SR2,r8 + mtsr SR3,r8 + mtsr SR4,r8 + mtsr SR5,r8 + mtsr SR6,r8 + mtsr SR7,r8 + mtsr SR8,r8 + mtsr SR9,r8 + mtsr SR10,r8 + mtsr SR11,r8 + mtsr SR12,r8 + mtsr SR13,r8 + mtsr SR14,r8 + mtsr SR15,r8 + isync + sync + sync + + /* Disable L1 icache/dcache */ + li r4,0x0000 + isync + mtspr HID0,r4 + sync + isync + + /* Invalidate and enable L1 icache */ + mfspr r4,HID0 + ori r4,r4,0x8800 + isync + mtspr HID0,r4 + sync + isync + +/* check if we need to relocate ourselves to the link addr or were we + loaded there to begin with -- Cort */ + lis r4,start@h + ori r4,r4,start@l + mflr r3 + subi r3,r3,4 /* we get the nip, not the ip of the branch */ + mr r8,r3 + cmp 0,r3,r4 + bne 1010f +/* compute size of whole image in words. this should be moved to + * start_ldr() -- Cort + */ + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* round up */ + sub r5,r5,r4 + srwi r5,r5,2 + mr r7,r5 + b start_ldr +1010: +/* + * no matter where we're loaded, move ourselves to -Ttext address + */ +relocate: + mflr r3 /* Compute code bias */ + subi r3,r3,4 + mr r8,r3 + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* Round up - just in case */ + sub r5,r5,r4 /* Compute # longwords to move */ + srwi r5,r5,2 + mtctr r5 + mr r7,r5 + li r6,0 + subi r3,r3,4 /* Set up for loop */ + subi r4,r4,4 +00: lwzu r5,4(r3) + stwu r5,4(r4) + xor r6,r6,r5 + bdnz 00b + lis r3,start_ldr@h + ori r3,r3,start_ldr@l + mtlr r3 /* Easiest way to do an absolute jump */ + blr +start_ldr: +/* Clear all of BSS and set up stack for C calls */ + lis r3,edata@h + ori r3,r3,edata@l + lis r4,end@h + ori r4,r4,end@l + subi r3,r3,4 + subi r4,r4,4 + li r0,0 +50: stwu r0,4(r3) + cmp 0,r3,r4 + bne 50b +90: mr r9,r1 /* Save old stack pointer (in case it matters) */ + lis r1,.stack@h + ori r1,r1,.stack@l + addi r1,r1,4096*2 + subi r1,r1,256 + li r2,0x000F /* Mask pointer to 16-byte boundary */ + andc r1,r1,r2 + +/* + * Exec kernel loader + */ + mr r3,r8 /* Load point */ + mr r4,r7 /* Program length */ + mr r5,r6 /* Checksum */ + bl decompress_kernel + + lis r6,cmd_line@h + ori r6,r6,cmd_line@l + lwz r6, 0(r6) + subi r7,r6,1 +00: lbzu r2,1(r7) + cmpi 0,r2,0 + bne 00b + + /* r4,r5 have initrd_start, size */ + lis r2,initrd_start@h + ori r2,r2,initrd_start@l + lwz r4,0(r2) + lis r2,initrd_end@h + ori r2,r2,initrd_end@l + lwz r5,0(r2) + + li r9,0x4 + mtlr r9 + li r9,0 + + /* + * Jump to kernel start + */ + blr + +hang: + b hang + +/* + * Delay for a number of microseconds + * -- Use the BUS timer (assumes 66MHz) + */ + .globl udelay +udelay: + mfspr r4,PVR + srwi r4,r4,16 + cmpi 0,r4,1 /* 601 ? */ + bne .udelay_not_601 +00: li r0,86 /* Instructions / microsecond? */ + mtctr r0 +10: addi r0,r0,0 /* NOP */ + bdnz 10b + subic. r3,r3,1 + bne 00b + blr + +.udelay_not_601: + mulli r4,r3,1000 /* nanoseconds */ + addi r4,r4,59 + li r5,60 + divw r4,r4,r5 /* BUS ticks */ +1: mftbu r5 + mftb r6 + mftbu r7 + cmp 0,r5,r7 + bne 1b /* Get [synced] base time */ + addc r9,r6,r4 /* Compute end time */ + addze r8,r5 +2: mftbu r5 + cmp 0,r5,r8 + blt 2b + bgt 3f + mftb r6 + cmp 0,r6,r9 + blt 2b +3: blr + +.globl _get_HID0 +_get_HID0: + mfspr r3,HID0 + blr + +.globl _put_HID0 +_put_HID0: + mtspr HID0,r3 + blr + +.globl _get_MSR +_get_MSR: + mfmsr r3 + blr + +.globl _put_MSR +_put_MSR: + mtmsr r3 + blr + +/* + * Flush instruction cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_instruction_cache) + mflr r5 + bl flush_data_cache + mfspr r3,HID0 /* Caches are controlled by this register */ + li r4,0 + ori r4,r4,(HID0_ICE|HID0_ICFI) + or r3,r3,r4 /* Need to enable+invalidate to clear */ + mtspr HID0,r3 + andc r3,r3,r4 + ori r3,r3,HID0_ICE /* Enable cache */ + mtspr HID0,r3 + mtlr r5 + blr + +#define NUM_CACHE_LINES 128*8 +#define CACHE_LINE_SIZE 32 +#define cache_flush_buffer 0x1000 + +/* + * Flush data cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_data_cache) + lis r3,cache_flush_buffer@h + ori r3,r3,cache_flush_buffer@l + li r4,NUM_CACHE_LINES + mtctr r4 +00: lwz r4,0(r3) + addi r3,r3,CACHE_LINE_SIZE /* Next line, please */ + bdnz 00b +10: blr + .comm .stack,4096*2,4 + diff -Nru a/arch/ppc/boot/prep/Makefile b/arch/ppc/boot/prep/Makefile --- a/arch/ppc/boot/prep/Makefile Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/boot/prep/Makefile Sat Jun 16 06:00:28 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.15 05/21/01 11:51:32 trini +# BK Id: %F% %I% %G% %U% %#% # # arch/ppc/boot/Makefile # @@ -33,13 +33,17 @@ endif ZLINKFLAGS = -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00800000 -OBJECTS := head.o misc.o vreset.o kbd.o ../common/misc-common.o \ +OBJECTS := head.o misc.o ../common/misc-common.o \ ../common/string.o of1275.o OBJCOPY_ARGS = -O elf32-powerpc LIBS = ../lib/zlib.a ifeq ($(CONFIG_SERIAL_CONSOLE),y) OBJECTS += ns16550.o +endif + +ifeq ($(CONFIG_VGA_CONSOLE),y) +OBJECTS += vreset.o kbd.o endif # Tools diff -Nru a/arch/ppc/boot/prep/head.S b/arch/ppc/boot/prep/head.S --- a/arch/ppc/boot/prep/head.S Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/boot/prep/head.S Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.head.S 1.8 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ #include "../../kernel/ppc_defs.h" #include "../../kernel/ppc_asm.tmpl" diff -Nru a/arch/ppc/boot/prep/iso_font.h b/arch/ppc/boot/prep/iso_font.h --- a/arch/ppc/boot/prep/iso_font.h Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/boot/prep/iso_font.h Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.iso_font.h 1.6 05/18/01 15:16:42 cort + * BK Id: %F% %I% %G% %U% %#% */ static const unsigned char font[] = { /* 0x00 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, diff -Nru a/arch/ppc/boot/prep/kbd.c b/arch/ppc/boot/prep/kbd.c --- a/arch/ppc/boot/prep/kbd.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/boot/prep/kbd.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.kbd.c 1.7 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ #include @@ -130,20 +130,29 @@ goto loop; } -static void kbdreset(void) +static int __kbdreset(void) { unsigned char c; - int i; + int i, t; /* flush input queue */ + t = 1000; while ((inb(KBSTATP) & KBINRDY)) { (void)inb(KBDATAP); + if (--t == 0) + return 1; } /* Send self-test */ - while (inb(KBSTATP) & KBOUTRDY) ; + t = 10000; + while (inb(KBSTATP) & KBOUTRDY) + if (--t == 0) + return 2; outb(KBSTATP,0xAA); - while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */ + t = 100000; + while ((inb(KBSTATP) & KBINRDY) == 0) /* wait input ready */ + if (--t == 0) + return 3; if ((c = inb(KBDATAP)) != 0x55) { puts("Keyboard self test failed - result:"); @@ -151,15 +160,23 @@ puts("\n"); } /* Enable interrupts and keyboard controller */ - while (inb(KBSTATP) & KBOUTRDY) ; - outb(KBSTATP,0x60); - while (inb(KBSTATP) & KBOUTRDY) ; + t = 10000; + while (inb(KBSTATP) & KBOUTRDY) + if (--t == 0) return 4; + outb(KBSTATP,0x60); + t = 10000; + while (inb(KBSTATP) & KBOUTRDY) + if (--t == 0) return 5; outb(KBDATAP,0x45); for (i = 0; i < 10000; i++) udelay(1); - - while (inb(KBSTATP) & KBOUTRDY) ; + + t = 10000; + while (inb(KBSTATP) & KBOUTRDY) + if (--t == 0) return 6; outb(KBSTATP,0x20); - while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */ + t = 100000; + while ((inb(KBSTATP) & KBINRDY) == 0) /* wait input ready */ + if (--t == 0) return 7; if (! (inb(KBDATAP) & 0x40)) { /* * Quote from PS/2 System Reference Manual: @@ -169,15 +186,31 @@ * output-buffer-full bit in the Controller Status * register are set 0." (KBINRDY and KBOUTRDY) */ - - while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ; + t = 100000; + while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) + if (--t == 0) return 8; outb(KBDATAP,0xF0); - while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ; + t = 100000; + while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) + if (--t == 0) return 9; outb(KBDATAP,0x01); } - - while (inb(KBSTATP) & KBOUTRDY) ; + t = 10000; + while (inb(KBSTATP) & KBOUTRDY) + if (--t == 0) return 10; outb(KBSTATP,0xAE); + return 0; +} + +static void kbdreset(void) +{ + int ret = __kbdreset(); + + if (ret) { + puts("__kbdreset failed: "); + puthex(ret); + puts("\n"); + } } /* We have to actually read the keyboard when CRT_tstc is called, diff -Nru a/arch/ppc/boot/prep/misc.c b/arch/ppc/boot/prep/misc.c --- a/arch/ppc/boot/prep/misc.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/boot/prep/misc.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.misc.c 1.10 06/05/01 20:20:05 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * misc.c @@ -13,8 +13,9 @@ #include #include "zlib.h" #include -#include #include +#include +#include #include #include #include @@ -102,6 +103,7 @@ return; } +#ifdef CONFIG_VGA_CONSOLE void scroll() { @@ -111,6 +113,7 @@ for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 ) vidmem[i] = ' '; } +#endif /* CONFIG_VGA_CONSOLE */ /* * This routine is used to control the second processor on the @@ -170,7 +173,9 @@ #if defined(CONFIG_SERIAL_CONSOLE) com_port = serial_init(0); #endif /* CONFIG_SERIAL_CONSOLE */ +#if defined(CONFIG_VGA_CONSOLE) vga_init((char)0xC0000000); +#endif /* CONFIG_VGA_CONSOLE */ if (residual) { @@ -360,8 +365,15 @@ while (timer++ < 5*1000) { if (tstc()) { while ((ch = getc()) != '\n' && ch != '\r') { - if (ch == '\b') { + /* Test for backspace/delete */ + if (ch == '\b' || ch == '\177') { if (cp != cmd_line) { + cp--; + puts("\b \b"); + } + /* Test for ^x/^u (and wipe the line) */ + } else if (ch == '\030' || ch == '\025') { + while (cp != cmd_line) { cp--; puts("\b \b"); } diff -Nru a/arch/ppc/boot/prep/of1275.c b/arch/ppc/boot/prep/of1275.c --- a/arch/ppc/boot/prep/of1275.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/boot/prep/of1275.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.of1275.c 1.6 05/18/01 15:16:42 cort + * BK Id: %F% %I% %G% %U% %#% */ /* Open Firmware Client Interface */ diff -Nru a/arch/ppc/boot/prep/of1275.h b/arch/ppc/boot/prep/of1275.h --- a/arch/ppc/boot/prep/of1275.h Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/boot/prep/of1275.h Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.of1275.h 1.6 05/18/01 15:16:42 cort + * BK Id: %F% %I% %G% %U% %#% */ /* 6.3.2.1 Client interface */ diff -Nru a/arch/ppc/boot/prep/vreset.c b/arch/ppc/boot/prep/vreset.c --- a/arch/ppc/boot/prep/vreset.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/boot/prep/vreset.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.vreset.c 1.9 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * vreset.c diff -Nru a/arch/ppc/boot/sandpoint/Makefile b/arch/ppc/boot/sandpoint/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/sandpoint/Makefile Sat Jun 16 06:00:30 2001 @@ -0,0 +1,91 @@ +# arch/ppc/boot/sandpoint/Makefile +# +# Makefile for Motorola SPS Sandpoint bootloader +# +# Author: Mark A. Greer +# mgreer@mvista.com +# +# Copyright 2001 MontaVista Software Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. + +.c.s: + $(CC) $(CFLAGS) -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) -D__BOOTER__ -c -o $*.o $< +.S.s: + $(CPP) $(AFLAGS) -traditional -o $*.o $< +.S.o: + $(CC) $(AFLAGS) -traditional -c -o $*.o $< + +ZLINKFLAGS = -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00800000 + +OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \ + ../common/ns16550.o ../common/string.o +OBJCOPY_ARGS = -O elf32-powerpc +LIBS := ../lib/zlib.a + +OFFSET := ../utils/offset +SIZE := ../utils/size + +all: zImage + +../common/misc-simple.o: ../common/misc-simple.c + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ + -DZIMAGE_SIZE=0 -c -o $@ $*.c + +zvmlinux.initrd: $(OBJECTS) $(LIBS) ../images/vmlinux.gz + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ initrd` \ + -DINITRD_SIZE=`sh $(SIZE) $(OBJDUMP) $@ initrd` \ + -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ + -c -o ../common/misc-simple.o ../common/misc-simple.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +zImage: zvmlinux + mv zvmlinux ../images/$@.sandpoint + rm ../images/vmlinux.gz + +zImage.initrd: zvmlinux.initrd + mv zvmlinux.initrd ../images/$@.sandpoint + rm ../images/vmlinux.gz + +zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz +# +# build the boot loader image and then compute the offset into it +# for the kernel image +# + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ +# +# then with the offset rebuild the bootloader so we know where the kernel is +# + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ + -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ + -D__BOOTER__ \ + -c -o ../common/misc-simple.o ../common/misc-simple.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/sandpoint/head.S b/arch/ppc/boot/sandpoint/head.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/sandpoint/head.S Sat Jun 16 06:00:31 2001 @@ -0,0 +1,316 @@ +/* + * arch/ppc/boot/sandpoint/head.S + * + * Initial board bringup code for Motorola SPS Sandpoint test platform + * + * Author: Mark A. Greer + * mgreer@mvista.com + * Derived from arch/ppc/boot/pcore/head.S (mporter@mvista.com) + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include "../../kernel/ppc_defs.h" +#include "../../kernel/ppc_asm.tmpl" +#include +#include + + .text + +/* + * + * Begin at some arbitrary location in RAM or Flash + * Initialize core registers + * Configure memory controller (Not executing from RAM) + * Move the boot code to the link address (8M) + * Setup C stack + * Initialize UART + * Decompress the kernel to 0x0 + * Jump to the kernel entry + * + */ + + .globl start +start: + bl start_ + +start_: +/* + * Configure core registers + */ + + /* Establish default MSR value, exception prefix 0xFFF */ + li r3,MSR_IP|MSR_FP + mtmsr r3 + + /* Clear BATS */ + li r8,0 + mtspr DBAT0U,r8 + mtspr DBAT0L,r8 + mtspr DBAT1U,r8 + mtspr DBAT1L,r8 + mtspr DBAT2U,r8 + mtspr DBAT2L,r8 + mtspr DBAT3U,r8 + mtspr DBAT3L,r8 + mtspr IBAT0U,r8 + mtspr IBAT0L,r8 + mtspr IBAT1U,r8 + mtspr IBAT1L,r8 + mtspr IBAT2U,r8 + mtspr IBAT2L,r8 + mtspr IBAT3U,r8 + mtspr IBAT3L,r8 + isync + sync + sync + + /* Set segment registers */ + lis r8, 0x8000 + isync + mtsr SR0,r8 + mtsr SR1,r8 + mtsr SR2,r8 + mtsr SR3,r8 + mtsr SR4,r8 + mtsr SR5,r8 + mtsr SR6,r8 + mtsr SR7,r8 + mtsr SR8,r8 + mtsr SR9,r8 + mtsr SR10,r8 + mtsr SR11,r8 + mtsr SR12,r8 + mtsr SR13,r8 + mtsr SR14,r8 + mtsr SR15,r8 + isync + sync + sync + + /* Disable L1 icache/dcache */ + li r4,0x0000 + isync + mtspr HID0,r4 + sync + isync + + /* Flash Invalidate L1 icache/dcache */ + ori r4,r4,0x8000 + ori r8,r4,0x0800 + isync + mtspr HID0,r8 + sync + isync + + /* Older cores need to manually clear ICFI bit */ + mtspr HID0,r4 + sync + isync + +/* check if we need to relocate ourselves to the link addr or were we + loaded there to begin with -- Cort */ + lis r4,start@h + ori r4,r4,start@l + mflr r3 + subi r3,r3,4 /* we get the nip, not the ip of the branch */ + mr r8,r3 + cmp 0,r3,r4 + bne 1010f +/* compute size of whole image in words. this should be moved to + * start_ldr() -- Cort + */ + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* round up */ + sub r5,r5,r4 + srwi r5,r5,2 + mr r7,r5 + b start_ldr +1010: +/* + * no matter where we're loaded, move ourselves to -Ttext address + */ +relocate: + mflr r3 /* Compute code bias */ + subi r3,r3,4 + mr r8,r3 + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* Round up - just in case */ + sub r5,r5,r4 /* Compute # longwords to move */ + srwi r5,r5,2 + mtctr r5 + mr r7,r5 + li r6,0 + subi r3,r3,4 /* Set up for loop */ + subi r4,r4,4 +00: lwzu r5,4(r3) + stwu r5,4(r4) + xor r6,r6,r5 + bdnz 00b + lis r3,start_ldr@h + ori r3,r3,start_ldr@l + mtlr r3 /* Easiest way to do an absolute jump */ + blr +start_ldr: +/* Clear all of BSS and set up stack for C calls */ + lis r3,edata@h + ori r3,r3,edata@l + lis r4,end@h + ori r4,r4,end@l + subi r3,r3,4 + subi r4,r4,4 + li r0,0 +50: stwu r0,4(r3) + cmp 0,r3,r4 + bne 50b +90: mr r9,r1 /* Save old stack pointer (in case it matters) */ + lis r1,.stack@h + ori r1,r1,.stack@l + addi r1,r1,4096*2 + subi r1,r1,256 + li r2,0x000F /* Mask pointer to 16-byte boundary */ + andc r1,r1,r2 + +/* + * Exec kernel loader + */ + mr r3,r8 /* Load point */ + mr r4,r7 /* Program length */ + mr r5,r6 /* Checksum */ + bl decompress_kernel + + lis r6,cmd_line@h + ori r6,r6,cmd_line@l + lwz r6, 0(r6) + subi r7,r6,1 +00: lbzu r2,1(r7) + cmpi 0,r2,0 + bne 00b + + /* r4,r5 have initrd_start, size */ + lis r2,initrd_start@h + ori r2,r2,initrd_start@l + lwz r4,0(r2) + lis r2,initrd_end@h + ori r2,r2,initrd_end@l + lwz r5,0(r2) + + li r9,0x4 + mtlr r9 + li r9,0 + + /* + * Jump to kernel start + */ + blr + +hang: + b hang + +/* + * Delay for a number of microseconds + * -- Use the BUS timer (assumes 66MHz) + */ + .globl udelay +udelay: + mfspr r4,PVR + srwi r4,r4,16 + cmpi 0,r4,1 /* 601 ? */ + bne .udelay_not_601 +00: li r0,86 /* Instructions / microsecond? */ + mtctr r0 +10: addi r0,r0,0 /* NOP */ + bdnz 10b + subic. r3,r3,1 + bne 00b + blr + +.udelay_not_601: + mulli r4,r3,1000 /* nanoseconds */ + addi r4,r4,59 + li r5,60 + divw r4,r4,r5 /* BUS ticks */ +1: mftbu r5 + mftb r6 + mftbu r7 + cmp 0,r5,r7 + bne 1b /* Get [synced] base time */ + addc r9,r6,r4 /* Compute end time */ + addze r8,r5 +2: mftbu r5 + cmp 0,r5,r8 + blt 2b + bgt 3f + mftb r6 + cmp 0,r6,r9 + blt 2b +3: blr + +.globl _get_HID0 +_get_HID0: + mfspr r3,HID0 + blr + +.globl _put_HID0 +_put_HID0: + mtspr HID0,r3 + blr + +.globl _get_MSR +_get_MSR: + mfmsr r3 + blr + +.globl _put_MSR +_put_MSR: + mtmsr r3 + blr + +/* + * Flush instruction cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_instruction_cache) + mflr r5 + bl flush_data_cache + mfspr r3,HID0 /* Caches are controlled by this register */ + li r4,0 + ori r4,r4,(HID0_ICE|HID0_ICFI) + or r3,r3,r4 /* Need to enable+invalidate to clear */ + mtspr HID0,r3 + andc r3,r3,r4 + ori r3,r3,HID0_ICE /* Enable cache */ + mtspr HID0,r3 + mtlr r5 + blr + +#define NUM_CACHE_LINES 128*8 +#define CACHE_LINE_SIZE 32 +#define cache_flush_buffer 0x1000 + +/* + * Flush data cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_data_cache) + lis r3,cache_flush_buffer@h + ori r3,r3,cache_flush_buffer@l + li r4,NUM_CACHE_LINES + mtctr r4 +00: lwz r4,0(r3) + addi r3,r3,CACHE_LINE_SIZE /* Next line, please */ + bdnz 00b +10: blr + .comm .stack,4096*2,4 + diff -Nru a/arch/ppc/boot/spruce/Makefile b/arch/ppc/boot/spruce/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/spruce/Makefile Sat Jun 16 06:00:30 2001 @@ -0,0 +1,101 @@ +# arch/ppc/spruceboot/Makefile +# +# Makefile for IBM Spruce reference platform +# +# Author: Johnnie Peters +# jpeters@mvista.com +# +# Cleanups: Tom Rini +# trini@mvista.com +# +# Copyright 2000-2001 MontaVista Software Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED +# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN +# NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +# 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., +# 675 Mass Ave, Cambridge, MA 02139, USA. + +.c.s: + $(CC) $(CFLAGS) -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) -c -o $*.o $< +.S.s: + $(CPP) $(AFLAGS) -traditional -o $*.o $< +.S.o: + $(CC) $(AFLAGS) -traditional -c -o $*.o $< + +TFTPIMAGE := /tftpboot/zImage.spruce + +ZLINKFLAGS := -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00800000 + +OBJECTS := head.o misc.o ../common/misc-common.o ../common/string.o +ifdef CONFIG_SERIAL_CONSOLE +OBJECTS += ../common/ns16550.o +endif + +LIBS := ../lib/zlib.a +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJCOPY_ARGS = -O elf32-powerpc +MKEVIMG = ../utils/mkevimg -l -v +MKIRIMG = ../utils/mkirimg + +all: zImage + +zImage.initrd: zvmlinux.initrd + $(OBJDUMP) --syms zvmlinux.initrd | grep irSectStart > irSectStart.txt + $(MKIRIMG) zvmlinux.initrd zvmlinux.out irSectStart.txt + $(MKEVIMG) zvmlinux.out ../images/zImage.spruce.initrd + rm -f zvmlinux.out irSectStart.txt zvmlinux.initrd + +zImage: zvmlinux + $(OBJDUMP) --syms zvmlinux | grep irSectStart > irSectStart.txt + $(MKIRIMG) zvmlinux zvmlinux.out irSectStart.txt + $(MKEVIMG) zvmlinux.out ../images/zImage.spruce + rm -f zvmlinux.out irSectStart.txt zvmlinux + + +zvmlinux.initrd: $(OBJECTS) $(LIBS) ../images/vmlinux.gz + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +znetboot: zImage + cp ../images/zImage.spruce $(TFTPIMAGE) + +znetboot.initrd: zImage.initrd + cp ../images/zImage.spruce.initrd $(TFTPIMAGE) + +floppy: $(TOPDIR)/vmlinux zImage + dd if=zImage of=/dev/fd0H1440 bs=64b + +clean: + rm -f irSectStart.txt + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/spruce/head.S b/arch/ppc/boot/spruce/head.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/spruce/head.S Sat Jun 16 06:00:31 2001 @@ -0,0 +1,293 @@ +/* + * arch/ppc/boot/spruce/head.S + * + * Initial board bringup code for IBM Spruce + * + * Author: Matt Porter and Johnnie Peters + * mporter@mvista.com + * jpeters@mvista.com + * + * Derived from arch/ppc/boot/pmon/head.S + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "../../kernel/ppc_defs.h" +#include "../../kernel/ppc_asm.tmpl" +#include +#include + +/* This is a kludge for the bootloader */ +#define _IO_BASE 0x80000000 + +.text + +/* + * Move the boot code to the link address (8M) + * Setup C stack + * Initialize UART + * Decompress the kernel to 0x0 + * Jump to the kernel entry + */ + + .globl start +start: + bl start_ + +start_: + /* Disable and flash the L1 Cache */ + mfspr r3,HID0 + ori r3,r3,(HID0_ICFI|HID0_DCI) + andi. r3,r3,0x3fff + mtspr HID0,r3 + sync + isync + + /* Disable and flush L2 Cache */ + mfspr r3,L2CR + oris r3,r3,0x20 + andis. r3,r3,0x7fff + mtspr L2CR,r3 + sync + isync + + /* Trun the data cache flush assist bit back off */ + mfspr r3,HID0 + andi. r3,r3,0x3fbf + mtspr HID0,r3 + sync + isync + + /* check if we need to relocate ourselves to the link addr or were we + loaded there to begin with -- Cort */ + lis r4,start@h + ori r4,r4,start@l + mflr r3 + subi r3,r3,4 /* we get the nip, not the ip of the branch */ + mr r8,r3 + cmp 0,r3,r4 + bne 1010f +/* compute size of whole image in words. this should be moved to + * start_ldr() -- Cort + */ + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* round up */ + sub r5,r5,r4 + srwi r5,r5,2 + mr r7,r5 + b start_ldr +1010: +/* + * no matter where we're loaded, move ourselves to -Ttext address + */ +relocate: + mflr r3 /* Compute code bias */ + subi r3,r3,4 + mr r8,r3 + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* Round up - just in case */ + sub r5,r5,r4 /* Compute # longwords to move */ + srwi r5,r5,2 + mtctr r5 + mr r7,r5 + li r6,0 + subi r3,r3,4 /* Set up for loop */ + subi r4,r4,4 +00: lwzu r5,4(r3) + stwu r5,4(r4) + xor r6,r6,r5 + bdnz 00b + lis r3,start_ldr@h + ori r3,r3,start_ldr@l + mtlr r3 /* Easiest way to do an absolute jump */ + blr +start_ldr: +/* Clear all of BSS and set up stack for C calls */ + lis r3,edata@h + ori r3,r3,edata@l + lis r4,end@h + ori r4,r4,end@l + subi r3,r3,4 + subi r4,r4,4 + li r0,0 +50: stwu r0,4(r3) + cmp 0,r3,r4 + bne 50b +90: mr r9,r1 /* Save old stack pointer (in case it matters) */ + lis r1,.stack@h + ori r1,r1,.stack@l + addi r1,r1,4096*2 + subi r1,r1,256 + li r2,0x000F /* Mask pointer to 16-byte boundary */ + andc r1,r1,r2 + +/* + * Exec kernel loader + */ + mr r3,r8 /* Load point */ + mr r4,r7 /* Program length */ + mr r5,r6 /* Checksum */ + bl decompress_kernel + + lis r6,cmd_line@h + ori r6,r6,cmd_line@l + lwz r6, 0(r6) + subi r7,r6,1 +00: lbzu r2,1(r7) + cmpi 0,r2,0 + bne 00b + + /* r4,r5 have initrd_start, size */ + lis r2,initrd_start@h + ori r2,r2,initrd_start@l + lwz r4,0(r2) + lis r2,initrd_end@h + ori r2,r2,initrd_end@l + lwz r5,0(r2) + + li r9,0x4 + mtlr r9 + li r9,0 + stb r20,0(r9) /* Save MSIZ reg for kernel */ + + /* + * Jump to kernel start + */ + blr + +hang: + b hang + +/* + * Delay for a number of microseconds + * -- Use the BUS timer (assumes 66MHz) + */ + .globl udelay +udelay: + mfspr r4,PVR + srwi r4,r4,16 + cmpi 0,r4,1 /* 601 ? */ + bne .udelay_not_601 +00: li r0,86 /* Instructions / microsecond? */ + mtctr r0 +10: addi r0,r0,0 /* NOP */ + bdnz 10b + subic. r3,r3,1 + bne 00b + blr + +.udelay_not_601: + mulli r4,r3,1000 /* nanoseconds */ + addi r4,r4,59 + li r5,60 + divw r4,r4,r5 /* BUS ticks */ +1: mftbu r5 + mftb r6 + mftbu r7 + cmp 0,r5,r7 + bne 1b /* Get [synced] base time */ + addc r9,r6,r4 /* Compute end time */ + addze r8,r5 +2: mftbu r5 + cmp 0,r5,r8 + blt 2b + bgt 3f + mftb r6 + cmp 0,r6,r9 + blt 2b +3: blr + +.globl _get_HID0 +_get_HID0: + mfspr r3,HID0 + blr + +.globl _put_HID0 +_put_HID0: + mtspr HID0,r3 + blr + +.globl _get_MSR +_get_MSR: + mfmsr r3 + blr + +.globl _put_MSR +_put_MSR: + mtmsr r3 + blr + + +.globl _get_L2CR +_get_L2CR: + mfspr r3,L2CR + blr + +.globl _put_L2CR +_put_L2CR: + mtspr L2CR,r3 + blr + +/* + * Flush instruction cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_instruction_cache) + mflr r5 + bl flush_data_cache + mfspr r3,HID0 /* Caches are controlled by this register */ + li r4,0 + ori r4,r4,(HID0_ICE|HID0_ICFI) + or r3,r3,r4 /* Need to enable+invalidate to clear */ + mtspr HID0,r3 + andc r3,r3,r4 + ori r3,r3,HID0_ICE /* Enable cache */ + mtspr HID0,r3 + mtlr r5 + blr + +#define NUM_CACHE_LINES 128*8 +#define CACHE_LINE_SIZE 32 +#define cache_flush_buffer 0x1000 + +/* + * Flush data cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_data_cache) + lis r3,cache_flush_buffer@h + ori r3,r3,cache_flush_buffer@l + li r4,NUM_CACHE_LINES + mtctr r4 +00: lwz r4,0(r3) + addi r3,r3,CACHE_LINE_SIZE /* Next line, please */ + bdnz 00b +10: blr + .comm .stack,4096*2,4 + diff -Nru a/arch/ppc/boot/spruce/misc.c b/arch/ppc/boot/spruce/misc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/spruce/misc.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,438 @@ +/* + * arch/ppc/boot/spruce/misc.c + * + * Misc. bootloader code for IBM Spruce reference platform + * + * Author: Johnnie Peters + * jpeters@mvista.com + * + * Derived from arch/ppc/boot/prep/misc.c + * + * Copyright 2000-2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include "zlib.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +unsigned long com_port; + +unsigned int irSectStart = 0xdeadbeaf; + +unsigned int imageSect_start = 0; +unsigned int imageSect_size = 0; +unsigned int initrdSect_start = 0; +unsigned int initrdSect_size = 0; + +char *avail_ram; +char *end_avail; +extern char _end[]; + +#ifdef CONFIG_CMDLINE +#define CMDLINE CONFIG_CMDLINE +#else +#define CMDLINE "" +#endif +char cmd_preset[] = CMDLINE; +char cmd_buf[256]; +char *cmd_line = cmd_buf; + +unsigned long initrd_start = 0, initrd_end = 0; +char *zimage_start; +int zimage_size; + +extern void udelay(long); +extern void puts(const char *); +extern void putc(const char c); +extern void puthex(unsigned long val); +extern void gunzip(void *, int, unsigned char *, int *); + +volatile struct NS16550 * serial_init(int); + +/* PCI configuration space access routines. */ +unsigned int *pci_config_address = (unsigned int *)SPRUCE_PCI_CONFIG_ADDR; +unsigned char *pci_config_data = (unsigned char *)SPRUCE_PCI_CONFIG_DATA; + +void cpc700_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned char *val) +{ + out_le32(pci_config_address, + (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); + + *val= (in_le32((unsigned *)pci_config_data) >> (8 * (offset & 3))) & 0xff; +} + +void cpc700_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned char val) +{ + out_le32(pci_config_address, + (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); + + out_8(pci_config_data + (offset&3), val); +} + +void cpc700_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned short *val) +{ + out_le32(pci_config_address, + (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); + + *val= in_le16((unsigned short *)(pci_config_data + (offset&3))); +} + +void cpc700_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned short val) +{ + out_le32(pci_config_address, + (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); + + out_le16((unsigned short *)(pci_config_data + (offset&3)), val); +} + +void cpc700_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned int *val) +{ + out_le32(pci_config_address, + (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); + + *val= in_le32((unsigned *)pci_config_data); +} + +void cpc700_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned int val) +{ + out_le32(pci_config_address, + (((bus & 0xff)<<16) | (dev_fn<<8) | (offset&0xfc) | 0x80000000)); + + out_le32((unsigned *)pci_config_data, val); +} + +unsigned long isa_io_base = SPRUCE_ISA_IO_BASE; + +#define PCNET32_WIO_RDP 0x10 +#define PCNET32_WIO_RAP 0x12 +#define PCNET32_WIO_RESET 0x14 + +#define PCNET32_DWIO_RDP 0x10 +#define PCNET32_DWIO_RAP 0x14 +#define PCNET32_DWIO_RESET 0x18 + +/* Processor interface config register access */ +#define PIFCFGADDR 0xff500000 +#define PIFCFGDATA 0xff500004 + +#define PLBMIFOPT 0x18 /* PLB Master Interface Options */ +#define PLBMTLSA1 0x20 /* PLB Master Byte Swap Region 1 Starting Address */ +#define PLBMTLEA1 0x24 /* PLB Master Byte Swap Region 1 Ending Address */ + +#define MEM_MBEN 0x24 +#define MEM_TYPE 0x28 +#define MEM_B1SA 0x3c +#define MEM_B1EA 0x5c +#define MEM_B2SA 0x40 +#define MEM_B2EA 0x60 + +unsigned long +decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) +{ + int loop; + int timer; + char *cp, ch; + unsigned long TotalMemory; + int csr0; + int csr_id; + int *mem_addr = (int *)0xff500008; + int *mem_data = (int *)0xff50000c; + int mem_size = 0; + unsigned long mem_mben; + unsigned long mem_type; + unsigned long mem_start; + unsigned long mem_end; + int *pif_addr = (int *)0xff500000; + int *pif_data = (int *)0xff500004; + int pci_devfn; + int found_multi = 0; + unsigned short vendor; + unsigned short device; + unsigned short command; + unsigned char header_type; + unsigned int bar0; + + /* Initialize the serial console port */ + com_port = (unsigned long *)serial_init(0); + + /* Set the PCI memory space mapping to be little endian */ + *pif_addr = PLBMTLSA1; + *pif_data = 0x80000000; + + *pif_addr = PLBMTLEA1; + *pif_data = 0xff4fffff; + + *pif_addr = PLBMIFOPT; + *pif_data = 0x80000000; + + /* Get the size of memory from the memory controller. */ + *mem_addr = MEM_MBEN; + asm("isync"); + mem_mben = *mem_data; + asm("isync"); + for(loop = 0; loop < 1000; loop++); + + *mem_addr = MEM_TYPE; + asm("isync"); + mem_type = *mem_data; + asm("isync"); + for(loop = 0; loop < 1000; loop++); + + *mem_addr = MEM_TYPE; + /* Confirm bank 1 has DRAM memory */ + if ((mem_mben & 0x40000000) && + ((mem_type & 0x30000000) == 0x10000000)) { + *mem_addr = MEM_B1SA; + asm("isync"); + mem_start = *mem_data; + asm("isync"); + for(loop = 0; loop < 1000; loop++); + + *mem_addr = MEM_B1EA; + asm("isync"); + mem_end = *mem_data; + asm("isync"); + for(loop = 0; loop < 1000; loop++); + + mem_size = mem_end - mem_start + 0x100000; + } + + /* Confirm bank 2 has DRAM memory */ + if ((mem_mben & 0x20000000) && + ((mem_type & 0xc000000) == 0x4000000)) { + *mem_addr = MEM_B2SA; + asm("isync"); + mem_start = *mem_data; + asm("isync"); + for(loop = 0; loop < 1000; loop++); + + *mem_addr = MEM_B2EA; + asm("isync"); + mem_end = *mem_data; + asm("isync"); + for(loop = 0; loop < 1000; loop++); + + mem_size += mem_end - mem_start + 0x100000; + } + + /* Search out and turn off the PcNet ethernet boot device. */ + for (pci_devfn = 1; pci_devfn < 0xff; pci_devfn++) { + if (PCI_FUNC(pci_devfn) && !found_multi) + continue; + + cpc700_pcibios_read_config_byte(0, pci_devfn, + PCI_HEADER_TYPE, &header_type); + + if (!PCI_FUNC(pci_devfn)) + found_multi = header_type & 0x80; + + cpc700_pcibios_read_config_word(0, pci_devfn, PCI_VENDOR_ID, + &vendor); + + if (vendor != 0xffff) { + cpc700_pcibios_read_config_word(0, pci_devfn, + PCI_DEVICE_ID, &device); + + /* If this PCI device is the Lance PCNet board then turn it off */ + if ((vendor == PCI_VENDOR_ID_AMD) && + (device == PCI_DEVICE_ID_AMD_LANCE)) { + + /* Turn on I/O Space on the board. */ + cpc700_pcibios_read_config_word(0, pci_devfn, + PCI_COMMAND, &command); + command |= 0x1; + cpc700_pcibios_write_config_word(0, pci_devfn, + PCI_COMMAND, command); + + /* Get the I/O space address */ + cpc700_pcibios_read_config_dword(0, pci_devfn, + PCI_BASE_ADDRESS_0, &bar0); + bar0 &= 0xfffffffe; + + /* Reset the PCNet Board */ + inl (bar0+PCNET32_DWIO_RESET); + inw (bar0+PCNET32_WIO_RESET); + + /* First do a work oriented read of csr0. If the value is + * 4 then this is the correct mode to access the board. + * If not try a double word ortiented read. + */ + outw(0, bar0 + PCNET32_WIO_RAP); + csr0 = inw(bar0 + PCNET32_WIO_RDP); + + if (csr0 == 4) { + /* Check the Chip id register */ + outw(88, bar0 + PCNET32_WIO_RAP); + csr_id = inw(bar0 + PCNET32_WIO_RDP); + + if (csr_id) { + /* This is the valid mode - set the stop bit */ + outw(0, bar0 + PCNET32_WIO_RAP); + outw(csr0, bar0 + PCNET32_WIO_RDP); + } + } else { + outl(0, bar0 + PCNET32_DWIO_RAP); + csr0 = inl(bar0 + PCNET32_DWIO_RDP); + if (csr0 == 4) { + /* Check the Chip id register */ + outl(88, bar0 + PCNET32_WIO_RAP); + csr_id = inl(bar0 + PCNET32_WIO_RDP); + + if (csr_id) { + /* This is the valid mode - set the stop bit*/ + outl(0, bar0 + PCNET32_WIO_RAP); + outl(csr0, bar0 + PCNET32_WIO_RDP); + } + } + } + } + } + } + + /* Assume 128MB on the SBS K2 */ + TotalMemory = 0x08000000; + + /* assume the chunk below 8M is free */ + end_avail = (char *)0x00800000; + + /* + * Reveal where we were loaded at and where we + * were relocated to. + */ + puts("loaded at: "); puthex(load_addr); + puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); + zimage_start = (char *)imageSect_start; + zimage_size = imageSect_size; + + if (initrdSect_start) + initrd_start = initrdSect_start; + else + initrd_start = 0; + + initrd_end = initrd_start + initrdSect_size; + + if (initrd_start) { + puts("initrd at: "); puthex(initrd_start); + puts(" "); puthex(initrd_end); puts("\n"); + } + + avail_ram = (char *)0x00400000; + end_avail = (char *)0x00800000; + puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); + puthex((unsigned long)end_avail); puts("\n"); + + /* Display standard Linux/PPC boot prompt for kernel args */ + puts("\nLinux/PPC load: "); + timer = 0; + cp = cmd_line; + memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); + while ( *cp ) putc(*cp++); + while (timer++ < 5*1000) { + if (tstc()) { + while ((ch = getc()) != '\n' && ch != '\r') { + if (ch == '\b') { + if (cp != cmd_line) { + cp--; + puts("\b \b"); + } + } else { + *cp++ = ch; + putc(ch); + } + } + break; /* Exit 'timer' loop */ + } + udelay(1000); /* 1 msec */ + } + *cp = 0; + puts("\n"); + + puts("Uncompressing Linux..."); + + gunzip(0, 0x400000, zimage_start, &zimage_size); + + puts("done.\n"); + + { + struct bi_record *rec; + + rec = (struct bi_record *)_ALIGN((ulong)zimage_size + + (1<<20)-1,(1<<20)); + + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + memcpy( (void *)rec->data, "spruceboot", 11); + rec->size = sizeof(struct bi_record) + 10 + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = _MACH_spruce; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MEMSIZE; + rec->data[0] = mem_size; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_CMD_LINE; + memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); + rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; + rec = (struct bi_record *)((ulong)rec + rec->size); + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + } + + puts("Now booting the kernel\n"); + + return 0; +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -Nru a/arch/ppc/boot/tree/Makefile b/arch/ppc/boot/tree/Makefile --- a/arch/ppc/boot/tree/Makefile Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/boot/tree/Makefile Sat Jun 16 06:00:20 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.5 05/18/01 06:20:29 patch +# BK Id: %F% %I% %G% %U% %#% # # # Module name: Makefile @@ -26,12 +26,13 @@ GZIP = gzip -vf9 RM = rm -f -MKEVIMG = ../utils/mkevimg -l +MKEVIMG = ../utils/mkevimg -l -c MKIRIMG = ../utils/mkirimg +CFLAGS += -I$(TOPDIR)/drivers/net LD_ARGS = -e _start -T ld.script -Ttext 0x00200000 -Bstatic OBJS = ../common/crt0.o main.o misc.o irSect.o ../common/string.o \ - ../common/misc-common.o + ../common/misc-common.o ../common/ns16550.o LIBS = ../lib/zlib.a treeboot: $(OBJS) $(LIBS) ld.script diff -Nru a/arch/ppc/boot/tree/irSect.c b/arch/ppc/boot/tree/irSect.c --- a/arch/ppc/boot/tree/irSect.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/boot/tree/irSect.c Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.irSect.c 1.6 05/18/01 15:17:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * diff -Nru a/arch/ppc/boot/tree/irSect.h b/arch/ppc/boot/tree/irSect.h --- a/arch/ppc/boot/tree/irSect.h Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/boot/tree/irSect.h Sat Jun 16 06:00:24 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.irSect.h 1.6 05/18/01 15:17:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * diff -Nru a/arch/ppc/boot/tree/main.c b/arch/ppc/boot/tree/main.c --- a/arch/ppc/boot/tree/main.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/boot/tree/main.c Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.main.c 1.7 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (c) 1997 Paul Mackerras @@ -12,6 +12,7 @@ * frank_rowand@mvista.com or source@mvista.com * debbie_chu@mvista.com * + * * Module name: main.c * * Description: @@ -74,16 +75,6 @@ #define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) -#define stringify(s) tostring(s) -#define tostring(s) #s - -#define mtdcr(rn, v) asm volatile("mtdcr " stringify(rn) ",%0" : : "r" (v)) -#define mfdcr(rn) ({unsigned int rval; \ - asm volatile("mfdcr %0," stringify(rn) \ - : "=r" (rval)); rval;}) -#define DCRN_MALCR 0x180 /* MAL Configuration */ -#define MALCR_SR 0x80000000 /* Software Reset */ - /* Global Variables */ /* Needed by zalloc and zfree for allocating memory */ @@ -91,15 +82,11 @@ char *avail_ram; /* Indicates start of RAM available for heap */ char *end_avail; /* Indicates end of RAM available for heap */ -bd_t board_info; - -/* - * XXX - Until either the IBM boot ROM provides a way of passing arguments to - * the program it launches or until I/O is working in the boot loader, - * this is a good spot to pass in command line arguments to the kernel - * (e.g. console=tty0). - */ +/* Needed for serial I/O. +*/ +extern unsigned long *com_port; +bd_t board_info; /* ** The bootrom may change bootrom_cmdline to point to a buffer in the @@ -116,13 +103,15 @@ /* Function Prototypes */ -extern void *zalloc(void *x, unsigned items, unsigned size); +extern void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp); -/* serial I/O functions. - * These should have generic names, although this is similar to 16550.... - */ -static volatile unsigned char *uart0_lsr = (unsigned char *)0xef600305; -static volatile unsigned char *uart0_xcvr = (unsigned char *)0xef600300; +void +kick_watchdog(void) +{ +#ifdef CONFIG_405GP + mtspr(SPRN_TSR, (TSR_ENW | TSR_WIS)); +#endif +} void serial_putc(void *unused, unsigned char c) @@ -144,7 +133,6 @@ return ((*uart0_lsr & LSR_DR) != 0); } - void start(void) { void *options; @@ -156,40 +144,34 @@ bd_t *(*get_board_info)(void) = (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR); bd_t *bip = NULL; - volatile unsigned long *em0mr0 = (long *)0xEF600800; /* ftr fixup */ + com_port = (struct NS16550 *)serial_init(0); -#if defined(CONFIG_WALNUT) - /* turn off ethernet */ +#ifdef CONFIG_405GP + /* turn off on-chip ethernet */ /* This is to fix a problem with early walnut bootrom. */ - - mtdcr(DCRN_MALCR, MALCR_SR); /* 1st reset MAL */ - - while (mfdcr(DCRN_MALCR) & MALCR_SR) {}; /* wait for the reset */ - - *em0mr0 = 0x20000000; /* then reset EMAC */ -#endif - - -#if 0 - /* ftr revisit - remove printf()s */ - - printf("\n\nbootrom_cmdline = >%s<\n\n", bootrom_cmdline); - if (*bootrom_cmdline != '\0') { - printf("bootrom_cmdline != NULL, copying it into cmdline\n\n"); - *treeboot_bootrom_cmdline = '\0'; - strcat(treeboot_bootrom_cmdline, bootrom_cmdline); - cmdline = treeboot_bootrom_cmdline; + + { + /* Physical mapping of ethernet register space. */ + static struct ppc405_enet_regs *ppc405_enet_regp = + (struct ppc405_enet_regs *)PPC405_EM0_REG_ADDR; + + mtdcr(DCRN_MALCR, MALCR_MMSR); /* 1st reset MAL */ + + while (mfdcr(DCRN_MALCR) & MALCR_MMSR) {}; /* wait for the reset */ + + ppc405_enet_regp->em0mr0 = 0x20000000; /* then reset EMAC */ } #endif - if ((bip = get_board_info()) != NULL) memcpy(&board_info, bip, sizeof(bd_t)); /* Init RAM disk (initrd) section */ + kick_watchdog(); + if (initrdSect_start != 0 && (initrd_size = initrdSect_size) != 0) { initrd_start = (RAM_END - initrd_size) & ~0xFFF; @@ -208,6 +190,8 @@ /* Linux kernel image section */ + kick_watchdog(); + im = (unsigned char *)(imageSect_start); len = imageSect_size; dst = (void *)PROG_START; @@ -233,6 +217,7 @@ memmove(dst, im, len); } + kick_watchdog(); flush_cache(dst, len); diff -Nru a/arch/ppc/boot/tree/misc.S b/arch/ppc/boot/tree/misc.S --- a/arch/ppc/boot/tree/misc.S Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/boot/tree/misc.S Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.misc.S 1.7 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Paul Mackerras 1997. diff -Nru a/arch/ppc/boot/utils/addnote.c b/arch/ppc/boot/utils/addnote.c --- a/arch/ppc/boot/utils/addnote.c Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/boot/utils/addnote.c Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.addnote.c 1.7 05/18/01 15:17:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Program to hack in a PT_NOTE program header entry in an ELF file. diff -Nru a/arch/ppc/boot/utils/hack-coff.c b/arch/ppc/boot/utils/hack-coff.c --- a/arch/ppc/boot/utils/hack-coff.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/boot/utils/hack-coff.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.hack-coff.c 1.8 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * hack-coff.c - hack the header of an xcoff file to fill in diff -Nru a/arch/ppc/boot/utils/mkbugboot.c b/arch/ppc/boot/utils/mkbugboot.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/mkbugboot.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,188 @@ +/* + * arch/ppc/pp3boot/mkbugboot.c + * + * Makes a Motorola PPCBUG ROM bootable image which can be flashed + * into one of the FLASH banks on a Motorola PowerPlus board. + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#define ELF_HEADER_SIZE 65536 + +#include +#include +#include +#include +#include +#include + +#ifdef __i386__ +#define cpu_to_be32(x) le32_to_cpu(x) +#define cpu_to_be16(x) le16_to_cpu(x) +#else +#define cpu_to_be32(x) (x) +#define cpu_to_be16(x) (x) +#endif + +#define cpu_to_le32(x) le32_to_cpu((x)) +unsigned long le32_to_cpu(unsigned long x) +{ + return (((x & 0x000000ffU) << 24) | + ((x & 0x0000ff00U) << 8) | + ((x & 0x00ff0000U) >> 8) | + ((x & 0xff000000U) >> 24)); +} + +#define cpu_to_le16(x) le16_to_cpu((x)) +unsigned short le16_to_cpu(unsigned short x) +{ + return (((x & 0x00ff) << 8) | + ((x & 0xff00) >> 8)); +} + +/* size of read buffer */ +#define SIZE 0x1000 + +/* typedef long int32_t; */ +typedef unsigned long uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; + +/* PPCBUG ROM boot header */ +typedef struct bug_boot_header { + uint8_t magic_word[4]; /* "BOOT" */ + uint32_t entry_offset; /* Offset from top of header to code */ + uint32_t routine_length; /* Length of code */ + uint8_t routine_name[8]; /* Name of the boot code */ +} bug_boot_header_t; + +#define HEADER_SIZE sizeof(bug_boot_header_t) + +uint32_t copy_image(int32_t in_fd, int32_t out_fd) +{ + uint8_t buf[SIZE]; + int n; + uint32_t image_size = 0; + uint8_t zero = 0; + + lseek(in_fd, ELF_HEADER_SIZE, SEEK_SET); + + /* Copy an image while recording its size */ + while ( (n = read(in_fd, buf, SIZE)) > 0 ) + { + image_size = image_size + n; + write(out_fd, buf, n); + } + + /* BUG romboot requires that our size is divisible by 2 */ + /* align image to 2 byte boundary */ + if (image_size % 2) + { + image_size++; + write(out_fd, &zero, 1); + } + + return image_size; +} + +void write_bugboot_header(int32_t out_fd, uint32_t boot_size) +{ + uint8_t header_block[HEADER_SIZE]; + bug_boot_header_t *bbh = (bug_boot_header_t *)&header_block[0]; + + bzero(header_block, HEADER_SIZE); + + /* Fill in the PPCBUG ROM boot header */ + strncpy(bbh->magic_word, "BOOT", 4); /* PPCBUG magic word */ + bbh->entry_offset = cpu_to_be32(HEADER_SIZE); /* Entry address */ + bbh->routine_length= cpu_to_be32(HEADER_SIZE+boot_size+2); /* Routine length */ + strncpy(bbh->routine_name, "LINUXROM", 8); /* Routine name */ + + /* Output the header and bootloader to the file */ + write(out_fd, header_block, HEADER_SIZE); +} + +uint16_t calc_checksum(int32_t bug_fd) +{ + uint32_t checksum_var = 0; + uint8_t buf[2]; + int n; + + /* Checksum loop */ + while ( (n = read(bug_fd, buf, 2) ) ) + { + checksum_var = checksum_var + *(uint16_t *)buf; + + /* If we carry out, mask it and add one to the checksum */ + if (checksum_var >> 16) + checksum_var = (checksum_var & 0x0000ffff) + 1; + } + + return checksum_var; +} + +int main(int argc, char *argv[]) +{ + int32_t image_fd, bugboot_fd; + int argptr = 1; + uint32_t kernel_size = 0; + uint16_t checksum = 0; + uint8_t bugbootname[256]; + + if ( (argc != 3) ) + { + fprintf(stderr, "usage: %s \n",argv[0]); + exit(-1); + } + + /* Get file args */ + + /* kernel image file */ + if ((image_fd = open( argv[argptr] , 0)) < 0) + exit(-1); + argptr++; + + /* bugboot file */ + if ( !strcmp( argv[argptr], "-" ) ) + bugboot_fd = 1; /* stdout */ + else + if ((bugboot_fd = creat( argv[argptr] , 0755)) < 0) + exit(-1); + else + strcpy(bugbootname, argv[argptr]); + argptr++; + + /* Set file position after ROM header block where zImage will be written */ + lseek(bugboot_fd, HEADER_SIZE, SEEK_SET); + + /* Copy kernel image into bugboot image */ + kernel_size = copy_image(image_fd, bugboot_fd); + close(image_fd); + + /* Set file position to beginning where header/romboot will be written */ + lseek(bugboot_fd, 0, SEEK_SET); + + /* Write out BUG header/romboot */ + write_bugboot_header(bugboot_fd, kernel_size); + + /* Close bugboot file */ + close(bugboot_fd); + + /* Reopen it as read/write */ + bugboot_fd = open(bugbootname, O_RDWR); + + /* Calculate checksum */ + checksum = calc_checksum(bugboot_fd); + + /* Write out the calculated checksum */ + write(bugboot_fd, &checksum, 2); + + return 0; +} diff -Nru a/arch/ppc/boot/utils/mkevimg b/arch/ppc/boot/utils/mkevimg --- a/arch/ppc/boot/utils/mkevimg Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/boot/utils/mkevimg Sat Jun 16 06:00:16 2001 @@ -23,7 +23,8 @@ # unsigned long num_512blocks; Size, rounded-up, in 512 byte blocks # unsigned long debug_flag; Run the debugger or image after load # unsigned long entry_point; The image address to jump to after load -# unsigned long reserved[3]; +# unsigned long checksum; 32 bit checksum including header +# unsigned long reserved[2]; # } boot_block_t; # # @@ -61,6 +62,7 @@ } if ($status != 1) { + print(" -c Put checksum in load information block.\n"); print(" -h Print out this message and exit.\n"); print(" -l Linux mode; if present, copy 'image' and 'initrd' sections.\n"); print(" -v Verbose. Print out lots of ELF information.\n"); @@ -148,10 +150,14 @@ sub decode_options { - if (!getopts("hlvV")) { + if (!getopts("chlvV")) { usage(1); } + if ($opt_c) { + $do_checksum = 1; + } + if ($opt_h) { usage(0); } @@ -360,14 +366,20 @@ $output_size += $initrd_size; } - $num_blocks = $output_size / 512 + 1; + # + # Compute size with header + # + + $header = pack("H8N7", "0052504f", 0, 0, 0, 0, 0, 0, 0); + $num_blocks = ($output_size + length($header) + 511) / 512; # # Write IBM PowerPC evaluation board boot_block_t header # $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0, - $text_addr, 0, 0, 0); + $text_addr, 0, 0, 0); + $bytes = length($header); @@ -412,18 +424,57 @@ # # Pad to a multiple of 512 bytes + # If the (size of the boot image mod 512) is between 509 and 511 bytes + # then the tftp to the Walnut fails. This may be fixed in more recent + # Walnut bootrom. # - $pad_size = 512 - (length($header) + $output_size) % 512; + $pad_size = 512 - ((length($header) + $output_size) % 512); + if ($pad_size == 512) { + $pad_size = 0; + } + + if ($pad_size != 0) { + + if ($verbose) { + print("Padding boot image by an additional $pad_size bytes.\n"); + } + + $pad_string = pack("H8","deadbeef") x 128; + + syswrite(BOOT, $pad_string, $pad_size) or + die "Could not pad boot image in output file.\n"; - if ($verbose) { - print("Padding boot image by an additional $pad_size bytes.\n"); } - $pad_string = pack(("H8","deadbeef") x 128); + # + # Compute 32 bit checksum over entire file. + # + + if ($do_checksum) { - syswrite(BOOT, $pad_string, $pad_size) or - die "Could not pad boot image in output file.\n"; + close(BOOT); + open(BOOT, "+<$ofile") || die "Cannot open output file"; + undef $/; + $temp = unpack("%32N*", ); + # Solaris and PPC Linux return 0x80000000 for "-$temp" when $temp + # is negative. "~($temp - 1)" negates $temp properly. + $csum = ~($temp - 1); + printf("Checksum = 0x%08x\r\n", $csum); + + # + # Rewrite IBM PowerPC evaluation board boot_block_t header, + # this time with the checksum included + # + + $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0, + $text_addr, $csum, 0, 0); + + seek(BOOT, 0, 0); + syswrite(BOOT, $header, length($header)) or + die("Could not write boot image header to output file."); + + } # # Clean-up and leave @@ -431,7 +482,7 @@ close(BOOT); - print("\nBoot image file \"$ofile\" built successfully.\n\n"); + print("\nBoot image file \"$ofile\" built successfuly.\n\n"); exit(0); } diff -Nru a/arch/ppc/boot/utils/mknote.c b/arch/ppc/boot/utils/mknote.c --- a/arch/ppc/boot/utils/mknote.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/boot/utils/mknote.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mknote.c 1.7 05/18/01 15:17:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Cort Dougan 1999. diff -Nru a/arch/ppc/boot/utils/mkpmon.c b/arch/ppc/boot/utils/mkpmon.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/mkpmon.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,49 @@ +/* + * arch/ppc/pmonboot/mkpmon.c + * + * Munger code to create PMON bootable images + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int file; + unsigned long image_address = 0, image_size = 0, file_size = 0; + + if ( argc != 4 ) + { + fprintf(stderr, "usage: %s \n",argv[0]); + exit(-1); + } + + image_address = strtoul(argv[1], NULL, 16); + image_size = strtoul(argv[2], NULL, 16); + file_size = __cpu_to_be32(image_address + image_size - 0x10000); + + file = open(argv[3], O_RDWR); + + /* Seek to the program header file size field */ + lseek(file, 0x44, SEEK_SET); + + /* Write out new file size */ + write(file, &file_size, sizeof(file_size)); + + return 0; +} diff -Nru a/arch/ppc/boot/utils/mkprep.c b/arch/ppc/boot/utils/mkprep.c --- a/arch/ppc/boot/utils/mkprep.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/boot/utils/mkprep.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mkprep.c 1.7 05/18/01 06:20:29 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * Makes a prep bootable image which can be dd'd onto diff -Nru a/arch/ppc/boot/utils/mksimage.c b/arch/ppc/boot/utils/mksimage.c --- a/arch/ppc/boot/utils/mksimage.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/boot/utils/mksimage.c Sat Jun 16 06:00:31 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mksimage.c 1.6 05/18/01 15:16:42 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * diff -Nru a/arch/ppc/boot/utils/piggyback.c b/arch/ppc/boot/utils/piggyback.c --- a/arch/ppc/boot/utils/piggyback.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/boot/utils/piggyback.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.piggyback.c 1.7 05/18/01 15:17:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/boot/zx4500/Makefile b/arch/ppc/boot/zx4500/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/zx4500/Makefile Sat Jun 16 06:00:31 2001 @@ -0,0 +1,89 @@ +# arch/ppc/boot/zx4500/Makefile +# +# Makefile for Znyx ZX4500 cPCI board +# +# Author: Mark A. Greer +# +# Copyright 2001 MontaVista Software Inc. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. + +.c.s: + $(CC) $(CFLAGS) -S -o $*.s $< +.s.o: + $(AS) -o $*.o $< +.c.o: + $(CC) $(CFLAGS) -c -o $*.o $< +.S.s: + $(CPP) $(AFLAGS) -traditional -o $*.o $< +.S.o: + $(CC) $(AFLAGS) -traditional -c -o $*.o $< + +ZLINKFLAGS = -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00800000 + +OBJECTS := head.o ../common/misc-common.o ../common/misc-simple.o \ + ../common/ns16550.o ../common/string.o +OBJCOPY_ARGS = -O elf32-powerpc +LIBS := ../lib/zlib.a + +OFFSET := ../utils/offset +SIZE := ../utils/size + +all: zImage + +../common/misc-simple.o: ../common/misc-simple.c + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 -DZIMAGE_OFFSET=0 \ + -DZIMAGE_SIZE=0 -c -o $@ $*.c + +zvmlinux.initrd: $(OBJECTS) $(LIBS) ../images/vmlinux.gz + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ initrd` \ + -DINITRD_SIZE=`sh $(SIZE) $(OBJDUMP) $@ initrd` \ + -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ + -c -o ../common/misc-simple.o ../common/misc-simple.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=initrd=../images/ramdisk.image.gz \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +zImage: zvmlinux + dd if=zvmlinux of=../images/$@.zx4500 skip=64 bs=1k + rm -f zvmlinux + +zImage.initrd: zvmlinux.initrd + dd if=zvmlinux.initrd of=../images/$@.zx4500 skip=64 bs=1k + rm -f zvmlinux.initrd + +zvmlinux: $(OBJECTS) $(LIBS) ../images/vmlinux.gz +# +# build the boot loader image and then compute the offset into it +# for the kernel image +# + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ +# +# then with the offset rebuild the bootloader so we know where the kernel is +# + $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ + -DZIMAGE_OFFSET=`sh $(OFFSET) $(OBJDUMP) $@ image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) $@ image` \ + -c -o ../common/misc-simple.o ../common/misc-simple.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp $@ + rm -f $@.tmp + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/zx4500/head.S b/arch/ppc/boot/zx4500/head.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/zx4500/head.S Sat Jun 16 06:00:30 2001 @@ -0,0 +1,315 @@ +/* + * arch/ppc/boot/zx4500/head.S + * + * Initial board bringup code for Znyx ZX4500 cPCI non-sys board. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include "../../kernel/ppc_defs.h" +#include "../../kernel/ppc_asm.tmpl" +#include +#include + + .text + +/* + * + * Begin at some arbitrary location in RAM or Flash + * Initialize core registers + * Configure memory controller (Not executing from RAM) + * Move the boot code to the link address (8M) + * Setup C stack + * Initialize UART + * Decompress the kernel to 0x0 + * Jump to the kernel entry + * + */ + + .globl start +start: + bl start_ + +start_: +/* + * Configure core registers + */ + + /* Establish default MSR value, exception prefix 0xFFF */ + li r3,MSR_IP|MSR_FP + mtmsr r3 + + /* Clear BATS */ + li r8,0 + mtspr DBAT0U,r8 + mtspr DBAT0L,r8 + mtspr DBAT1U,r8 + mtspr DBAT1L,r8 + mtspr DBAT2U,r8 + mtspr DBAT2L,r8 + mtspr DBAT3U,r8 + mtspr DBAT3L,r8 + mtspr IBAT0U,r8 + mtspr IBAT0L,r8 + mtspr IBAT1U,r8 + mtspr IBAT1L,r8 + mtspr IBAT2U,r8 + mtspr IBAT2L,r8 + mtspr IBAT3U,r8 + mtspr IBAT3L,r8 + isync + sync + sync + + /* Set segment registers */ + lis r8, 0x8000 + isync + mtsr SR0,r8 + mtsr SR1,r8 + mtsr SR2,r8 + mtsr SR3,r8 + mtsr SR4,r8 + mtsr SR5,r8 + mtsr SR6,r8 + mtsr SR7,r8 + mtsr SR8,r8 + mtsr SR9,r8 + mtsr SR10,r8 + mtsr SR11,r8 + mtsr SR12,r8 + mtsr SR13,r8 + mtsr SR14,r8 + mtsr SR15,r8 + isync + sync + sync + + /* Disable L1 icache/dcache */ + li r4,0x0000 + isync + mtspr HID0,r4 + sync + isync + + /* Flash Invalidate L1 icache/dcache */ + ori r4,r4,0x8000 + ori r8,r4,0x0800 + isync + mtspr HID0,r8 + sync + isync + + /* Older cores need to manually clear ICFI bit */ + mtspr HID0,r4 + sync + isync + +/* check if we need to relocate ourselves to the link addr or were we + loaded there to begin with -- Cort */ + lis r4,start@h + ori r4,r4,start@l + mflr r3 + subi r3,r3,4 /* we get the nip, not the ip of the branch */ + mr r8,r3 + cmp 0,r3,r4 + bne 1010f +/* compute size of whole image in words. this should be moved to + * start_ldr() -- Cort + */ + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* round up */ + sub r5,r5,r4 + srwi r5,r5,2 + mr r7,r5 + b start_ldr +1010: +/* + * no matter where we're loaded, move ourselves to -Ttext address + */ +relocate: + mflr r3 /* Compute code bias */ + subi r3,r3,4 + mr r8,r3 + lis r4,start@h + ori r4,r4,start@l + lis r5,end@h + ori r5,r5,end@l + addi r5,r5,3 /* Round up - just in case */ + sub r5,r5,r4 /* Compute # longwords to move */ + srwi r5,r5,2 + mtctr r5 + mr r7,r5 + li r6,0 + subi r3,r3,4 /* Set up for loop */ + subi r4,r4,4 +00: lwzu r5,4(r3) + stwu r5,4(r4) + xor r6,r6,r5 + bdnz 00b + lis r3,start_ldr@h + ori r3,r3,start_ldr@l + mtlr r3 /* Easiest way to do an absolute jump */ + blr +start_ldr: +/* Clear all of BSS and set up stack for C calls */ + lis r3,edata@h + ori r3,r3,edata@l + lis r4,end@h + ori r4,r4,end@l + subi r3,r3,4 + subi r4,r4,4 + li r0,0 +50: stwu r0,4(r3) + cmp 0,r3,r4 + bne 50b +90: mr r9,r1 /* Save old stack pointer (in case it matters) */ + lis r1,.stack@h + ori r1,r1,.stack@l + addi r1,r1,4096*2 + subi r1,r1,256 + li r2,0x000F /* Mask pointer to 16-byte boundary */ + andc r1,r1,r2 + +/* + * Exec kernel loader + */ + mr r3,r8 /* Load point */ + mr r4,r7 /* Program length */ + mr r5,r6 /* Checksum */ + bl decompress_kernel + + lis r6,cmd_line@h + ori r6,r6,cmd_line@l + lwz r6, 0(r6) + subi r7,r6,1 +00: lbzu r2,1(r7) + cmpi 0,r2,0 + bne 00b + + /* r4,r5 have initrd_start, size */ + lis r2,initrd_start@h + ori r2,r2,initrd_start@l + lwz r4,0(r2) + lis r2,initrd_end@h + ori r2,r2,initrd_end@l + lwz r5,0(r2) + + li r9,0x4 + mtlr r9 + li r9,0 + + /* + * Jump to kernel start + */ + blr + +hang: + b hang + +/* + * Delay for a number of microseconds + * -- Use the BUS timer (assumes 66MHz) + */ + .globl udelay +udelay: + mfspr r4,PVR + srwi r4,r4,16 + cmpi 0,r4,1 /* 601 ? */ + bne .udelay_not_601 +00: li r0,86 /* Instructions / microsecond? */ + mtctr r0 +10: addi r0,r0,0 /* NOP */ + bdnz 10b + subic. r3,r3,1 + bne 00b + blr + +.udelay_not_601: + mulli r4,r3,1000 /* nanoseconds */ + addi r4,r4,59 + li r5,60 + divw r4,r4,r5 /* BUS ticks */ +1: mftbu r5 + mftb r6 + mftbu r7 + cmp 0,r5,r7 + bne 1b /* Get [synced] base time */ + addc r9,r6,r4 /* Compute end time */ + addze r8,r5 +2: mftbu r5 + cmp 0,r5,r8 + blt 2b + bgt 3f + mftb r6 + cmp 0,r6,r9 + blt 2b +3: blr + +.globl _get_HID0 +_get_HID0: + mfspr r3,HID0 + blr + +.globl _put_HID0 +_put_HID0: + mtspr HID0,r3 + blr + +.globl _get_MSR +_get_MSR: + mfmsr r3 + blr + +.globl _put_MSR +_put_MSR: + mtmsr r3 + blr + +/* + * Flush instruction cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_instruction_cache) + mflr r5 + bl flush_data_cache + mfspr r3,HID0 /* Caches are controlled by this register */ + li r4,0 + ori r4,r4,(HID0_ICE|HID0_ICFI) + or r3,r3,r4 /* Need to enable+invalidate to clear */ + mtspr HID0,r3 + andc r3,r3,r4 + ori r3,r3,HID0_ICE /* Enable cache */ + mtspr HID0,r3 + mtlr r5 + blr + +#define NUM_CACHE_LINES 128*8 +#define CACHE_LINE_SIZE 32 +#define cache_flush_buffer 0x1000 + +/* + * Flush data cache + * *** I'm really paranoid here! + */ +_GLOBAL(flush_data_cache) + lis r3,cache_flush_buffer@h + ori r3,r3,cache_flush_buffer@l + li r4,NUM_CACHE_LINES + mtctr r4 +00: lwz r4,0(r3) + addi r3,r3,CACHE_LINE_SIZE /* Next line, please */ + bdnz 00b +10: blr + .comm .stack,4096*2,4 + diff -Nru a/arch/ppc/config.in b/arch/ppc/config.in --- a/arch/ppc/config.in Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/config.in Sat Jun 16 06:00:16 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.config.in 1.24 05/21/01 00:48:24 cort +# BK Id: %F% %I% %G% %U% %#% # # For a description of the syntax of this configuration file, # see Documentation/kbuild/config-language.txt. @@ -44,7 +44,9 @@ if [ "$CONFIG_8260" = "y" ]; then define_bool CONFIG_SERIAL_CONSOLE y - bool 'Support for EST8260' CONFIG_EST8260 + choice 'Machine Type' \ + "EST8260 CONFIG_EST8260 \ + SBS8260 CONFIG_SBS8260" EST8260 fi if [ "$CONFIG_4xx" = "y" ]; then @@ -84,9 +86,33 @@ if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ]; then choice 'Machine Type' \ - "PowerMac/PReP/MTX/CHRP CONFIG_ALL_PPC \ - Gemini CONFIG_GEMINI \ - APUS CONFIG_APUS" PowerMac/PReP/MTX/CHRP + "CHRP/PowerMac/PReP CONFIG_ALL_PPC \ + Amiga-APUS CONFIG_APUS \ + IBM-Spruce CONFIG_SPRUCE \ + Force-PowerCore CONFIG_PCORE \ + MEN-F1 CONFIG_MENF1 \ + Motorola-MCPN765 CONFIG_MCPN765 \ + Motorola-MVME5100 CONFIG_MVME5100 \ + Motorola-PrPMC750 CONFIG_PRPMC750 \ + Motorola-Sandpoint CONFIG_SANDPOINT \ + SBS-K2 CONFIG_K2 \ + Synergy-Gemini CONFIG_GEMINI \ + Zynx-ZX4500 CONFIG_ZX4500" CHRP/PowerMac/PReP +fi + +if [ "$CONFIG_PRPMC750" = "y" ]; then + choice 'Carrier Type' \ + "PrPMCBASE CONFIG_PRPMC_BASE \ + PrPMC-Carrier CONFIG_PRPMC_CARRIER" PrPMCBASE +fi + +if [ "$CONFIG_MVME5100" = "y" ]; then + bool 'MVME5100 configured with an IPMC761' CONFIG_MVME5100_IPMC761_PRESENT +fi + +if [ "$CONFIG_SPURCE" = "y" ]; then + define_bool CONFIG_SERIAL_CONSOLE_NONSTD y + define_int CONFIG_SERIAL_CONSOLE_BAUD 9600 fi if [ "$CONFIG_PPC64BRIDGE" != "y" ]; then @@ -104,6 +130,7 @@ if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ];then bool 'AltiVec Support' CONFIG_ALTIVEC + bool 'Thermal Management Support' CONFIG_TAU fi if [ "$CONFIG_4xx" = "y" -o "$CONFIG_8xx" = "y" ]; then @@ -176,12 +203,12 @@ if [ "$CONFIG_ALL_PPC" = "y" ]; then bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE bool 'Support for RTAS (RunTime Abstraction Services) in /proc' CONFIG_PPC_RTAS - bool 'Support for early boot text console (BootX or OpenFirmware only)' CONFIG_BOOTX_TEXT bool 'Support for PReP Residual Data' CONFIG_PREP_RESIDUAL - bool 'Default bootloader kernel arguments' CONFIG_CMDLINE_BOOL - if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then - string 'Initial kernel command string' CONFIG_CMDLINE "console=ttyS0,9600 console=tty0 root=/dev/sda2" - fi +fi + +bool 'Default bootloader kernel arguments' CONFIG_CMDLINE_BOOL +if [ "$CONFIG_CMDLINE_BOOL" = "y" ] ; then + string 'Initial kernel command string' CONFIG_CMDLINE "console=ttyS0,9600 console=tty0 root=/dev/sda2" fi if [ "$CONFIG_APUS" = "y" ]; then @@ -375,4 +402,11 @@ bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ bool 'Include kgdb kernel debugger' CONFIG_KGDB bool 'Include xmon kernel debugger' CONFIG_XMON +if [ "$CONFIG_ALL_PPC" = "y" ]; then + bool 'Support for early boot text console (BootX or OpenFirmware only)' CONFIG_BOOTX_TEXT +fi +if [ "$CONFIG_MCPN765" = "y" -o "$CONFIG_SANDPOINT" = "y" \ + -o "$CONFIG_ZX4500" = "y" ]; then + bool 'Support for early boot texts over serial port' CONFIG_DEBUG_TEXT +fi endmenu diff -Nru a/arch/ppc/configs/iSeries_defconfig b/arch/ppc/configs/iSeries_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/configs/iSeries_defconfig Sat Jun 16 06:00:31 2001 @@ -0,0 +1,431 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +# CONFIG_6xx is not set +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +CONFIG_PPC_ISERIES=y +CONFIG_PPC64BRIDGE=y +# CONFIG_ALL_PPC is not set +# CONFIG_SMP is not set +CONFIG_MACH_SPECIFIC=y + +# +# General setup +# +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +# CONFIG_PCI is not set +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +CONFIG_BSD_PROCESS_ACCT=y +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=y +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +CONFIG_VIODASD=y +# CONFIG_VIODASD_IDE is not set +# 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=y +# CONFIG_BLK_DEV_NBD 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_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +# CONFIG_NETFILTER is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# 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_NET_DIVERT 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 + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_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 + +# +# Ethernet (10 or 100Mbit) +# +# CONFIG_NET_ETHERNET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +CONFIG_VETH=y +# 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 + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +CONFIG_CD_NO_IDESCSI=y +# CONFIG_AZTCD is not set +# CONFIG_GSCD is not set +# CONFIG_SBPCD is not set +# CONFIG_MCD is not set +# CONFIG_MCDX is not set +# CONFIG_OPTCD is not set +# CONFIG_CM206 is not set +# CONFIG_SJCD is not set +# CONFIG_ISP16_CDI is not set +# CONFIG_CDU31A is not set +# CONFIG_CDU535 is not set +CONFIG_VIOCD=y +# CONFIG_VIOCD_AZTECH is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT 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=256 +# CONFIG_PRINTER is not set +# CONFIG_PPDEV is not set +CONFIG_VIOCONS=y + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_JOYSTICK is not set + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set +CONFIG_VIOTAPE=y + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_INTEL_RNG is not set +# CONFIG_NVRAM 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 + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +CONFIG_REISERFS_FS=y +# CONFIG_REISERFS_CHECK 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=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +CONFIG_ISO9660_FS=y +CONFIG_JOLIET=y +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# 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=y +CONFIG_ROOT_NFS=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +CONFIG_SUNRPC=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS 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 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_936 is not set +# CONFIG_NLS_CODEPAGE_950 is not set +# CONFIG_NLS_CODEPAGE_932 is not set +# CONFIG_NLS_CODEPAGE_949 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_CODEPAGE_1251 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_9 is not set +# CONFIG_NLS_ISO8859_13 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_KOI8_U is not set +# CONFIG_NLS_UTF8 is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff -Nru a/arch/ppc/configs/k2_defconfig b/arch/ppc/configs/k2_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/configs/k2_defconfig Sat Jun 16 06:00:30 2001 @@ -0,0 +1,542 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +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_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +CONFIG_K2=y +# CONFIG_GEMINI is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +CONFIG_MACH_SPECIFIC=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# 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_PPC_RTC=y +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD 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_CPQ_CISS_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_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_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG 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_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM 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_NET_DIVERT 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 + +# +# 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_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 is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set + +# +# 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_BLK_DEV_IDEDMA_PCI is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# 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_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_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_BLK_DEV_OSB4 is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX 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 is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 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_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET 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_HP100 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_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 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_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# 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 +# 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 + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# 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 +# 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 + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK 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_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +CONFIG_XMON=y diff -Nru a/arch/ppc/configs/mcpn765_defconfig b/arch/ppc/configs/mcpn765_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/configs/mcpn765_defconfig Sat Jun 16 06:00:30 2001 @@ -0,0 +1,449 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +CONFIG_MCPN765=y +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +CONFIG_ALTIVEC=y + +# +# General setup +# +CONFIG_HIGHMEM=y +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# 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_PPC_RTC=y +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD 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_CPQ_CISS_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_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_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV 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_NET_IPIP is not set +# CONFIG_NET_IPGRE 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_NET_DIVERT 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 + +# +# 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 + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 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_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET 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_HP100 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_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 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_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# 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 +# 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 + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_EXTENDED=y +# CONFIG_SERIAL_MANY_PORTS is not set +CONFIG_SERIAL_SHARE_IRQ=y +CONFIG_SERIAL_DETECT_IRQ=y +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# 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 +# 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 + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK 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_TMPFS=y +# 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_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=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_DEBUG_TEXT is not set diff -Nru a/arch/ppc/configs/menf1_defconfig b/arch/ppc/configs/menf1_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/configs/menf1_defconfig Sat Jun 16 06:00:30 2001 @@ -0,0 +1,545 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +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_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +CONFIG_MENF1=y +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# 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_PPC_RTC=y +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD 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_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_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_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM 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_NET_DIVERT 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 + +# +# 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_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_IDESCSI is not set + +# +# 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_BLK_DEV_IDEDMA_PCI is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# 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_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_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_BLK_DEV_OSB4 is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX 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 is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 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_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET 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_HP100 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_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 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_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# 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 +# 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 + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# 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 +# 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 + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK 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_TMPFS=y +# 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_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=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff -Nru a/arch/ppc/configs/mvme5100_defconfig b/arch/ppc/configs/mvme5100_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/configs/mvme5100_defconfig Sat Jun 16 06:00:30 2001 @@ -0,0 +1,620 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +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_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +CONFIG_MVME5100=y +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_MVME5100_IPMC761_PRESENT is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +CONFIG_ALTIVEC=y +CONFIG_MACH_SPECIFIC=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# 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_PPC_RTC=y +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD 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_CPQ_CISS_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_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_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +CONFIG_FILTER=y +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM 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_NET_DIVERT 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 + +# +# 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_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 is not set +# CONFIG_BLK_DEV_IDETAPE is not set +# CONFIG_BLK_DEV_IDEFLOPPY is not set +# CONFIG_BLK_DEV_IDESCSI is not set + +# +# 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_BLK_DEV_IDEDMA_PCI is not set +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +# CONFIG_BLK_DEV_IDEDMA is not set +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# 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_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_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_BLK_DEV_OSB4 is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX 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=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +# CONFIG_CHR_DEV_SG is not set + +# +# 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_AIC7XXX_OLD 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 +# 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_NCR53C406A 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_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_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 +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 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_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET 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_HP100 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_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 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_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# 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 +# 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 + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# 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 +# 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 + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK 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_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff -Nru a/arch/ppc/configs/pcore_defconfig b/arch/ppc/configs/pcore_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/configs/pcore_defconfig Sat Jun 16 06:00:32 2001 @@ -0,0 +1,560 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +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_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +CONFIG_PCORE=y +# CONFIG_MENF1 is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +CONFIG_ALTIVEC=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# 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_PPC_RTC=y +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD 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_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_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_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM 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_NET_DIVERT 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 + +# +# 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 + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_SD_EXTRA_DEVS=40 +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +CONFIG_BLK_DEV_SR=y +# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_SR_EXTRA_DEVS=2 +# CONFIG_CHR_DEV_SG is not set + +# +# 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 +# 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_AIC7XXX_OLD 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 +# 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_NCR53C406A 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_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_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 +# CONFIG_SCSI_DEBUG is not set +# CONFIG_SCSI_MESH is not set +# CONFIG_SCSI_MAC53C94 is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 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_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET 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_HP100 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_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 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_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# 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 +# 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 + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +CONFIG_BUSMOUSE=y +# CONFIG_ATIXL_BUSMOUSE is not set +# CONFIG_LOGIBUSMOUSE is not set +# CONFIG_MS_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# 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 +# 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 + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK 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_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff -Nru a/arch/ppc/configs/prpmc750_defconfig b/arch/ppc/configs/prpmc750_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/configs/prpmc750_defconfig Sat Jun 16 06:00:30 2001 @@ -0,0 +1,484 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +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_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_MVME5100 is not set +CONFIG_PRPMC750=y +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +CONFIG_MACH_SPECIFIC=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# 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_PPC_RTC 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 +# 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_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_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_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV is not set +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=m +CONFIG_IP_NF_FTP=m +# CONFIG_IP_NF_QUEUE is not set +CONFIG_IP_NF_IPTABLES=m +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_MARK=m +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_TCPMSS=m +CONFIG_IP_NF_MATCH_STATE=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_OWNER=m +CONFIG_IP_NF_FILTER=m +CONFIG_IP_NF_TARGET_REJECT=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=m +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=m +CONFIG_IP_NF_TARGET_REDIRECT=m +CONFIG_IP_NF_NAT_FTP=m +# CONFIG_IP_NF_MANGLE is not set +# CONFIG_IP_NF_TARGET_LOG is not set +CONFIG_IP_NF_TARGET_TCPMSS=m +CONFIG_IP_NF_COMPAT_IPCHAINS=m +CONFIG_IP_NF_NAT_NEEDED=y +# CONFIG_IP_NF_COMPAT_IPFWADM 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_NET_DIVERT 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 + +# +# 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 + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 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_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET 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_HP100 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_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 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_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# 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 +# 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 + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +CONFIG_VT=y +# CONFIG_VT_CONSOLE is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +CONFIG_BUSMOUSE=y +# CONFIG_ATIXL_BUSMOUSE is not set +# CONFIG_LOGIBUSMOUSE is not set +# CONFIG_MS_BUSMOUSE is not set +CONFIG_MOUSE=y +CONFIG_PSMOUSE=y +# CONFIG_82C710_MOUSE is not set +# CONFIG_PC110_PAD is not set + +# +# 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 +# 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 + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK 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_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff -Nru a/arch/ppc/configs/sandpoint_defconfig b/arch/ppc/configs/sandpoint_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/configs/sandpoint_defconfig Sat Jun 16 06:00:31 2001 @@ -0,0 +1,518 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +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_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +# CONFIG_MENF1 is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +CONFIG_SANDPOINT=y +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +# CONFIG_ZX4500 is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +CONFIG_ALTIVEC=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=y +# 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_PPC_RTC=y +# CONFIG_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD 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_CPQ_CISS_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_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_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV 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_NET_IPIP is not set +# CONFIG_NET_IPGRE 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_NET_DIVERT 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 + +# +# 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_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_IDESCSI is not set + +# +# 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=y +CONFIG_BLK_DEV_IDEDMA_PCI=y +# CONFIG_BLK_DEV_OFFBOARD is not set +# CONFIG_IDEDMA_PCI_AUTO is not set +CONFIG_BLK_DEV_IDEDMA=y +# CONFIG_IDEDMA_PCI_WIP is not set +# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set +# CONFIG_BLK_DEV_AEC62XX is not set +# CONFIG_AEC62XX_TUNING is not set +# CONFIG_BLK_DEV_ALI15X3 is not set +# 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_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_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_BLK_DEV_OSB4 is not set +# CONFIG_BLK_DEV_SIS5513 is not set +# CONFIG_BLK_DEV_SLC90E66 is not set +# CONFIG_BLK_DEV_TRM290 is not set +# CONFIG_BLK_DEV_VIA82CXXX is not set +CONFIG_BLK_DEV_SL82C105=y +# CONFIG_IDE_CHIPSETS is not set +# CONFIG_IDEDMA_AUTO is not set +# CONFIG_IDEDMA_IVB is not set +# CONFIG_DMA_NONPCI is not set +CONFIG_BLK_DEV_IDE_MODES=y + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 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_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET 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_HP100 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_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 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_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# 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 +# 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 + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# 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 +# 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 + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK 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_TMPFS=y +# 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_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=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_DEBUG_TEXT is not set diff -Nru a/arch/ppc/configs/spruce_defconfig b/arch/ppc/configs/spruce_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/configs/spruce_defconfig Sat Jun 16 06:00:30 2001 @@ -0,0 +1,441 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +CONFIG_KMOD=y + +# +# Platform support +# +CONFIG_PPC=y +CONFIG_6xx=y +# CONFIG_4xx is not set +# CONFIG_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +CONFIG_SPRUCE=y +# CONFIG_GEMINI is not set +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set +CONFIG_MACH_SPECIFIC=y + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +# CONFIG_BINFMT_MISC is not set +# 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_CMDLINE_BOOL is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD 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_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_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_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV 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_NET_IPIP is not set +# CONFIG_NET_IPGRE 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_NET_DIVERT 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 + +# +# 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 + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 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_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET 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_HP100 is not set +# CONFIG_NET_ISA is not set +CONFIG_NET_PCI=y +CONFIG_PCNET32=y +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_APRICOT is not set +# CONFIG_CS89x0 is not set +# CONFIG_TULIP is not set +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +# CONFIG_EEPRO100 is not set +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 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_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# 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 +# 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 + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# 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=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# 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 +# 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 + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK 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_TMPFS=y +# CONFIG_RAMFS is not set +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_MINIX_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +# CONFIG_DEVFS_FS is not set +# CONFIG_DEVFS_MOUNT is not set +# CONFIG_DEVFS_DEBUG is not set +CONFIG_DEVPTS_FS=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set diff -Nru a/arch/ppc/configs/zx4500_defconfig b/arch/ppc/configs/zx4500_defconfig --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/configs/zx4500_defconfig Sat Jun 16 06:00:32 2001 @@ -0,0 +1,455 @@ +# +# Automatically generated make config: don't edit +# +# CONFIG_UID16 is not set +# CONFIG_RWSEM_GENERIC_SPINLOCK is not set +CONFIG_RWSEM_XCHGADD_ALGORITHM=y + +# +# Code maturity level options +# +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_POWER3 is not set +# CONFIG_POWER4 is not set +# CONFIG_8xx is not set +# CONFIG_8260 is not set +# CONFIG_ALL_PPC is not set +# CONFIG_APUS is not set +# CONFIG_SPRUCE is not set +# CONFIG_PCORE is not set +# CONFIG_MENF1 is not set +# CONFIG_MCPN765 is not set +# CONFIG_MVME5100 is not set +# CONFIG_PRPMC750 is not set +# CONFIG_SANDPOINT is not set +# CONFIG_K2 is not set +# CONFIG_GEMINI is not set +CONFIG_ZX4500=y +# CONFIG_PPC601_SYNC_FIX is not set +# CONFIG_SMP is not set +# CONFIG_ALTIVEC is not set + +# +# General setup +# +# CONFIG_HIGHMEM is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_SBUS is not set +# CONFIG_MCA is not set +CONFIG_PCI=y +CONFIG_NET=y +CONFIG_SYSCTL=y +CONFIG_SYSVIPC=y +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_KCORE_ELF=y +CONFIG_BINFMT_ELF=y +CONFIG_KERNEL_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_PCI_NAMES=y +# CONFIG_HOTPLUG is not set +# CONFIG_PCMCIA is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set +# CONFIG_PPC_RTC 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 +# 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_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_SIZE=16384 +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_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_NETLINK=y +# CONFIG_RTNETLINK is not set +# CONFIG_NETLINK_DEV 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_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_INET_ECN is not set +CONFIG_SYN_COOKIES=y +# 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_NET_DIVERT 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 + +# +# 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 + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 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_TUN is not set +# CONFIG_ETHERTAP is not set +# CONFIG_NET_SB1000 is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_MACE is not set +# CONFIG_BMAC is not set +# CONFIG_GMAC is not set +# CONFIG_NCR885E is not set +# CONFIG_OAKNET 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_HP100 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_APRICOT is not set +# CONFIG_CS89x0 is not set +CONFIG_TULIP=y +# CONFIG_DE4X5 is not set +# CONFIG_DGRS is not set +# CONFIG_DM9102 is not set +CONFIG_EEPRO100=y +# CONFIG_EEPRO100_PM is not set +# CONFIG_LNE390 is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_NE3210 is not set +# CONFIG_ES3210 is not set +# CONFIG_8139TOO is not set +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 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_HAPPYMEAL is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# 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 +# 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 + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Old CD-ROM drivers (not SCSI, not IDE) +# +# CONFIG_CD_NO_IDESCSI is not set + +# +# Console drivers +# +# CONFIG_VGA_CONSOLE is not set + +# +# Frame-buffer support +# +# CONFIG_FB is not set + +# +# Input core support +# +# CONFIG_INPUT is not set + +# +# Macintosh device drivers +# + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +CONFIG_SERIAL_EXTENDED=y +# CONFIG_SERIAL_MANY_PORTS is not set +CONFIG_SERIAL_SHARE_IRQ=y +CONFIG_SERIAL_DETECT_IRQ=y +# CONFIG_SERIAL_MULTIPORT is not set +# CONFIG_HUB6 is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=256 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# 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 +# 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 + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# File systems +# +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK 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_TMPFS=y +# 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_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +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 +# 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=y +# 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_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set + +# +# Partition Types +# +# CONFIG_PARTITION_ADVANCED is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Kernel hacking +# +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_KGDB is not set +# CONFIG_XMON is not set +# CONFIG_DEBUG_TEXT is not set diff -Nru a/arch/ppc/iSeries/HvCall.c b/arch/ppc/iSeries/HvCall.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/HvCall.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,128 @@ +/* + * HvCall.c + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#ifndef _HVCALLSC_H +#include +#endif +#include + +#ifndef _HVTYPES_H +#include +#endif + + +//===================================================================== +// Note that this call takes at MOST one page worth of data +int HvCall_readLogBuffer(HvLpIndex lpIndex, void *buffer, u64 bufLen) +{ + struct HvLpBufferList *bufList; + u64 bytesLeft = bufLen; + u64 leftThisPage; + u64 curPtr = virt_to_absolute( (unsigned long) buffer ); + u64 retVal; + int npages; + int i; + + npages = 0; + while (bytesLeft) + { + npages++; + leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr; + + if (leftThisPage > bytesLeft) + bytesLeft = 0; + else + bytesLeft -= leftThisPage; + + curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE; + } + + if (npages == 0) + return 0; + + bufList = (struct HvLpBufferList *)kmalloc(npages * sizeof(struct HvLpBufferList), GFP_ATOMIC); + bytesLeft = bufLen; + curPtr = virt_to_absolute( (unsigned long) buffer ); + for(i=0; i bytesLeft) + { + bufList[i].len = bytesLeft; + bytesLeft = 0; + } + else + { + bufList[i].len = leftThisPage; + bytesLeft -= leftThisPage; + } + + curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE; + } + + + retVal = HvCall3(HvCallBaseReadLogBuffer,lpIndex, virt_to_absolute((unsigned long)bufList), bufLen); + + kfree(bufList); + + return (int)retVal; +} + +//===================================================================== +void HvCall_writeLogBuffer(const void *buffer, u64 bufLen) +{ + struct HvLpBufferList bufList; + u64 bytesLeft = bufLen; + u64 leftThisPage; + u64 curPtr = virt_to_absolute( (unsigned long) buffer ); + + while (bytesLeft) + { + bufList.addr = curPtr; + + leftThisPage = ((curPtr & PAGE_MASK) + PAGE_SIZE) - curPtr; + + if (leftThisPage > bytesLeft) + { + bufList.len = bytesLeft; + bytesLeft = 0; + } + else + { + bufList.len = leftThisPage; + bytesLeft -= leftThisPage; + } + + curPtr = (curPtr & PAGE_MASK) + PAGE_SIZE; + } + + + HvCall2(HvCallBaseWriteLogBuffer, virt_to_absolute((unsigned long)&bufList), bufLen); + +} diff -Nru a/arch/ppc/iSeries/HvLpConfig.c b/arch/ppc/iSeries/HvLpConfig.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/HvLpConfig.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,27 @@ +/* + * HvLpConfig.c + * Copyright (C) 2001 Kyle A. Lucke, IBM Corporation + * + * 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 + */ + +#ifndef _HVLPCONFIG_H +#include +#endif + +HvLpIndex HvLpConfig_getLpIndex_outline(void) +{ + return HvLpConfig_getLpIndex(); +} diff -Nru a/arch/ppc/iSeries/HvLpEvent.c b/arch/ppc/iSeries/HvLpEvent.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/HvLpEvent.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,87 @@ +/* + * HvLpEvent.c + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * 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 + */ + +#include +#include +#include +#include +#include +#include + +// Array of LpEvent handler functions +LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; +unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes]; + +// Register a handler for an LpEvent type + +int HvLpEvent_registerHandler( HvLpEvent_Type eventType, LpEventHandler handler ) +{ + int rc = 1; + if ( eventType < HvLpEvent_Type_NumTypes ) { + lpEventHandler[eventType] = handler; + rc = 0; + } + return rc; + +} + +int HvLpEvent_unregisterHandler( HvLpEvent_Type eventType ) +{ + int rc = 1; + if ( eventType < HvLpEvent_Type_NumTypes ) { + if ( !lpEventHandlerPaths[eventType] ) { + lpEventHandler[eventType] = NULL; + rc = 0; + } + } + return rc; +} + +// (lpIndex is the partition index of the target partition. +// needed only for VirtualIo, VirtualLan and SessionMgr. Zero +// indicates to use our partition index - for the other types) +int HvLpEvent_openPath( HvLpEvent_Type eventType, HvLpIndex lpIndex ) +{ + int rc = 1; + if ( eventType < HvLpEvent_Type_NumTypes && + lpEventHandler[eventType] ) { + if ( lpIndex == 0 ) + lpIndex = itLpNaca.xLpIndex; + HvCallEvent_openLpEventPath( lpIndex, eventType ); + ++lpEventHandlerPaths[eventType]; + rc = 0; + } + return rc; +} + +int HvLpEvent_closePath( HvLpEvent_Type eventType, HvLpIndex lpIndex ) +{ + int rc = 1; + if ( eventType < HvLpEvent_Type_NumTypes && + lpEventHandler[eventType] && + lpEventHandlerPaths[eventType] ) { + if ( lpIndex == 0 ) + lpIndex = itLpNaca.xLpIndex; + HvCallEvent_closeLpEventPath( lpIndex, eventType ); + --lpEventHandlerPaths[eventType]; + rc = 0; + } + return rc; +} + diff -Nru a/arch/ppc/iSeries/ItLpQueue.c b/arch/ppc/iSeries/ItLpQueue.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/ItLpQueue.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,149 @@ +/* + * ItLpQueue.c + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include + +// Array of LpEvent handler functions +extern LpEventHandler lpEventHandler[HvLpEvent_Type_NumTypes]; +u64 ItLpQueueInProcess = 0; + +struct HvLpEvent * ItLpQueue_getNextLpEvent( struct ItLpQueue * lpQueue ) +{ + struct HvLpEvent * nextLpEvent = + (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; + if ( nextLpEvent->xFlags.xValid ) { + // Set pointer to next potential event + lpQueue->xSlicCurEventPtr += ((nextLpEvent->xSizeMinus1 + + LpEventAlign ) / + LpEventAlign ) * + LpEventAlign; + // Wrap to beginning if no room at end + if (lpQueue->xSlicCurEventPtr > lpQueue->xSlicLastValidEventPtr) + lpQueue->xSlicCurEventPtr = lpQueue->xSlicEventStackPtr; + } + else + nextLpEvent = NULL; + + return nextLpEvent; +} + +int ItLpQueue_isLpIntPending( struct ItLpQueue * lpQueue ) +{ + struct HvLpEvent * nextLpEvent = + (struct HvLpEvent *)lpQueue->xSlicCurEventPtr; + return ( nextLpEvent->xFlags.xValid | + lpQueue->xPlicOverflowIntPending); +} + +void ItLpQueue_clearValid( struct HvLpEvent * event ) +{ + // Clear the valid bit of the event + // Also clear bits within this event that might + // look like valid bits (on 64-byte boundaries) + unsigned extra = (( event->xSizeMinus1 + LpEventAlign ) / + LpEventAlign ) - 1; + switch ( extra ) { + case 3: + ((struct HvLpEvent*)((char*)event+3*LpEventAlign))->xFlags.xValid=0; + case 2: + ((struct HvLpEvent*)((char*)event+2*LpEventAlign))->xFlags.xValid=0; + case 1: + ((struct HvLpEvent*)((char*)event+1*LpEventAlign))->xFlags.xValid=0; + case 0: + } + mb(); + event->xFlags.xValid = 0; +} + +// No lock is necessary when processing the Lp Queue because a single +// processor is assigned to each lpqueue. Interrupts are disabled +// while processing events. +// Some device drivers' interrupt handlers run with interrupts +// enabled. This requires us to prevent being re-entered here. +// We use the xInUse flag for that. + +unsigned ItLpQueue_process( struct ItLpQueue * lpQueue, struct pt_regs *regs ) +{ + unsigned numIntsProcessed = 0; + struct HvLpEvent * nextLpEvent; + + // If we have recursed, just return + if ( lpQueue->xInUse ) + return 0; + + lpQueue->xInUse = 1; + + if (ItLpQueueInProcess == 0) + ItLpQueueInProcess = 1; + else + BUG(); + + for (;;) { + nextLpEvent = ItLpQueue_getNextLpEvent( lpQueue ); + + if ( nextLpEvent ) { + // Count events to return to caller + // and count processed events in lpQueue + ++numIntsProcessed; + lpQueue->xLpIntCount++; + // Call appropriate handler here, passing + // a pointer to the LpEvent. The handler + // must make a copy of the LpEvent if it + // needs it in a bottom half. (perhaps for + // an ACK) + + // Handlers are responsible for ACK processing + + // The Hypervisor guarantees that LpEvents will + // only be delivered with types that we have + // registered for, so no type check is necessary + // here! + if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes ) + lpQueue->xLpIntCountByType[nextLpEvent->xType]++; + if ( nextLpEvent->xType < HvLpEvent_Type_NumTypes && + lpEventHandler[nextLpEvent->xType] ) + lpEventHandler[nextLpEvent->xType](nextLpEvent, regs); + else + printk(KERN_INFO "Unexpected Lp Event type=%d\n", nextLpEvent->xType ); + + ItLpQueue_clearValid( nextLpEvent ); + } + else // No more valid events + // If overflow events are pending + // process them + if ( lpQueue->xPlicOverflowIntPending ) { + HvCallEvent_getOverflowLpEvents( + lpQueue->xIndex); + } + else // If nothing left then we are done + break; + } + + lpQueue->xInUse = 0; + + ItLpQueueInProcess = 0; + + return numIntsProcessed; +} diff -Nru a/arch/ppc/iSeries/LparData.c b/arch/ppc/iSeries/LparData.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/LparData.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,332 @@ +/* + * LparData.c + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * 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 + */ + +#define __KERNEL__ 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ReleaseData.h" + +// maxProcessors is the number of physical processors +// The number of logical processors is twice that +// number to support hardware multi-threading. +// If CONFIG_SMP is not defined, then logical +// processors will be defined, but the other threads +// will spin forever in iSeries_head.S +#define maxProcessors 16 + +extern char _start_boltedStacks[]; +unsigned maxPacas = maxProcessors * 2; + +// The LparMap is used by the hypervisor to map the load area. +// This indicates that the load area should be mapped to VSID +// 0x000000000000C and that this should be made addressable at +// ESID 0x00000000C. On 32-bit machines this is equivalent to +// loading segment register 12 with VSID 12. +// 8192 indicates to map 8192 pages (32 MB) of the load area. + +struct LparMap xLparMap = { + xNumberEsids: 4, // Number ESID/VSID pairs + xNumberRanges: 1, // Number of memory ranges + xSegmentTableOffs: 0, // Segment Table Page (unused) + xKernelEsidC: 0xC, // ESID to map + xKernelVsidC: 0xC, // VSID to map + xKernelEsidD: 0xD, // ESID to map + xKernelVsidD: 0xD, // VSID to map + xKernelEsidE: 0xE, // ESID to map + xKernelVsidE: 0xE, // VSID to map + xKernelEsidF: 0xF, // ESID to map + xKernelVsidF: 0xF, // VSID to map + + xPages: HvPagesToMap, // # of pages to map (8192) + xOffset: 0, // Offset into load area + xVPN: 0xC0000 // VPN of first mapped page +}; + +// The Naca has a pointer to the ItVpdAreas. The hypervisor finds +// the Naca via the HvReleaseData area. The HvReleaseData has the +// offset into the Naca of the pointer to the ItVpdAreas. + +extern struct ItVpdAreas itVpdAreas; + +struct Naca xNaca = { + 0, (void *)&itVpdAreas, + 0, 0, // Ram Disk start + 0, 0 // Ram Disk size +}; + +// The LpQueue is used to pass event data from the hypervisor to +// the partition. This is where I/O interrupt events are communicated. +// The ItLpQueue must be initialized (even though only to all zeros) +// If it were uninitialized (in .bss) it would get zeroed after the +// kernel gets control. The hypervisor will have filled in some fields +// before the kernel gets control. By initializing it we keep it out +// of the .bss + +struct ItLpQueue xItLpQueue = {}; + +// The Paca is an array with one entry per processor. Each contains an +// ItLpPaca, which contains the information shared between the +// hypervisor and Linux. Each also contains an ItLpRegSave area which +// is used by the hypervisor to save registers. +// On systems with hardware multi-threading, there are two threads +// per processor. The Paca array must contain an entry for each thread. +// The VPD Areas will give a max logical processors = 2 * max physical +// processors. The processor VPD array needs one entry per physical +// processor (not thread). + +#define PacaInit( n, start, lpq ) \ + { 0, (struct ItLpPaca *)(((char *)(&xPaca[(n)]))+offsetof(struct Paca, xLpPaca)), \ + 0, (struct ItLpRegSave *)(((char *)(&xPaca[(n)]))+offsetof(struct Paca, xRegSav)), \ + 0, 0, 0, \ + (n), (start), \ + 0, \ + 0, \ + 0, 0, 0, 0, 0, 0, {0},\ + (lpq), \ + 0, 0, {0}, \ + { /* LpPaca */ \ + xDesc: 0xd397d781, /* "LpPa" */ \ + xSize: sizeof(struct ItLpPaca), \ + xFPRegsInUse: 1, \ + xDynProcStatus: 2, \ + xEndOfQuantum: 0xffffffffffffffff \ + }, \ + { /* LpRegSave */ \ + 0xd397d9e2, /* "LpRS" */ \ + sizeof(struct ItLpRegSave) \ + } \ + } + +struct Paca xPaca[maxProcessors*2] __bolteddata = { + PacaInit( 0, 1, &xItLpQueue ) + ,PacaInit( 1, 0, 0 ) + ,PacaInit( 2, 0, 0 ) + ,PacaInit( 3, 0, 0 ) + ,PacaInit( 4, 0, 0 ) + ,PacaInit( 5, 0, 0 ) + ,PacaInit( 6, 0, 0 ) + ,PacaInit( 7, 0, 0 ) + ,PacaInit( 8, 0, 0 ) + ,PacaInit( 9, 0, 0 ) + ,PacaInit( 10, 0, 0 ) + ,PacaInit( 11, 0, 0 ) + ,PacaInit( 12, 0, 0 ) + ,PacaInit( 13, 0, 0 ) + ,PacaInit( 14, 0, 0 ) + ,PacaInit( 15, 0, 0 ) + ,PacaInit( 16, 0, 0 ) + ,PacaInit( 17, 0, 0 ) + ,PacaInit( 18, 0, 0 ) + ,PacaInit( 19, 0, 0 ) + ,PacaInit( 20, 0, 0 ) + ,PacaInit( 21, 0, 0 ) + ,PacaInit( 22, 0, 0 ) + ,PacaInit( 23, 0, 0 ) + ,PacaInit( 24, 0, 0 ) + ,PacaInit( 25, 0, 0 ) + ,PacaInit( 26, 0, 0 ) + ,PacaInit( 27, 0, 0 ) + ,PacaInit( 28, 0, 0 ) + ,PacaInit( 29, 0, 0 ) + ,PacaInit( 30, 0, 0 ) + ,PacaInit( 31, 0, 0 ) +}; + + + +// The HvReleaseData is the root of the information shared between +// the hypervisor and Linux. + +struct HvReleaseData + hvReleaseData = { 0xc8a5d9c4, // desc = "HvRD" ebcdic + sizeof(struct HvReleaseData), + offsetof(struct Naca, xItVpdAreas64), + 0, &xNaca, // 64-bit Naca address + ((u32)&xLparMap-KERNELBASE), + 0, + 1, // tags inactive mode + 1, // 32-bit mode + 0, // shared processors + 0, // hardware multithreading + 6, // TEMP: set me back to 0 + // this allows non-ga 450 driver + 3, // We are v5r1m0 + 3, // Min supported PLIC = v5r1m0 + 3, // Min usuable PLIC = v5r1m0 + RELEASEDATA, + {0} + }; + + +struct ItLpNaca itLpNaca = { 0xd397d581, // desc = "LpNa" ebcdic + 0x0400, // size of ItLpNaca + 0x0300, 19, // offset to int array, # ents + 0, 0, 0, // Part # of primary, serv, me + 0, 0x100, // # of LP queues, offset + 0, 0, 0, // Piranha stuff + { 0,0,0,0,0 }, // reserved + 0,0,0,0,0,0,0, // stuff + { 0,0,0,0,0 }, // reserved + 0, // reserved + 0, // VRM index of PLIC + 0, 0, // min supported, compat SLIC + 0, // 64-bit addr of load area + 0, // chunks for load area + 0, // reserved + { 0 }, // 72 reserved bytes + { 0 }, // 128 reserved bytes + { 0 }, // Old LP Queue + { 0 }, // 384 reserved bytes + { + 0xc0000100, // int 0x100 + 0xc0000200, // int 0x200 + 0xc0000300, // int 0x300 + 0xc0000400, // int 0x400 + 0xc0000500, // int 0x500 + 0xc0000600, // int 0x600 + 0xc0000700, // int 0x700 + 0xc0000800, // int 0x800 + 0xc0000900, // int 0x900 + 0xc0000a00, // int 0xa00 + 0xc0000b00, // int 0xb00 + 0xc0000c00, // int 0xc00 + 0xc0000d00, // int 0xd00 + 0xc0000e00, // int 0xe00 + 0xc0000f00, // int 0xf00 + 0xc0001000, // int 0x1000 + 0xc0001010, // int 0x1010 + 0xc0001020, // int 0x1020 CPU ctls + 0xc0000500 // SC Ret Hdlr + // int 0x380 + // int 0x480 + } + }; + +// All of the data structures that will be filled in by the hypervisor +// must be initialized (even if only to zeroes) to keep them out of +// the bss. If in bss, they will be zeroed by the kernel startup code +// after the hypervisor has filled them in. + +struct ItIplParmsReal xItIplParmsReal = {}; + +struct IoHriProcessorVpd xIoHriProcessorVpd[maxProcessors] = { + { + xTimeBaseFreq: 50000000 + } +}; + + +u64 xMsVpd[3400] = {}; // Space for Main Store Vpd 27,200 bytes + +u64 xRecoveryLogBuffer[32] = {}; // Space for Recovery Log Buffer + +struct SpCommArea xSpCommArea = { + 0xE2D7C3C2, + 1, + {0}, + 0, 0, 0, 0, {0} +}; + +struct ItVpdAreas itVpdAreas = { + 0xc9a3e5c1, // "ItVA" + sizeof( struct ItVpdAreas ), + 0, 0, + 26, // # VPD array entries + 10, // # DMA array entries + maxProcessors*2, maxProcessors, // Max logical, physical procs + offsetof(struct ItVpdAreas,xPlicDmaToks),// offset to DMA toks + offsetof(struct ItVpdAreas,xSlicVpdAdrs),// offset to VPD addrs + offsetof(struct ItVpdAreas,xPlicDmaLens),// offset to DMA lens + offsetof(struct ItVpdAreas,xSlicVpdLens),// offset to VPD lens + 0, // max slot labels + 1, // max LP queues + {0}, {0}, // reserved + {0}, // DMA lengths + {0}, // DMA tokens + { // VPD lengths + 0,0,0,0, // 0 - 3 + sizeof(struct Paca), // 4 length of Paca + 0, // 5 + sizeof(struct ItIplParmsReal),// 6 length of IPL parms + 26992, // 7 length of MS VPD + 0, // 8 + sizeof(struct ItLpNaca),// 9 length of LP Naca + 0, // 10 + 256, // 11 length of Recovery Log Buf + sizeof(struct SpCommArea), // 12 length of SP Comm area + 0,0,0, // 13 - 15 + sizeof(struct IoHriProcessorVpd),// 16 length of Proc Vpd + 0,0,0,0,0,0, // 17 - 22 + sizeof(struct ItLpQueue),// 23 length of Lp Queue + 0,0 // 24 - 25 + }, + { // VPD addresses + {0},{0},{0},{0}, // 0 - 3 + {0, &xPaca[0]}, // 4 first Paca + {0}, // 5 + {0, &xItIplParmsReal}, // 6 IPL parms + {0, &xMsVpd}, // 7 MS Vpd + {0}, // 8 + {0, &itLpNaca}, // 9 LpNaca + {0}, // 10 + {0, &xRecoveryLogBuffer},// 11 Recovery Log Buffer + {0, &xSpCommArea}, // 12 Sp Comm Area + {0},{0},{0}, // 13 - 15 + {0, &xIoHriProcessorVpd},// 16 Proc Vpd + {0},{0},{0},{0},{0},{0},// 17 - 22 + {0, &xItLpQueue}, // 23 Lp Queue + {0},{0} + } + +}; + +// The size of this array determines how much main store can be +// configured for use in the partition. 4096 allows 4096 * 256KB +// which is 1GB. This is enough for the 32-bit +// implementation, but the msChunks array will need to be dynamically +// allocated for really big partitions. +u32 msChunks[4096] __bolteddata = {0}; +u32 totalLpChunks __bolteddata = 0; + +// Data area used in flush_hash_page +long long flush_hash_page_hpte[2] __bolteddata = {0,0}; + +u64 virt_to_absolute_outline(u32 address) +{ + return virt_to_absolute(address); +} diff -Nru a/arch/ppc/iSeries/Makefile b/arch/ppc/iSeries/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/Makefile Sat Jun 16 06:00:31 2001 @@ -0,0 +1,26 @@ +# +# Makefile for Linux arch/ppc/iSeries source directory +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# +# Note 2! The CFLAGS definitions are now in the main makefile... + +O_TARGET := iSeries.o +export-objs := iSeries_ksyms.o +obj-y += LparData.o ItLpQueue.o HvLpEvent.o HvCall.o mf.o viopath.o iSeries_proc.o mf_proc.o iSeries_ksyms.o HvLpConfig.o pmc_proc.o rtc.o + +obj-$(CONFIG_PCI) += XmPciLpEvent.o iSeries_FlightRecorder.o iSeries_IoMmTable.o iSeries_VpdInfo.o iSeries_fixup.o iSeries_irq.o iSeries_pci.o iSeries_pci_proc.o iSeries_reset_device.o + +all: iSeries.o + +LparData.c:: ReleaseData.h + +ReleaseData.h: $(TOPDIR)/Makefile + /bin/bash ./createReleaseData $(KERNELRELEASE) > $@ + +clean: + rm -f ReleaseData.h + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/iSeries/XmPciLpEvent.c b/arch/ppc/iSeries/XmPciLpEvent.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/XmPciLpEvent.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,150 @@ +/* + * File XmPciLpEvent.h created by Wayne Holm on Mon Jan 15 2001. + * + * This module handles PCI interrupt events sent by the AS400 Hypervisor. +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + + +enum XmPciLpEvent_Subtype { + XmPciLpEvent_BusCreated = 0, // PHB has been created + XmPciLpEvent_BusFailed = 1, // PHB has failed + XmPciLpEvent_BusRecovered = 12, // PHB has been recovered + XmPciLpEvent_NodeFailed = 4, // Multi-adapter bridge has failed + XmPciLpEvent_NodeRecovered = 5, // Multi-adapter bridge has recovered + XmPciLpEvent_SlotInterrupt = 22 // Slot interrupt +}; + +struct XmPciLpEvent_BusInterrupt { + HvBusNumber busNumber; + HvSubBusNumber subBusNumber; +}; + +struct XmPciLpEvent_NodeInterrupt { + HvBusNumber busNumber; + HvSubBusNumber subBusNumber; + HvAgentId deviceId; +}; + +struct XmPciLpEvent { + struct HvLpEvent hvLpEvent; + + union { + u64 alignData; // Align on an 8-byte boundary + + struct { + u32 fisr; + HvBusNumber busNumber; + HvSubBusNumber subBusNumber; + HvAgentId deviceId; + } slotInterrupt; + + struct XmPciLpEvent_BusInterrupt busFailed; + struct XmPciLpEvent_BusInterrupt busRecovered; + struct XmPciLpEvent_BusInterrupt busCreated; + + struct XmPciLpEvent_NodeInterrupt nodeFailed; + struct XmPciLpEvent_NodeInterrupt nodeRecovered; + + } eventData; + +}; + +static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm); + +static void XmPciLpEvent_handler( struct HvLpEvent* eventParm, struct pt_regs* regsParm) { + if (eventParm && eventParm->xType == HvLpEvent_Type_PciIo) { + switch( eventParm->xFlags.xFunction ) { + case HvLpEvent_Function_Int: + intReceived( (struct XmPciLpEvent*)eventParm, regsParm ); + break; + case HvLpEvent_Function_Ack: + printk(KERN_ERR "XmPciLpEvent.c: unexpected ack received\n"); + break; + default: + printk(KERN_ERR "XmPciLpEvent.c: unexpected event function %d\n", + (int)eventParm->xFlags.xFunction); + break; + }; + } + else { + if (event) { + printk(KERN_ERR "XmPciLpEvent.c: unrecognized event type 0x%x\n", + (int)eventParm->xType); + } + else { + printk(KERN_ERR "XmPciLpEvent.c: NULL event received\n"); + } + } +} + +static void intReceived(struct XmPciLpEvent* eventParm, struct pt_regs* regsParm) { + int irq; + + switch (eventParm->hvLpEvent.xSubtype) { + case XmPciLpEvent_SlotInterrupt: + irq = eventParm->hvLpEvent.xCorrelationToken; + /* Dispatch the interrupt handlers for this irq */ + ppc_irq_dispatch_handler(regsParm, irq); + HvCallPci_eoi(eventParm->eventData.slotInterrupt.busNumber, + eventParm->eventData.slotInterrupt.subBusNumber, + eventParm->eventData.slotInterrupt.deviceId); + break; + /* Ignore error recovery events for now */ + case XmPciLpEvent_BusCreated: + printk(KERN_INFO "XmPciLpEvent.c: system bus %d created\n", eventParm->eventData.busCreated.busNumber); + break; + case XmPciLpEvent_BusFailed: + printk(KERN_INFO "XmPciLpEvent.c: system bus %d failed\n", eventParm->eventData.busFailed.busNumber); + break; + case XmPciLpEvent_BusRecovered: + printk(KERN_INFO "XmPciLpEvent.c: system bus %d recovered\n", eventParm->eventData.busRecovered.busNumber); + break; + case XmPciLpEvent_NodeFailed: + printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d failed\n", eventParm->eventData.nodeFailed.busNumber, eventParm->eventData.nodeFailed.subBusNumber, eventParm->eventData.nodeFailed.deviceId); + break; + case XmPciLpEvent_NodeRecovered: + printk(KERN_INFO "XmPciLpEvent.c: multi-adapter bridge %d/%d/%d recovered\n", eventParm->eventData.nodeRecovered.busNumber, eventParm->eventData.nodeRecovered.subBusNumber, eventParm->eventData.nodeRecovered.deviceId); + break; + default: + printk(KERN_ERR "XmPciLpEvent.c: unrecognized event subtype 0x%x\n", + eventParm->hvLpEvent.xSubtype); + break; + }; +} + + +/* This should be called sometime prior to buswalk (init_IRQ would be good) */ +int XmPciLpEvent_init() { + int xRc; + + xRc = HvLpEvent_registerHandler(HvLpEvent_Type_PciIo, &XmPciLpEvent_handler); + if (xRc == 0) { + xRc = HvLpEvent_openPath(HvLpEvent_Type_PciIo, 0); + if (xRc != 0) { + printk(KERN_ERR "XmPciLpEvent.c: open event path failed with rc 0x%x\n", xRc); + } + } + else { + printk(KERN_ERR "XmPciLpEvent.c: register handler failed with rc 0x%x\n", xRc); + } + + return xRc; +} + diff -Nru a/arch/ppc/iSeries/createReleaseData b/arch/ppc/iSeries/createReleaseData --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/createReleaseData Sat Jun 16 06:00:31 2001 @@ -0,0 +1,115 @@ +#!/bin/bash +#################################################### +# Build a hex ebcdic representation of the +# KERNELRELEASE for use in the iSeries +# hvReleaseData structure +#################################################### + +if [ $# -ne 1 ] +then + echo "Syntax: createReleaseData kernelversion" + exit 1 +fi + +len=${#1} + +rd='' +#################################################### +# ReleaseData is maximum of 12 chars +#################################################### +if [ $len -gt 12 ] +then + len=12 +fi + +#for (( i=0 ; $i < $len ; i=$i+1 )) ; +i=0 +while (($i<$len)); +do + char=${1:$i:1} + case $char in + 'a') xchar='0x81';; + 'b') xchar='0x82';; + 'c') xchar='0x83';; + 'd') xchar='0x84';; + 'e') xchar='0x85';; + 'f') xchar='0x86';; + 'g') xchar='0x87';; + 'h') xchar='0x88';; + 'i') xchar='0x89';; + 'j') xchar='0x91';; + 'k') xchar='0x92';; + 'l') xchar='0x93';; + 'm') xchar='0x94';; + 'n') xchar='0x95';; + 'o') xchar='0x96';; + 'p') xchar='0x97';; + 'q') xchar='0x98';; + 'r') xchar='0x99';; + 's') xchar='0xA2';; + 't') xchar='0xA3';; + 'u') xchar='0xA4';; + 'v') xchar='0xA5';; + 'w') xchar='0xA6';; + 'x') xchar='0xA7';; + 'y') xchar='0xA8';; + 'z') xchar='0xA9';; + 'A') xchar='0xC1';; + 'B') xchar='0xC2';; + 'C') xchar='0xC3';; + 'D') xchar='0xC4';; + 'E') xchar='0xC5';; + 'F') xchar='0xC6';; + 'G') xchar='0xC7';; + 'H') xchar='0xC8';; + 'I') xchar='0xC9';; + 'J') xchar='0xD1';; + 'K') xchar='0xD2';; + 'L') xchar='0xD3';; + 'M') xchar='0xD4';; + 'N') xchar='0xD5';; + 'O') xchar='0xD6';; + 'P') xchar='0xD7';; + 'Q') xchar='0xD8';; + 'R') xchar='0xD9';; + 'S') xchar='0xE2';; + 'T') xchar='0xE3';; + 'U') xchar='0xE4';; + 'V') xchar='0xE5';; + 'W') xchar='0xE6';; + 'X') xchar='0xE7';; + 'Y') xchar='0xE8';; + 'Z') xchar='0xE9';; + '0') xchar='0xF0';; + '1') xchar='0xF1';; + '2') xchar='0xF2';; + '3') xchar='0xF3';; + '4') xchar='0xF4';; + '5') xchar='0xF5';; + '6') xchar='0xF6';; + '7') xchar='0xF7';; + '8') xchar='0xF8';; + '9') xchar='0xF9';; + '.') xchar='0x4B';; + '-') xchar='0x60';; + '_') xchar='0x6D';; + '+') xchar='0x4E';; + '@') xchar='0x7C';; + '$') xchar='0x5B';; + '%') xchar='0x6C';; + *) xchar='';; + esac + + rd=${rd}${xchar} + if [ $(($i+1)) -lt $len ] + then + rd=${rd}', ' + fi + i=$i+1 +done + +#echo "#define RELEASEDATA { $rd }">ReleaseData.h + +echo "#define RELEASEDATA { $rd }" + + diff -Nru a/arch/ppc/iSeries/iSeries_FlightRecorder.c b/arch/ppc/iSeries/iSeries_FlightRecorder.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/iSeries_FlightRecorder.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,89 @@ +/************************************************************************/ +/* File iSeries_FlightRecorder.c created by Al Trautman on Jan 22 2001. */ +/************************************************************************/ +/* This code supports the pci interface on the IBM iSeries systems. */ +/* Copyright (C) 20yy */ +/* */ +/* 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 */ +/************************************************************************/ +/* Change Activity: */ +/* Created, Jan 22, 2001 */ +/* Added Time Stamps, April 12, 2001 */ +/* End Change Activity */ +/************************************************************************/ +#include +#include +#include +#include +#include +/************************************************************************/ +/* Log entry into buffer, */ +/* ->If entry is going to wrap, log "WRAP" and start at the top. */ +/************************************************************************/ +void iSeries_LogFr_Entry(FlightRecorder* Fr, char* LogText) { + int Residual, TextLen; + if(Fr->StartingPointer > 0) { /* Initialized yet? */ + Residual = FlightRecorderSize - (Fr->CurrentPointer - Fr->StartingPointer); + TextLen = strlen(LogText); /* Length of Text */ + if(TextLen+16 > Residual) { /* Room for text or need to wrap*/ + strcpy(Fr->CurrentPointer,"WRAP"); + ++Fr->WrapCount; /* Increment Wraps */ + Fr->CurrentPointer = Fr->StartingPointer; + } + strcpy(Fr->CurrentPointer,LogText); + Fr->CurrentPointer += TextLen+1; + strcpy(Fr->CurrentPointer,"<="); + } +} +/************************************************************************/ +/* Log entry with time */ +/************************************************************************/ +void iSeries_LogFr_Time(FlightRecorder* Fr, char* LogText) { + struct rtc_time Rtc; + char LogBuffer[256]; + mf_getRtc(&Rtc); + sprintf(LogBuffer,"%02d:%02d:%02d %s", + Rtc.tm_hour,Rtc.tm_min,Rtc.tm_sec, + LogText); + iSeries_LogFr_Entry(Fr,LogBuffer); +} +/************************************************************************/ +/* Log Entry with Date and call Time Log */ +/************************************************************************/ +void iSeries_LogFr_Date(FlightRecorder* Fr, char* LogText) { + struct rtc_time Rtc; + char LogBuffer[256]; + mf_getRtc(&Rtc); + sprintf(LogBuffer,"%02d.%02d.%02d %02d:%02d:%02d %s", + Rtc.tm_year+1900, Rtc.tm_mon, Rtc.tm_mday, + Rtc.tm_hour,Rtc.tm_min,Rtc.tm_sec, + LogText); + iSeries_LogFr_Entry(Fr,LogBuffer); +} +/************************************************************************/ +/* Initialized the Flight Recorder */ +/************************************************************************/ +void iSeries_Fr_Initialize(FlightRecorder* Fr, char* Signature) { + if(strlen(Signature) > 16) memcpy(Fr->Signature,Signature,16); + else strcpy(Fr->Signature,Signature); + Fr->StartingPointer = &Fr->Buffer[0]; + Fr->CurrentPointer = Fr->StartingPointer; + Fr->logEntry = iSeries_LogFr_Entry; + Fr->logDate = iSeries_LogFr_Date; + Fr->logTime = iSeries_LogFr_Time; + Fr->logEntry(Fr,"FR Initialized."); /* Note, can't use time yet! */ +} diff -Nru a/arch/ppc/iSeries/iSeries_IoMmTable.c b/arch/ppc/iSeries/iSeries_IoMmTable.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/iSeries_IoMmTable.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,206 @@ +/************************************************************************/ +/* This module supports the iSeries I/O Address translation mapping */ +/* Copyright (C) 20yy */ +/* */ +/* 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 */ +/************************************************************************/ +/* Change Activity: */ +/* Created, December 14, 2000 */ +/* Added Bar table for IoMm performance. */ +/* End Change Activity */ +/************************************************************************/ +#include +#include +#include +#include +#include +#include + +#include "iSeries_IoMmTable.h" +#include "iSeries_pci.h" + +void iSeries_allocateDeviceBars(struct pci_dev* PciDevPtr); +/*******************************************************************/ +/* Table defines */ +/* Entry size is 4 MB * 1024 Entries = 4GB. */ +/*******************************************************************/ +#define iSeries_IoMmTable_Entry_Size 0x00400000 +#define iSeries_IoMmTable_Size 1024 +#define iSeries_Base_Io_Memory 0xFFFFFFFF + +/*******************************************************************/ +/* Static and Global variables */ +/*******************************************************************/ +struct pci_dev* iSeries_IoMmTable[iSeries_IoMmTable_Size]; +u8 iSeries_IoBarTable[iSeries_IoMmTable_Size]; +static int iSeries_CurrentIndex; +static char* iSeriesPciIoText = "iSeries PCI I/O"; +static spinlock_t iSeriesIoMmTableLock = SPIN_LOCK_UNLOCKED; +/*******************************************************************/ +/* iSeries_IoMmTable_Initialize */ +/*******************************************************************/ +/* - Initalizes the Address Translation Table and get it ready for */ +/* use. Must be called before any client calls any of the other */ +/* methods. */ +/*******************************************************************/ +void iSeries_IoMmTable_Initialize(void) { + int Index; + spin_lock(&iSeriesIoMmTableLock); + for(Index=0;Index 0) { + printk("PCI: iSeries_allocateDeviceBars 0x%08X\n",(int)PciDevPtr); + sprintf(PciFrBuffer,"IoBars %08X",(int)PciDevPtr); + ISERIES_PCI_FR(PciFrBuffer); + } + for(BarNumber = 0; BarNumber <= PCI_ROM_RESOURCE; ++BarNumber) { + BarResource = &PciDevPtr->resource[BarNumber]; + iSeries_IoMmTable_AllocateEntry(PciDevPtr, BarNumber); + } +} + +/*******************************************************************/ +/* iSeries_IoMmTable_AllocateEntry */ +/*******************************************************************/ +/* Adds pci_dev entry in address translation table */ +/*******************************************************************/ +/* - Allocates the number of entries required in table base on BAR */ +/* size. */ +/* - This version, allocates top down, starting at 4GB. */ +/* - The size is round up to be a multiple of entry size. */ +/* - CurrentIndex is decremented to keep track of the last entry. */ +/* - Builds the resource entry for allocated BARs. */ +/*******************************************************************/ +void iSeries_IoMmTable_AllocateEntry(struct pci_dev* PciDevPtr, u32 BarNumber) { + struct resource* BarResource = &PciDevPtr->resource[BarNumber]; + int BarSize = BarResource->end - BarResource->start; + u32 BarStartAddr; + u32 BarEndAddr; + /***************************************************************/ + /* No space to allocate, skip Allocation. */ + /***************************************************************/ + if(BarSize == 0) return; /* Quick stage exit */ + + /***************************************************************/ + /* Allocate the table entries needed. */ + /***************************************************************/ + spin_lock(&iSeriesIoMmTableLock); + while(BarSize > 0) { + iSeries_IoMmTable[iSeries_CurrentIndex] = PciDevPtr; + iSeries_IoBarTable[iSeries_CurrentIndex] = BarNumber; + BarSize -= iSeries_IoMmTable_Entry_Size; + --iSeries_CurrentIndex; /* Next Free entry */ + } + spin_unlock(&iSeriesIoMmTableLock); + BarStartAddr = iSeries_IoMmTable_Entry_Size*(iSeries_CurrentIndex+1); + BarEndAddr = BarStartAddr + (u32)(BarResource->end - BarResource->start); + /***************************************************************/ + /* Build Resource info */ + /***************************************************************/ + BarResource->name = iSeriesPciIoText; + BarResource->start = (long)BarStartAddr; + BarResource->end = (long)BarEndAddr; + + /***************************************************************/ + /* Tracing */ + /***************************************************************/ + if(PciTraceFlag > 0) { + printk("PCI: BarAloc %04X-%08X-%08X\n",iSeries_CurrentIndex+1,(int)BarStartAddr, (int)BarEndAddr); + sprintf(PciFrBuffer,"IoMmAloc %04X-%08X-%08X", + iSeries_CurrentIndex+1,(int)BarStartAddr, (int)BarEndAddr); + ISERIES_PCI_FR(PciFrBuffer); + } +} +/*******************************************************************/ +/* Translates an I/O Memory address to pci_dev* */ +/*******************************************************************/ +struct pci_dev* iSeries_xlateIoMmAddress(u32* IoAddress) { + int PciDevIndex; + struct pci_dev* PciDevPtr; + PciDevIndex = (u32)IoAddress/iSeries_IoMmTable_Entry_Size; + PciDevPtr = iSeries_IoMmTable[PciDevIndex]; + if(PciDevPtr == 0) { + printk("PCI: Invalid I/O Address: 0x%08X\n",(int)IoAddress); + sprintf(PciFrBuffer,"Invalid MMIO Address 0x%08X",(int)IoAddress); + ISERIES_PCI_FR(PciFrBuffer); + } + return PciDevPtr; +} +/************************************************************************/ +/* Returns the Bar number of Address */ +/************************************************************************/ +int iSeries_IoMmTable_Bar(u32 *IoAddress) { + int BarIndex = (u32)IoAddress/iSeries_IoMmTable_Entry_Size; + int BarNumber = iSeries_IoBarTable[BarIndex]; + return BarNumber; +} +/************************************************************************/ +/* Return the Bar Base Address or 0. */ +/************************************************************************/ +u32* iSeries_IoMmTable_BarBase(u32 *IoAddress) { + u32 BaseAddr = -1; + pciDev* PciDev = iSeries_xlateIoMmAddress(IoAddress); + if(PciDev != 0) { + int BarNumber = iSeries_IoMmTable_Bar(IoAddress); + if(BarNumber != -1) { + BaseAddr = (&PciDev->resource[BarNumber])->start; + } + } + return (u32*)BaseAddr; +} +/************************************************************************/ +/* Return the Bar offset within the Bar Space */ +/* Note: Assumes that address is valid. */ +/************************************************************************/ +u32 iSeries_IoMmTable_BarOffset(u32* IoAddress) { + u32 BaseAddr = (u32)iSeries_IoMmTable_BarBase(IoAddress); + return (u32)IoAddress-BaseAddr; +} +/************************************************************************/ +/* Return 0 if Address is valid I/O Address */ +/************************************************************************/ +int iSeries_Is_IoMmAddress(unsigned long IoAddress) { + if( iSeries_IoMmTable_Bar((u32*)IoAddress) == -1) return 1; + else return 0; +} +/************************************************************************/ +/* Helper Methods to get TableSize and TableSizeEntry. */ +/************************************************************************/ +u32 iSeries_IoMmTable_TableEntrySize(void) { return iSeries_IoMmTable_Entry_Size; } +u32 iSeries_IoMmTable_TableSize(void) { return iSeries_IoMmTable_Size; } + + diff -Nru a/arch/ppc/iSeries/iSeries_IoMmTable.h b/arch/ppc/iSeries/iSeries_IoMmTable.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/iSeries_IoMmTable.h Sat Jun 16 06:00:30 2001 @@ -0,0 +1,105 @@ +#ifndef _ISERIES_IOMMTABLE_H +#define _ISERIES_IOMMTABLE_H +/************************************************************************/ +/* File iSeries_IoMmTable.h created by Allan Trautman on Dec 12 2001. */ +/************************************************************************/ +/* Interfaces for the write/read Io address translation table. */ +/* Copyright (C) 20yy Allan H Trautman, IBM Corporation */ +/* */ +/* 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 */ +/************************************************************************/ +/* Change Activity: */ +/* Created December 12, 2000 */ +/* End Change Activity */ +/************************************************************************/ + +/************************************************************************/ +/* iSeries_IoMmTable_Initialize */ +/************************************************************************/ +/* - Initalizes the Address Translation Table and get it ready for use. */ +/* Must be called before any client calls any of the other methods. */ +/* */ +/* Parameters: None. */ +/* */ +/* Return: None. */ +/************************************************************************/ +extern void iSeries_IoMmTable_Initialize(void); + +/************************************************************************/ +/* iSeries_allocateDeviceBars */ +/************************************************************************/ +/* - Allocates ALL pci_dev BAR's and updates the resources with the BAR */ +/* value. BARS with zero length will not have the resources. The */ +/* HvCallPci_getBarParms is used to get the size of the BAR space. */ +/* It calls as400_IoMmTable_AllocateEntry to allocate each entry. */ +/* */ +/* Parameters: */ +/* pci_dev = Pointer to pci_dev structure that will be mapped to pseudo */ +/* I/O Address. */ +/* */ +/* Return: */ +/* The pci_dev I/O resources updated with pseudo I/O Addresses. */ +/************************************************************************/ +extern void iSeries_allocateDeviceBars(struct pci_dev* Device); + +/************************************************************************/ +/* iSeries_IoMmTable_AllocateEntry */ +/************************************************************************/ +/* - Allocates(adds) the pci_dev entry in the Address Translation Table */ +/* and updates the Resources for the device. */ +/* */ +/* Parameters: */ +/* pci_dev = Pointer to pci_dev structure that will be mapped to pseudo */ +/* I/O Address. */ +/* */ +/* BarNumber = Which Bar to be allocated. */ +/* */ +/* Return: */ +/* The pseudo I/O Address in the resources that will map to the */ +/* pci_dev on iSeries_xlateIoMmAddress call. */ +/************************************************************************/ +extern void iSeries_IoMmTable_AllocateEntry(struct pci_dev* Device, u32 BarNumber); + +/************************************************************************/ +/* iSeries_xlateIoMmAddress */ +/************************************************************************/ +/* - Translates an I/O Memory address to pci_dev that has been allocated*/ +/* the psuedo I/O Address. */ +/* */ +/* Parameters: */ +/* IoAddress = I/O Memory Address. */ +/* */ +/* Return: */ +/* A pci_dev pointer to the device mapped to the I/O address. */ +/************************************************************************/ +extern struct pci_dev* iSeries_xlateIoMmAddress(u32* IoAddress); + +/************************************************************************/ +/* Helper Methods */ +/************************************************************************/ +extern int iSeries_IoMmTable_Bar(u32 *IoAddress); +extern u32* iSeries_IoMmTable_BarBase(u32* IoAddress); +extern u32 iSeries_IoMmTable_BarOffset(u32* IoAddress); +extern int iSeries_Is_IoMmAddress(unsigned long address); + +/************************************************************************/ +/* Helper Methods to get TableSize and TableSizeEntry. */ +/************************************************************************/ +extern u32 iSeries_IoMmTable_TableEntrySize(void); +extern u32 iSeries_IoMmTable_TableSize(void); + +#endif /* _ISERIES_IOMMTABLE_H */ diff -Nru a/arch/ppc/iSeries/iSeries_VpdInfo.c b/arch/ppc/iSeries/iSeries_VpdInfo.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/iSeries_VpdInfo.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,339 @@ +/************************************************************************/ +/* File iSeries_vpdInfo.c created by Allan Trautman on Fri Feb 2 2001. */ +/************************************************************************/ +/* This code gets the card location of the hardware */ +/* Copyright (C) 20yy */ +/* */ +/* 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 */ +/************************************************************************/ +/* Change Activity: */ +/* Created, Feb 2, 2001 */ +/* End Change Activity */ +/************************************************************************/ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include "iSeries_pci.h" + +/************************************************/ +/* Size of Bus VPD data */ +/************************************************/ +#define BUS_VPDSIZE 1024 +/************************************************/ +/* Bus Vpd Tags */ +/************************************************/ +#define VpdEndOfDataTag 0x78 +#define VpdEndOfAreaTag 0x79 +#define VpdIdStringTag 0x82 +#define VpdVendorAreaTag 0x84 +/************************************************/ +/* Mfg Area Tags */ +/************************************************/ +#define VpdAsmPartNumber 0x504E // "PN" +#define VpdFruFlag 0x4647 // "FG" +#define VpdFruLocation 0x464C // "FL" +#define VpdFruFrameId 0x4649 // "FI" +#define VpdFruPartNumber 0x464E // "FN" +#define VpdFruPowerData 0x5052 // "PR" +#define VpdFruSerial 0x534E // "SN" +#define VpdFruType 0x4343 // "CC" +#define VpdFruCcinExt 0x4345 // "CE" +#define VpdFruRevision 0x5256 // "RV" +#define VpdSlotMapFormat 0x4D46 // "MF" +#define VpdSlotMap 0x534D // "SM" + +/************************************************/ +/* Structures of the areas */ +/************************************************/ +struct BusVpdAreaStruct { + u8 Tag; + u8 LowLength; + u8 HighLength; +}; +typedef struct BusVpdAreaStruct BusVpdArea; +#define BUS_ENTRY_SIZE 3 + +struct MfgVpdAreaStruct { + u16 Tag; + u8 TagLength; +}; +typedef struct MfgVpdAreaStruct MfgVpdArea; +#define MFG_ENTRY_SIZE 3 + +struct SlotMapFormatStruct { + u16 Tag; + u8 TagLength; + u16 Format; +}; + +struct FrameIdMapStruct{ + u16 Tag; + u8 TagLength; + u8 FrameId; +}; +typedef struct FrameIdMapStruct FrameIdMap; + +struct SlotMapStruct { + u8 AgentId; + u8 SecondaryAgentId; + u8 PhbId; + char CardLocation[3]; + char Parms[8]; + char Reserved[2]; +}; +typedef struct SlotMapStruct SlotMap; +#define SLOT_ENTRY_SIZE 16 + +/****************************************************************/ +/* Prototypes */ +/****************************************************************/ +static void iSeries_Parse_Vpd(BusVpdArea*, int, LocationData*); +static void iSeries_Parse_MfgArea(MfgVpdArea*,int, LocationData*); +static void iSeries_Parse_SlotArea(SlotMap*, int, LocationData*); +static void iSeries_Parse_PhbId(BusVpdArea*, int, LocationData*); + +/****************************************************************/ +/* */ +/* */ +/* */ +/****************************************************************/ +LocationData* iSeries_GetLocationData(struct pci_dev* PciDev) { + LocationData* LocationPtr = 0; + BusVpdArea* BusVpdPtr = 0; + int BusVpdLen = 0; + BusVpdPtr = (BusVpdArea*)kmalloc(BUS_VPDSIZE, GFP_KERNEL); + BusVpdLen = HvCallPci_getBusVpd(ISERIES_GET_LPAR_BUS(PciDev->bus->number),REALADDR(BusVpdPtr),BUS_VPDSIZE); + /* printk("PCI: VpdBuffer 0x%08X \n",(int)BusVpdPtr); */ + /***************************************************************/ + /* Need to set Agent Id, Bus in location info before the call */ + /***************************************************************/ + LocationPtr = (LocationData*)kmalloc(LOCATION_DATA_SIZE, GFP_KERNEL); + LocationPtr->Bus = ISERIES_GET_LPAR_BUS(PciDev->bus->number); + LocationPtr->Board = 0; + LocationPtr->FrameId = 0; + iSeries_Parse_PhbId(BusVpdPtr,BusVpdLen,LocationPtr); + LocationPtr->Card = PCI_SLOT(PciDev->devfn); + strcpy(LocationPtr->CardLocation,"Cxx"); + LocationPtr->AgentId = ISERIES_DECODE_DEVICE(PciDev->devfn); + LocationPtr->SecondaryAgentId = 0x10; + /* And for Reference only. */ + LocationPtr->LinuxBus = PciDev->bus->number; + LocationPtr->LinuxDevFn = PciDev->devfn; + /***************************************************************/ + /* Any data to process? */ + /***************************************************************/ + if(BusVpdLen > 0) { + iSeries_Parse_Vpd(BusVpdPtr, BUS_VPDSIZE, LocationPtr); + } + else { + ISERIES_PCI_FR("No VPD Data...."); + } + kfree(BusVpdPtr); + + return LocationPtr; +} +/****************************************************************/ +/* */ +/****************************************************************/ +void iSeries_Parse_Vpd(BusVpdArea* VpdData,int VpdLen, LocationData* LocationPtr) { + MfgVpdArea* MfgVpdPtr = 0; + int BusTagLen = 0; + BusVpdArea* BusVpdPtr = VpdData; + int BusVpdLen = VpdLen; + /*************************************************************/ + /* Make sure this is what I think it is */ + /*************************************************************/ + if(BusVpdPtr->Tag != VpdIdStringTag) { /*0x82 */ + ISERIES_PCI_FR("Not 0x82 start."); + return; + } + BusTagLen = (BusVpdPtr->HighLength*256)+BusVpdPtr->LowLength; + BusTagLen += BUS_ENTRY_SIZE; + BusVpdPtr = (BusVpdArea*)((u32)BusVpdPtr+BusTagLen); + BusVpdLen -= BusTagLen; + /*************************************************************/ + /* Parse the Data */ + /*************************************************************/ + while(BusVpdLen > 0 ) { + BusTagLen = (BusVpdPtr->HighLength*256)+BusVpdPtr->LowLength; + /*********************************************************/ + /* End of data Found */ + /*********************************************************/ + if(BusVpdPtr->Tag == VpdEndOfAreaTag) { + BusVpdLen = 0; /* Done, Make sure */ + } + /*********************************************************/ + /* Was Mfg Data Found */ + /*********************************************************/ + else if(BusVpdPtr->Tag == VpdVendorAreaTag) { + MfgVpdPtr = (MfgVpdArea*)((u32)BusVpdPtr+BUS_ENTRY_SIZE); + iSeries_Parse_MfgArea(MfgVpdPtr,BusTagLen,LocationPtr); + } + /********************************************************/ + /* On to the next tag. */ + /********************************************************/ + if(BusVpdLen > 0) { + BusTagLen += BUS_ENTRY_SIZE; + BusVpdPtr = (BusVpdArea*)((u32)BusVpdPtr+BusTagLen); + BusVpdLen -= BusTagLen; + } + } +} + +/*****************************************************************/ +/* Parse the Mfg Area */ +/*****************************************************************/ +void iSeries_Parse_MfgArea(MfgVpdArea* VpdDataPtr,int VpdLen, LocationData* LocationPtr) { + SlotMap* SlotMapPtr = 0; + u16 SlotMapFmt = 0; + int MfgTagLen = 0; + MfgVpdArea* MfgVpdPtr = VpdDataPtr; + int MfgVpdLen = VpdLen; + + /*************************************************************/ + /* Parse Mfg Data */ + /*************************************************************/ + while(MfgVpdLen > 0) { + MfgTagLen = MfgVpdPtr->TagLength; + if (MfgVpdPtr->Tag == VpdFruFlag) {} /* FG */ + else if(MfgVpdPtr->Tag == VpdFruSerial) {} /* SN */ + else if(MfgVpdPtr->Tag == VpdAsmPartNumber){} /* PN */ + /*********************************************************/ + /* Frame ID */ + /*********************************************************/ + if(MfgVpdPtr->Tag == VpdFruFrameId) { /* FI */ + LocationPtr->FrameId = ((FrameIdMap*)MfgVpdPtr)->FrameId; + } + /*********************************************************/ + /* Slot Map Format */ + /*********************************************************/ + else if(MfgVpdPtr->Tag == VpdSlotMapFormat){ /* MF */ + SlotMapFmt = ((struct SlotMapFormatStruct*)MfgVpdPtr)->Format; + } + /*********************************************************/ + /* Slot Labels */ + /*********************************************************/ + else if(MfgVpdPtr->Tag == VpdSlotMap){ /* SM */ + if(SlotMapFmt == 0x1004) SlotMapPtr = (SlotMap*)((u32)MfgVpdPtr+MFG_ENTRY_SIZE+1); + else SlotMapPtr = (SlotMap*)((u32)MfgVpdPtr+MFG_ENTRY_SIZE); + iSeries_Parse_SlotArea(SlotMapPtr,MfgTagLen, LocationPtr); + } + /*********************************************************/ + /* Point to the next Mfg Area */ + /* Use defined size, sizeof give wrong answer */ + /*********************************************************/ + MfgTagLen += MFG_ENTRY_SIZE; + MfgVpdPtr = (MfgVpdArea*)( (u32)MfgVpdPtr + MfgTagLen); + MfgVpdLen -= MfgTagLen; + } +} +/*****************************************************************/ +/* Look for "BUS" Tag to set the PhbId. */ +/*****************************************************************/ +void iSeries_Parse_PhbId(BusVpdArea* VpdData,int VpdLen,LocationData* LocationPtr) { + int PhbId = 0xff; /* Not found flag */ + char* PhbPtr = (char*)VpdData+3; /* Skip over 82 tag */ + int DataLen = VpdLen; + while(DataLen > 0) { + if(*PhbPtr == 'B' && *(PhbPtr+1) == 'U' && *(PhbPtr+2) == 'S') { + if(*(PhbPtr+3) == ' ') PhbPtr += 4;/* Skip white spac*/ + else PhbPtr += 3; + if (*PhbPtr == '0') PhbId = 0; /* Don't convert, */ + else if(*PhbPtr == '1') PhbId = 1; /* Sanity check */ + else if(*PhbPtr == '2') PhbId = 2; /* values */ + DataLen = 0; /* Exit loop. */ + } + ++PhbPtr; + --DataLen; + } + LocationPtr->PhbId = PhbId; +} +/*****************************************************************/ +/* Parse the Slot Area */ +/*****************************************************************/ +void iSeries_Parse_SlotArea(SlotMap* MapPtr,int MapLen, LocationData* LocationPtr) { + int SlotMapLen = MapLen; + SlotMap* SlotMapPtr = MapPtr; + /*************************************************************/ + /* Parse Slot label until we find the one requrested */ + /*************************************************************/ + while(SlotMapLen > 0) { + if(SlotMapPtr->AgentId == LocationPtr->AgentId && + SlotMapPtr->SecondaryAgentId == LocationPtr->SecondaryAgentId) { + /*****************************************************/ + /* If Phb wasn't found, grab the first one found. */ + /*****************************************************/ + if(LocationPtr->PhbId == 0xff) LocationPtr->PhbId = SlotMapPtr->PhbId; + if( SlotMapPtr->PhbId == LocationPtr->PhbId ) { + /*****************************************************/ + /* Found what we were looking for, extract the data. */ + /*****************************************************/ + memcpy(&LocationPtr->CardLocation,&SlotMapPtr->CardLocation,3); + LocationPtr->CardLocation[3] = 0; /* Null terminate*/ + SlotMapLen = 0; /* We are done */ + } + } + /*********************************************************/ + /* Point to the next Slot */ + /* Use defined size, sizeof may give wrong answer */ + /*********************************************************/ + SlotMapLen -= SLOT_ENTRY_SIZE; + SlotMapPtr = (SlotMap*)((u32)SlotMapPtr+SLOT_ENTRY_SIZE); + } +} +/************************************************************************/ +/* Formats the device information. */ +/* - Pass in pci_dev* pointer to the device. */ +/* - Pass in buffer to place the data. Danger here is the buffer must */ +/* be as big as the client says it is. Should be at least 128 bytes.*/ +/* Return will the length of the string data put in the buffer. */ +/* Format: */ +/* PCI: Bus 0, Device 26, Vendor 0x12AE iSeries: Bus 2, Device 34, Fr*/ +/* ame 1, Card C10 Ethernet controller */ +/************************************************************************/ +int iSeries_Device_Information(struct pci_dev* PciDev,char* Buffer, int BufferSize) { + LocationData* LocationPtr; /* VPD Information */ + char* BufPtr = Buffer; + int LineLen = 0; + if(BufferSize >= 128) { + LineLen = sprintf(BufPtr+LineLen,"PCI: Bus%3d, Device%3d, Vendor %04X ", + PciDev->bus->number, PCI_SLOT(PciDev->devfn),PciDev->vendor); + + LocationPtr = iSeries_GetLocationData(PciDev); + LineLen += sprintf(BufPtr+LineLen,"iSeries: Bus%3d, Device%3d, Frame%3d, Card %4s ", + LocationPtr->Bus,LocationPtr->AgentId, + LocationPtr->FrameId,LocationPtr->CardLocation); + kfree(LocationPtr); + + if(pci_class_name(PciDev->class >> 8) == 0) { + LineLen += sprintf(BufPtr+LineLen,"0x%04X ",(int)(PciDev->class >> 8)); + } + else { + LineLen += sprintf(BufPtr+LineLen,"%s",pci_class_name(PciDev->class >> 8) ); + } + } + return LineLen; +} diff -Nru a/arch/ppc/iSeries/iSeries_fixup.c b/arch/ppc/iSeries/iSeries_fixup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/iSeries_fixup.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,255 @@ +/************************************************************************/ +/* This module supports the iSeries PCI bus device detection */ +/* Copyright (C) 20yy */ +/* */ +/* 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 */ +/************************************************************************/ +/* Change Activity: */ +/* Created, December 13, 2000 by Wayne Holm */ +/* End Change Activity */ +/************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iSeries_IoMmTable.h" +#include "iSeries_pci.h" + + + +unsigned int __init iSeries_scan_slot(struct pci_dev* temp_dev, + u16 hvBus, u8 slotSubBus, u8 maxAgents) +{ + u8 hvIdSel, hvFunction, hvAgentId; + u64 hvRc = 0; + u64 noConnectRc = 0xFFFF; + HvAgentId slotAgentId; + int irq; + + slotAgentId = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(slotSubBus), ISERIES_GET_FUNCTION_FROM_SUBBUS(slotSubBus)); + irq = iSeries_allocate_IRQ(hvBus, 0, slotAgentId); + for (hvIdSel = 1; hvIdSel <= maxAgents; ++hvIdSel) { + /* Connect all functions of any device found. However, only call pci_scan_slot + once for each idsel. pci_scan_slot handles multifunction devices appropriately */ + for (hvFunction = 0; hvFunction < 8 && hvRc == 0; ++hvFunction) { + hvAgentId = ISERIES_PCI_AGENTID(hvIdSel, hvFunction); + hvRc = HvCallXm_connectBusUnit(hvBus, slotSubBus, hvAgentId, irq); + if (hvRc == 0) { + noConnectRc = 0; + HvCallPci_configStore8(hvBus, slotSubBus, hvAgentId, PCI_INTERRUPT_LINE, irq); // Store the irq in the interrupt line register of the function config space + } + } + if (noConnectRc == 0) { + /* This assumes that the node slot is always on the primary bus! */ + temp_dev->devfn = ISERIES_ENCODE_SUBBUS(ISERIES_GET_DEVICE_FROM_SUBBUS(slotSubBus), + ISERIES_GET_FUNCTION_FROM_SUBBUS(slotSubBus), + 0); + iSeries_assign_IRQ(irq, hvBus, 0, slotAgentId); + pci_scan_slot(temp_dev); + } + } + return 0; +} + +void __init iSeries_fixup_bus(struct pci_bus* bus) +{ + struct pci_dev temp_dev; + struct pci_controller* hose; + u16 hvBus; + u8 hvSubBus, hvIdSel, hvFunction, hvAgentId, maxAgents, irq; + u64 hvRc, devInfoRealAdd, bridgeInfoRealAdd; + struct HvCallPci_DeviceInfo* devInfo; + struct HvCallPci_BridgeInfo* bridgeInfo; + u64 noConnectRc = 0xFFFF; + + hose = (struct pci_controller*)(bus->sysdata); + /* Get the hv bus number from the hose arch_data */ + hvBus = ISERIES_GET_HOSE_HV_BUSNUM(hose); + /* Initialize the global bus number map for this bus */ + iSeries_GlobalBusMap[bus->number][_HVBUSNUMBER_] = hvBus; + iSeries_GlobalBusMap[bus->number][_HVSUBBUSNUMBER_] = 0; + maxAgents = 7; + /* If not a primary bus, set the hypervisor subBus number of this bus into the map */ + if (bus->parent != NULL) { + bridgeInfo = kmalloc(sizeof(*bridgeInfo), GFP_KERNEL); + /* Perform linux virtual address to iSeries PLIC real address translation */ + bridgeInfoRealAdd = virt_to_absolute((u32)bridgeInfo); + bridgeInfoRealAdd = bridgeInfoRealAdd | 0x8000000000000000; + /* Find the Hypervisor address of the bridge which created this bus... */ + if (ISERIES_IS_SUBBUS_ENCODED_IN_DEVFN(bus->self->devfn)) { // This assumes that the bus passed to this function is connected to an EADS slot. The subbus encoding algorithm only applies to bridge cards attached directly to EADS. Future TODO is to allow for n levels of bridging. + hvSubBus = ISERIES_DEVFN_DECODE_SUBBUS(bus->self->devfn); + hvIdSel = 1; + } + else { + /* The hose arch_data needs to map Linux bus number -> PHB bus/subBus number + Could also use a global table, might be cheaper for multiple PHBs */ + // hvSubBus = iSeries_GlobalBusMap[bus->parent->number][_HVSUBBUSNUMBER_]; + hvSubBus = 0; // The bridge card devfn is not subbus encoded and is directly attached to the PCI primary bus. Its subbus number is 0 and the card config space is accessed via type 0 config cycles. + hvIdSel = PCI_SLOT(bus->self->devfn); + } + hvAgentId = ISERIES_PCI_AGENTID(hvIdSel, PCI_FUNC(bus->self->devfn)); + /* Now we know the HV bus/subbus/agent of the bridge creating this bus, + go get the subbus number from HV */ + hvRc = HvCallPci_getBusUnitInfo(hvBus, hvSubBus, hvAgentId, + bridgeInfoRealAdd, sizeof(*bridgeInfo)); + if (hvRc != 0 || bridgeInfo->busUnitInfo.deviceType != HvCallPci_BridgeDevice) { + kfree(bridgeInfo); + // return -1; + } + iSeries_GlobalBusMap[bus->number][_HVSUBBUSNUMBER_] = bridgeInfo->subBusNumber; + maxAgents = bridgeInfo->maxAgents; + kfree(bridgeInfo); + } + /* Bus number mapping is complete, from here on cfgIos should result in HvCalls */ + + hvSubBus = iSeries_GlobalBusMap[bus->number][_HVSUBBUSNUMBER_]; + + devInfo = kmalloc(sizeof(*devInfo), GFP_KERNEL); + devInfoRealAdd = virt_to_absolute((u32)devInfo); + devInfoRealAdd = devInfoRealAdd | 0x8000000000000000; + memset(&temp_dev, 0, sizeof(temp_dev)); + temp_dev.bus = bus; + temp_dev.sysdata = bus->sysdata; + + for (hvIdSel=1; hvIdSel <= maxAgents; ++hvIdSel) { + hvRc = HvCallPci_getDeviceInfo(hvBus, hvSubBus, hvIdSel, + devInfoRealAdd, sizeof(*devInfo)); + if (hvRc == 0) { + switch(devInfo->deviceType) { + case HvCallPci_NodeDevice: + /* bridgeInfo = kmalloc(HvCallPci_MaxBusUnitInfoSize, GFP_KERNEL); */ + bridgeInfo = kmalloc(sizeof(*bridgeInfo), GFP_KERNEL); + /* Loop through each node function to find usable bridges. Scan + the node bridge to create devices. The devices will appear + as if they were connected to the primary bus. */ + for (hvFunction=0; hvFunction < 8; ++hvFunction) { + hvAgentId = ISERIES_PCI_AGENTID(hvIdSel, hvFunction); + irq = 0; + /* Note: hvSubBus should always be 0 here! */ + hvRc = HvCallXm_connectBusUnit(hvBus, hvSubBus, hvAgentId, irq); + if (hvRc == 0) { + bridgeInfoRealAdd = virt_to_absolute((u32)bridgeInfo); + bridgeInfoRealAdd = bridgeInfoRealAdd | 0x8000000000000000; + hvRc = HvCallPci_getBusUnitInfo(hvBus, hvSubBus, hvAgentId, + bridgeInfoRealAdd, sizeof(*bridgeInfo)); + if (hvRc == 0 && bridgeInfo->busUnitInfo.deviceType == HvCallPci_BridgeDevice) + { + // scan any card plugged into this slot + iSeries_scan_slot(&temp_dev, hvBus, bridgeInfo->subBusNumber, + bridgeInfo->maxAgents); + } + } + } + kfree(bridgeInfo); + break; + + case HvCallPci_MultiFunctionDevice: + /* Attempt to connect each device function, then use architecture independent + pci_scan_slot to build the device(s) */ + irq = bus->self->irq; // Assume that this multi-function device is attached to a secondary bus. Get the irq from the dev struct for the bus and pass to Hv on the function connects as well as write it into the interrupt line registers of each function + for (hvFunction=0; hvFunction < 8 && hvRc == 0; ++hvFunction) { + hvAgentId = ISERIES_PCI_AGENTID(hvIdSel, hvFunction); + /* Try to connect each function. */ + hvRc = HvCallXm_connectBusUnit(hvBus, hvSubBus, hvAgentId, irq); + if (hvRc == 0) { + noConnectRc = 0; + HvCallPci_configStore8(hvBus, hvSubBus, hvAgentId, PCI_INTERRUPT_LINE, irq); // Store the irq in the interrupt line register of the function config space + } + } + if (noConnectRc == 0) { + noConnectRc = 0xFFFF; // Reset to error value in case other multi-function devices are attached to this bus + // Note: using hvIdSel assumes this device is on a secondary bus! + temp_dev.devfn = PCI_DEVFN(hvIdSel, 0); + pci_scan_slot(&temp_dev); + } + break; + + case HvCallPci_BridgeDevice: + case HvCallPci_IoaDevice: + /* Single function devices, just try to connect and use pci_scan_slot to + build the device */ + irq = bus->self->irq; + hvAgentId = ISERIES_PCI_AGENTID(hvIdSel, 0); + hvRc = HvCallXm_connectBusUnit(hvBus, hvSubBus, hvAgentId, irq); + if (hvRc == 0) { + HvCallPci_configStore8(hvBus, hvSubBus, hvAgentId, PCI_INTERRUPT_LINE, irq); // Store the irq in the interrupt line register of the device config space + // Note: using hvIdSel assumes this device is on a secondary bus! + temp_dev.devfn = PCI_DEVFN(hvIdSel, 0); + pci_scan_slot(&temp_dev); + } + break; + + default : /* Unrecognized device */ + break; + + }; /* end of switch */ + } + } + + kfree(devInfo); + // return 0; +} +/* Initialize bar space base and limit addresses for each device in the tree */ +void __init iSeries_fixup( void ) { + struct pci_dev *dev; + u8 LinuxBus, iSeriesBus, LastBusNumber; + char DeviceInfoBuffer[256]; + + /*********************************************************/ + /* PCI: Allocate Bars space for each device */ + /*********************************************************/ + pci_for_each_dev(dev) { + iSeries_allocateDeviceBars(dev); + } + /*********************************************************/ + /* Create the TCEs for each iSeries bus now that we know */ + /* how many buses there are. Need only create TCE for */ + /* for each iSeries bus. Multiple linux buses could */ + /* be on the same iSeries bus. AHT */ + /*********************************************************/ + LastBusNumber = 0xFF; /* Invalid */ + for( LinuxBus = 0; LinuxBus < 255; ++ LinuxBus) { + iSeriesBus = ISERIES_GET_LPAR_BUS(LinuxBus); + if(iSeriesBus == 0xFF) break; /* Done */ + else if(LastBusNumber != iSeriesBus ){ /* New Bus */ + create_pci_bus_tce_table(iSeriesBus); + LastBusNumber = iSeriesBus; /* Remember */ + } + } + /*********************************************************/ + /* List out all the PCI devices found... This will go */ + /* into the etc/proc/iSeries/pci info as well.... */ + /* This is to help service figure out who is who...... */ + /*********************************************************/ + pci_for_each_dev(dev) { + struct resource* BarResource = &dev->resource[0]; + iSeries_Device_Information(dev,DeviceInfoBuffer,256); + printk("%s\n",DeviceInfoBuffer); + printk("PCI: Bus%3d, Device%3d, %s at 0x%08x, irq %3d\n", + dev->bus->number, PCI_SLOT(dev->devfn),dev->name,(int)BarResource->start,dev->irq); + } + /* */ + iSeries_activate_IRQs(); // Unmask all device interrupts for assigned IRQs +} + diff -Nru a/arch/ppc/iSeries/iSeries_irq.c b/arch/ppc/iSeries/iSeries_irq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/iSeries_irq.c Sat Jun 16 06:00:32 2001 @@ -0,0 +1,256 @@ +/************************************************************************/ +/* This module supports the iSeries PCI bus interrupt handling */ +/* Copyright (C) 20yy */ +/* */ +/* 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 */ +/************************************************************************/ +/* Change Activity: */ +/* Created, December 13, 2000 by Wayne Holm */ +/* End Change Activity */ +/************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + + +hw_irq_controller iSeries_IRQ_handler = { + "iSeries irq controller", + iSeries_startup_IRQ, /* startup */ + iSeries_shutdown_IRQ, /* shutdown */ + iSeries_enable_IRQ, /* enable */ + iSeries_disable_IRQ, /* disable */ + NULL, /* ack */ + iSeries_end_IRQ, /* end */ + NULL /* set_affinity */ +}; + + +struct iSeries_irqEntry { + u32 dsa; + struct iSeries_irqEntry* next; +}; + +struct iSeries_irqAnchor { + u8 valid : 1; + u8 reserved : 7; + u16 entryCount; + struct iSeries_irqEntry* head; +}; + +struct iSeries_irqAnchor iSeries_irqMap[NR_IRQS]; + +void iSeries_init_irqMap(int irq); + +/* This is called by init_IRQ. set in ppc_md.init_IRQ by iSeries_setup.c */ +void __init iSeries_init_IRQ(void) +{ + + int i; + + for (i = 0; i < NR_IRQS; i++) { + irq_desc[i].handler = &iSeries_IRQ_handler; + irq_desc[i].status = 0; + irq_desc[i].status |= IRQ_DISABLED; + irq_desc[i].depth = 1; + iSeries_init_irqMap(i); + } + + /* Register PCI event handler and open an event path */ + XmPciLpEvent_init(); + + return; +} + +/* Called by iSeries_init_IRQ */ +void __init iSeries_init_irqMap(int irq) { + /* Prevent IRQs 0 and 255 from being used. IRQ 0 appears in + uninitialized devices. IRQ 255 appears in the PCI interrupt + line register if a PCI error occurs */ + iSeries_irqMap[irq].valid = (irq == 0 || irq == 255)? 0 : 1; + iSeries_irqMap[irq].entryCount = 0; + iSeries_irqMap[irq].head = NULL; +} + +/* This is called out of iSeries_scan_slot to allocate an IRQ for an EADS slot */ +int __init iSeries_allocate_IRQ(HvBusNumber busNumber, HvSubBusNumber subBusNumber, HvAgentId deviceId) { + + u8 idsel = (deviceId >> 4); + u8 function = deviceId & 0x0F; + int irq = ((((busNumber-1)*16 + (idsel-1)*8 + function)*9/8) % 254) + 1; + return irq; +} + +/* This is called out of iSeries_scan_slot to assign the EADS slot to its IRQ number */ +int __init iSeries_assign_IRQ(int irq, HvBusNumber busNumber, HvSubBusNumber subBusNumber, HvAgentId deviceId) { + + int rc; + u32 dsa = (busNumber << 16) | (subBusNumber << 8) | deviceId; + struct iSeries_irqEntry* newEntry; + unsigned long flags; + + if (irq < 0 || irq >= NR_IRQS) + return -1; + + newEntry = kmalloc(sizeof(*newEntry), GFP_KERNEL); + if (newEntry == NULL) + return -ENOMEM; + newEntry->dsa = dsa; + newEntry->next = NULL; + + /* Probably not necessary to lock the irq since allocation is only + done during buswalk, but it should not hurt anything except a little + performance */ + spin_lock_irqsave(&irq_desc[irq].lock, flags); + + if (iSeries_irqMap[irq].valid) { + /* Push the new element onto the irq stack */ + newEntry->next = iSeries_irqMap[irq].head; + iSeries_irqMap[irq].head = newEntry; + ++iSeries_irqMap[irq].entryCount; + rc = 0; + } + else + rc = -1; + + spin_unlock_irqrestore(&irq_desc[irq].lock, flags); + + if (rc != 0 && newEntry) + kfree(newEntry); + + return rc; + +} + + +/* This is called by iSeries_activate_IRQs */ +unsigned int iSeries_startup_IRQ(unsigned int irq) { + struct iSeries_irqEntry* entry; + u32 bus, subBus, deviceId, function, mask; + + /* irq should be locked by the caller */ + + for(entry=iSeries_irqMap[irq].head; entry!=NULL; entry=entry->next) { + bus = (entry->dsa >> 16) & 0xFFFF; + subBus = (entry->dsa >> 8) & 0xFF; + deviceId = entry->dsa & 0xFF; + function = deviceId & 0x0F; + /* Link the IRQ number to the bridge */ + HvCallXm_connectBusUnit(bus, subBus, deviceId, irq); + /* Unmask bridge interrupts in the FISR */ + mask = 0x01010000 << function; + HvCallPci_unmaskFisr(bus, subBus, deviceId, mask); + } + + return 0; +} + +/* This is called out of iSeries_fixup to + activate interrupt generation for usable slots */ +void __init iSeries_activate_IRQs() { + int irq; + unsigned long flags; + + for (irq=0; irq < NR_IRQS; irq++) { + spin_lock_irqsave(&irq_desc[irq].lock, flags); + irq_desc[irq].handler->startup(irq); + spin_unlock_irqrestore(&irq_desc[irq].lock, flags); + } + +} + +/* this is not called anywhere currently */ +void iSeries_shutdown_IRQ(unsigned int irq) { + struct iSeries_irqEntry* entry; + u32 bus, subBus, deviceId, function, mask; + + /* irq should be locked by the caller */ + + for(entry=iSeries_irqMap[irq].head; entry; entry=entry->next) { + bus = (entry->dsa >> 16) & 0xFFFF; + subBus = (entry->dsa >> 8) & 0xFF; + deviceId = entry->dsa & 0xFF; + function = deviceId & 0x0F; + /* Invalidate the IRQ number in the bridge */ + HvCallXm_connectBusUnit(bus, subBus, deviceId, 0); + /* Mask bridge interrupts in the FISR */ + mask = 0x01010000 << function; + HvCallPci_maskFisr(bus, subBus, deviceId, mask); + } + +} + + +/* This will be called by device drivers (via disable_IRQ to disable + INTA in the bridge interrupt status register */ +void iSeries_disable_IRQ(unsigned int irq) { + struct iSeries_irqEntry* entry; + u32 bus, subBus, deviceId, mask; + + /* The IRQ has already been locked by the caller */ + + for(entry=iSeries_irqMap[irq].head; entry; entry=entry->next) { + bus = (entry->dsa >> 16) & 0xFFFF; + subBus = (entry->dsa >> 8) & 0xFF; + deviceId = entry->dsa & 0xFF; + /* Mask secondary INTA */ + mask = 0x80000000; + HvCallPci_maskInterrupts(bus, subBus, deviceId, mask); + } +} + +/* This will be called by device drivers (via enable_IRQ to enable + INTA in the bridge interrupt status register */ +void iSeries_enable_IRQ(unsigned int irq) { + struct iSeries_irqEntry* entry; + u32 bus, subBus, deviceId, mask; + + /* The IRQ has already been locked by the caller */ + + for(entry=iSeries_irqMap[irq].head; entry; entry=entry->next) { + bus = (entry->dsa >> 16) & 0xFFFF; + subBus = (entry->dsa >> 8) & 0xFF; + deviceId = entry->dsa & 0xFF; + /* Unmask secondary INTA */ + mask = 0x80000000; + HvCallPci_unmaskInterrupts(bus, subBus, deviceId, mask); + } +} + +/* Need to define this so ppc_irq_dispatch_handler will NOT call + enable_IRQ at the end of interrupt handling. However, this + does nothing because there is not enough information provided + to do the EOI HvCall. This is done by XmPciLpEvent.c */ +void iSeries_end_IRQ(unsigned int irq) { +} + diff -Nru a/arch/ppc/iSeries/iSeries_ksyms.c b/arch/ppc/iSeries/iSeries_ksyms.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/iSeries_ksyms.c Sat Jun 16 06:00:32 2001 @@ -0,0 +1,81 @@ +/* File iSeries_ksyms.c created by root on Tue Feb 13 2001. */ + +/* Change Activity: */ +/* End Change Activity */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +EXPORT_SYMBOL(HvLpEvent_registerHandler); +EXPORT_SYMBOL(HvLpEvent_unregisterHandler); +EXPORT_SYMBOL(HvLpEvent_openPath); +EXPORT_SYMBOL(HvLpEvent_closePath); + +EXPORT_SYMBOL(HvCall1); +EXPORT_SYMBOL(HvCall2); +EXPORT_SYMBOL(HvCall3); +EXPORT_SYMBOL(HvCall4); +EXPORT_SYMBOL(HvCall5); +EXPORT_SYMBOL(HvCall6); +EXPORT_SYMBOL(HvCall7); +EXPORT_SYMBOL(HvCall0); +EXPORT_SYMBOL(HvCall0Ret16); +EXPORT_SYMBOL(HvCall1Ret16); +EXPORT_SYMBOL(HvCall2Ret16); +EXPORT_SYMBOL(HvCall3Ret16); +EXPORT_SYMBOL(HvCall4Ret16); +EXPORT_SYMBOL(HvCall5Ret16); +EXPORT_SYMBOL(HvCall6Ret16); +EXPORT_SYMBOL(HvCall7Ret16); + +EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline); +EXPORT_SYMBOL(virt_to_absolute_outline); + +EXPORT_SYMBOL(mf_allocateLpEvents); +EXPORT_SYMBOL(mf_deallocateLpEvents); + +EXPORT_SYMBOL(iSeries_proc_callback); + + +#ifdef CONFIG_PCI +EXPORT_SYMBOL(pci_map_single); +EXPORT_SYMBOL(pci_unmap_single); + +EXPORT_SYMBOL(iSeries_Readb); +EXPORT_SYMBOL(iSeries_Readw); +EXPORT_SYMBOL(iSeries_Readl); +EXPORT_SYMBOL(iSeries_Writeb); +EXPORT_SYMBOL(iSeries_Writew); +EXPORT_SYMBOL(iSeries_Writel); + +EXPORT_SYMBOL(iSeries_memcpy_fromio); +EXPORT_SYMBOL(iSeries_memcpy_toio); + +EXPORT_SYMBOL(iSeries_GetLocationData); + +EXPORT_SYMBOL(iSeries_Set_PciTraceFlag); +EXPORT_SYMBOL(iSeries_Get_PciTraceFlag); + +EXPORT_SYMBOL(iSeries_Device_Reset_NoIrq); +EXPORT_SYMBOL(iSeries_Device_Reset_Generic); +EXPORT_SYMBOL(iSeries_Device_Reset); +EXPORT_SYMBOL(iSeries_Device_RestoreConfigRegs); +EXPORT_SYMBOL(iSeries_Device_SaveConfigRegs); +EXPORT_SYMBOL(iSeries_Device_ToggleReset); +#endif + + + diff -Nru a/arch/ppc/iSeries/iSeries_pci.c b/arch/ppc/iSeries/iSeries_pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/iSeries_pci.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,559 @@ +/************************************************************************/ +/* File iSeries_pci.c created by Allan Trautman on Tue Jan 9 2001. */ +/************************************************************************/ +/* This code supports the pci interface on the IBM iSeries systems. */ +/* Copyright (C) 20yy */ +/* */ +/* 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 */ +/************************************************************************/ +/* Change Activity: */ +/* Created, Jan 9, 2001 */ +/* End Change Activity */ +/************************************************************************/ +#include +#include +#include +#include + +/************************************************************************/ +/* Arch specific's */ +/************************************************************************/ +#include /* Has Io Instructions. */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "iSeries_IoMmTable.h" +#include "iSeries_pci.h" + +/************************************************************************/ +/* /proc/iSeries/pci initialization. */ +/************************************************************************/ +extern void iSeries_pci_proc_init(struct proc_dir_entry *iSeries_proc); + void iSeries_pci_IoError(char* OpCode,iSeries_Device* Device); + +/************************************************************************/ +/* PCI Config Space Access functions for IBM iSeries Systems */ +/* */ +/* Modeled after the IBM Python */ +/* int pci_read_config_word(struct pci_dev*, int Offset, u16* ValuePtr) */ +/************************************************************************/ +/* Note: Normal these routines are defined by a macro and branch */ +/* table is created and stuffed in the pci_bus structure. */ +/* The following is for reference, if it was done this way. However for*/ +/* the first time out, the routines are individual coded. */ +/************************************************************************/ +/* This is the low level architecture depend interface routines. */ +/* 1. They must be in specific order, see for base */ +/* structure. */ +/* 2. The code in not inline here, it calls specific routines in */ +/* this module and HvCalls */ +/* 3. The common convention is to put a pointer to the structure in */ +/* pci_bus->sysdata. */ +/* 4. Direct call is the same as in 0) { + sprintf(PciFrBuffer,"RCB: %02X,%02X,%02X,%04X Rtn: %04X,%02X", + Device.BusNumber, Device.SubBus, Device.DevFn, Offset, + Device.RCode, *ValuePtr); + ISERIES_PCI_FR(PciFrBuffer); + if(Device.RCode != 0 ) printk("PCI: I/O Error %s",PciFrBuffer); + } + } + return Device.RCode; +} +int iSeries_pci_read_config_word( struct pci_dev* PciDev, int Offset, u16* ValuePtr) { + iSeries_Device Device; + build_iSeries_Device(&Device, PciDev); + if(Device.BusNumber == 0xFF) Device.RCode = 0x301; /* Trap out invalid bus. */ + else { + Device.RCode = HvCallPci_configLoad16(Device.BusNumber, Device.SubBus, Device.DevFn, Offset, ValuePtr); + if(Device.RCode != 0 || PciTraceFlag > 0) { + sprintf(PciFrBuffer,"RCW: %02X,%02X,%02X,%04X Rtn: %04X,%04X", + Device.BusNumber, Device.SubBus, Device.DevFn, Offset, + Device.RCode, *ValuePtr); + ISERIES_PCI_FR(PciFrBuffer); + if(Device.RCode != 0 ) printk("PCI: I/O Error %s",PciFrBuffer); + } + } + return Device.RCode; +} +int iSeries_pci_read_config_dword( struct pci_dev* PciDev, int Offset, u32* ValuePtr) { + iSeries_Device Device; + build_iSeries_Device(&Device, PciDev); + if(Device.BusNumber == 0xFF) Device.RCode = 0x301; /* Trap out invalid bus. */ + else { + Device.RCode = HvCallPci_configLoad32(Device.BusNumber, Device.SubBus, Device.DevFn, Offset, ValuePtr); + if(Device.RCode != 0 || PciTraceFlag > 0) { + sprintf(PciFrBuffer,"RCL: %02X,%02X,%02X,%04X Rtn: %04X,%08X", + Device.BusNumber, Device.SubBus, Device.DevFn, Offset, + Device.RCode, *ValuePtr); + ISERIES_PCI_FR(PciFrBuffer); + if(Device.RCode != 0 ) printk("PCI: I/O Error %s",PciFrBuffer); + } + } + return Device.RCode; +} +int iSeries_pci_write_config_byte( struct pci_dev* PciDev, int Offset, u8 Value) { + iSeries_Device Device; + build_iSeries_Device(&Device, PciDev); + if(Device.BusNumber == 0xFF) Device.RCode = 0x301; /* Trap out invalid bus. */ + else { + Device.RCode = HvCallPci_configStore8(Device.BusNumber, Device.SubBus, Device.DevFn, Offset, Value); + if(Device.RCode != 0 || PciTraceFlag > 0) { + sprintf(PciFrBuffer,"WCB: %02X,%02X,%02X,%04X Rtn: %04X,%02X", + Device.BusNumber, Device.SubBus, Device.DevFn, Offset, + Device.RCode, Value); + ISERIES_PCI_FR(PciFrBuffer); + if(Device.RCode != 0 ) printk("PCI: I/O Error %s",PciFrBuffer); + } + } + return Device.RCode; +} +int iSeries_pci_write_config_word( struct pci_dev* PciDev, int Offset, u16 Value) { + iSeries_Device Device; + build_iSeries_Device(&Device, PciDev); + if(Device.BusNumber == 0xFF) Device.RCode = 0x301; /* Trap out invalid bus. */ + else { + Device.RCode = HvCallPci_configStore16(Device.BusNumber, Device.SubBus, Device.DevFn, Offset, Value); + if(Device.RCode != 0 || PciTraceFlag > 0) { + sprintf(PciFrBuffer,"WCW: %02X,%02X,%02X,%04X Rtn: %04X,%04X", + Device.BusNumber, Device.SubBus, Device.DevFn, Offset, + Device.RCode, Value); + ISERIES_PCI_FR(PciFrBuffer); + if(Device.RCode != 0 ) printk("PCI: I/O Error %s",PciFrBuffer); + } + } + return Device.RCode; +} +int iSeries_pci_write_config_dword(struct pci_dev* PciDev, int Offset, u32 Value) { + iSeries_Device Device; + build_iSeries_Device(&Device, PciDev); + if(Device.BusNumber == 0xFF) Device.RCode = 0x301; /* Trap out invalid bus. */ + else { + Device.RCode = HvCallPci_configStore32(Device.BusNumber, Device.SubBus, Device.DevFn, Offset, Value); + if(Device.RCode != 0 || PciTraceFlag > 0) { + sprintf(PciFrBuffer,"WCL: %02X,%02X,%02X,%04X Rtn: %04X,%08X", + Device.BusNumber, Device.SubBus, Device.DevFn, Offset, + Device.RCode, Value); + ISERIES_PCI_FR(PciFrBuffer); + if(Device.RCode != 0 ) printk("PCI: I/O Error %s",PciFrBuffer); + } + } + return Device.RCode; +} +/************************************************************************/ +/* Branch Table */ +/************************************************************************/ +struct pci_ops iSeries_pci_ops = { + iSeries_pci_read_config_byte, + iSeries_pci_read_config_word, + iSeries_pci_read_config_dword, + iSeries_pci_write_config_byte, + iSeries_pci_write_config_word, + iSeries_pci_write_config_dword +}; + +/************************************************************************/ +/* Dump the device info into the Flight Recorder */ +/* Call should have 3 char text to prefix FR Entry */ +/************************************************************************/ +void iSeries_DumpDevice(char* Text, iSeries_Device* Device) { + sprintf(PciFrBuffer,"%s:%02X%02X%02X %04X",Text,Device->BusNumber,Device->SubBus,Device->DevFn,Device->RCode); + ISERIES_PCI_FR(PciFrBuffer); + if(Device->BarNumber != 0xFF) { + sprintf(PciFrBuffer,"BAR:%02X %04X ",Device->BarNumber,Device->BarOffset); + ISERIES_PCI_FR(PciFrBuffer); + } + if(Device->RCode != 0) { + /*****************************************************************/ + /* PCI I/O ERROR RDL: Bus: 0x01 Device: 0x06 ReturnCode: 0x000B */ + /*****************************************************************/ + printk("PCI: I/O ERROR %s: Bus: 0x%02X Device: 0x%02X ReturnCode: 0x%04X\n", + Text,Device->PciDevPtr->bus->number,Device->PciDevPtr->devfn,Device->RCode); + } +} + +/************************************************************************/ +/* Read MM I/O Instructions for the iSeries */ +/* On MM I/O error, all ones are returned and iSeries_pci_IoError is cal*/ +/* else, data is returned in big Endian format. */ +/************************************************************************/ +/* iSeries_Readb = Read Byte ( 8 bit) */ +/* iSeries_Readw = Read Word (16 bit) */ +/* iSeries_Readl = Read Long (32 bit) */ +/************************************************************************/ +u8 iSeries_Readb(u32* IoAddress) { + iSeries_Device Device; + u8 IoData; + u8 Data = -1; /* Return all ones on error */ + if(build_iSeries_Device_From_IoAddress(&Device, IoAddress) == 0) { + Device.RCode = HvCallPci_barLoad8 (Device.BusNumber, Device.SubBus,Device.DevFn, + Device.BarNumber, Device.BarOffset, &IoData); + if(Device.RCode == 0) Data = IoData; + if(PciTraceFlag > 0) { + sprintf(PciFrBuffer,"RDB: %08X Data.: %02X",(int)IoAddress,(int)Data); + ISERIES_PCI_FR(PciFrBuffer); + } + + /* Error Detected on operation. */ + if(Device.RCode != 0) { + iSeries_pci_IoError("RDB",&Device); + } + } + else { + printk("PCI: Invalid I/O Address 0x%08X\n",(int)IoAddress); + Data = 0; + } + return Data; +} +u16 iSeries_Readw(u32* IoAddress) { + iSeries_Device Device; + u16 IoData; + u16 Data = -1; /* Set all ones in case of error. */ + if(build_iSeries_Device_From_IoAddress(&Device, IoAddress) == 0) { + Device.RCode = HvCallPci_barLoad16(Device.BusNumber, Device.SubBus,Device.DevFn, + Device.BarNumber, Device.BarOffset, &IoData); + if(Device.RCode == 0) Data = swab16(IoData); + if(PciTraceFlag > 0) { + sprintf(PciFrBuffer,"RDW: %08X Data.: %04X",(int)IoAddress,(int)Data); + ISERIES_PCI_FR(PciFrBuffer); + } + if(Device.RCode != 0) { /* Error Detected on operation. */ + iSeries_pci_IoError("RDW",&Device); + } + } + else { + printk("PCI: Invalid I/O Address 0x%08X\n",(int)IoAddress); + Data = 0; + } + return Data; +} +u32 iSeries_Readl(u32* IoAddress) { + iSeries_Device Device; + u32 Data = -1; /* Set all ones in case of failure. */ + u32 IoData; + if( build_iSeries_Device_From_IoAddress(&Device, IoAddress) == 0) { + Device.RCode = HvCallPci_barLoad32(Device.BusNumber, Device.SubBus,Device.DevFn, + Device.BarNumber, Device.BarOffset, &IoData); + if(Device.RCode == 0) Data = swab32(IoData); + if(PciTraceFlag > 0) { + sprintf(PciFrBuffer,"RDL: %08X Data.: %08X",(int)IoAddress,(int)Data); + ISERIES_PCI_FR(PciFrBuffer); + } + if(Device.RCode != 0) { /* Error Detected on operation. */ + iSeries_pci_IoError("RDL",&Device); + } + } + else { + printk("PCI: Invalid I/O Address 0x%08X\n",(int)IoAddress); + Data = 0; + } + return Data; +} +/************************************************************************/ +/* Write MM I/O Instructions for the iSeries */ +/* On MM I/O error, iSeries_pci_IoError is called */ +/* Data is in big Endian format. */ +/************************************************************************/ +/* iSeries_Writeb = Write Byte (8 bit) */ +/* iSeries_Writew = Write Word(16 bit) */ +/* iSeries_Writel = Write Long(32 bit) */ +/************************************************************************/ +void iSeries_Writeb(u8 Data,u32* IoAddress) { + iSeries_Device Device; + u8 IoData = Data; + if(build_iSeries_Device_From_IoAddress(&Device, IoAddress) == 0) { + Device.RCode = HvCallPci_barStore8 (Device.BusNumber, Device.SubBus,Device.DevFn, + Device.BarNumber, Device.BarOffset, IoData); + if(PciTraceFlag > 0) { + sprintf(PciFrBuffer,"WRB: %08X Data.: %02X\n",(int)IoAddress,(int)Data); + ISERIES_PCI_FR(PciFrBuffer); + } + if(Device.RCode != 0) { /* Error Detected on operation. */ + iSeries_pci_IoError("WRB",&Device); + } + } +} +void iSeries_Writew(u16 Data,u32* IoAddress) { + iSeries_Device Device; + u16 IoData = swab16(Data); + if(build_iSeries_Device_From_IoAddress(&Device, IoAddress) == 0) { + Device.RCode = HvCallPci_barStore16(Device.BusNumber, Device.SubBus,Device.DevFn, + Device.BarNumber, Device.BarOffset, IoData); + if(PciTraceFlag > 0) { + sprintf(PciFrBuffer,"WRW: %08X Data.: %04X",(int)IoAddress,(int)Data); + ISERIES_PCI_FR(PciFrBuffer); + } + if(Device.RCode != 0) { /* Error Detected on operation. */ + iSeries_pci_IoError("WRW",&Device); + } + } +} +void iSeries_Writel(u32 Data,u32* IoAddress) { + iSeries_Device Device; + u32 IoData = swab32(Data); + if(build_iSeries_Device_From_IoAddress(&Device, IoAddress) == 0) { + Device.RCode = HvCallPci_barStore32(Device.BusNumber, Device.SubBus,Device.DevFn, + Device.BarNumber, Device.BarOffset, IoData); + if(PciTraceFlag > 0) { + sprintf(PciFrBuffer,"WRL: %08X Data.: %08X",(int)IoAddress,(int)Data); + ISERIES_PCI_FR(PciFrBuffer); + } + if(Device.RCode != 0) { /* Error Detected on operation. */ + iSeries_pci_IoError("WRL",&Device); + } + } +} +/************************************************************************/ +/* iSeries I/O Remap */ +/* -> Check to see if one of ours */ +/* -> If not, return null to help find the bug. */ +/************************************************************************/ +void* iSeries_ioremap (unsigned long offset, unsigned long size) { + if(iSeries_xlateIoMmAddress((u32*)offset) != 0) { + return (void*)offset; + } + else { + return NULL; + } +} +/************************************************************************/ +/* Routine to build the iSeries_Device for the pci device. */ +/************************************************************************/ +void build_iSeries_Device(iSeries_Device* Device, struct pci_dev* DevPtr) { + Device->PciDevPtr = DevPtr; + Device->BusNumber = ISERIES_GET_LPAR_BUS(DevPtr->bus->number); + if(ISERIES_GET_LPAR_SUBBUS(DevPtr->bus->number) == 0) { + Device->SubBus = ISERIES_DEVFN_DECODE_SUBBUS(DevPtr->devfn); + Device->DevFn = 0x10 | ISERIES_DECODE_FUNCTION(DevPtr->devfn); + } + else { + Device->SubBus = ISERIES_GET_LPAR_SUBBUS(DevPtr->bus->number); + Device->DevFn = ISERIES_44_FORMAT(DevPtr->devfn); + } + Device->BarNumber = 0xFF; + Device->BarOffset = 0; + Device->RCode = 0; +} +/************************************************************************/ +/* Routine to build the iSeries_Device for the IoAddress. */ +/************************************************************************/ +int build_iSeries_Device_From_IoAddress(iSeries_Device* Device, u32* IoAddress) { + Device->PciDevPtr = iSeries_xlateIoMmAddress(IoAddress); + if(Device->PciDevPtr != 0) { /* Valid pci_dev? */ + build_iSeries_Device(Device,Device->PciDevPtr); + Device->BarNumber = iSeries_IoMmTable_Bar(IoAddress); + if( Device->BarNumber != 0xFF) { + Device->BarOffset = iSeries_IoMmTable_BarOffset(IoAddress); + return 0; + } + else { + sprintf(PciFrBuffer,"I/O BAR Address: 0x%08X",(int)IoAddress); + ISERIES_PCI_FR(PciFrBuffer); + printk("PCI: %s\n",PciFrBuffer); + return -1; + } + } + return -1; +} +/************************************************************************/ +/* Returns the iSeries bus value */ +/************************************************************************/ +u8 iSeries_Get_Bus(struct pci_dev* DevPtr) { + return iSeries_GlobalBusMap[DevPtr->bus->number][_HVBUSNUMBER_]; +} +/************************************************************************/ +/* Returns the iSeries subbus value */ +/************************************************************************/ +u8 iSeries_Get_SubBus(struct pci_dev* DevPtr) { + u8 SubBus = iSeries_GlobalBusMap[DevPtr->bus->number][_HVSUBBUSNUMBER_]; + if (SubBus == 0xFF) SubBus = 0xFF; + else if(SubBus == 0) SubBus = ISERIES_DEVFN_DECODE_SUBBUS(DevPtr->devfn); + else SubBus = ISERIES_GET_LPAR_SUBBUS(DevPtr->bus->number); + return SubBus; +} +/************************************************************************/ +/* Returns the iSeries Device and Function Number */ +/************************************************************************/ +u8 iSeries_Get_DevFn(struct pci_dev* DevPtr) { + u8 SubBus = iSeries_GlobalBusMap[DevPtr->bus->number][_HVSUBBUSNUMBER_]; + u8 DevFn; + if (SubBus == 0xFF) DevFn = 0; + else if(SubBus == 0) DevFn = 0x10 | ISERIES_DECODE_FUNCTION(DevPtr->devfn); + else DevFn = ISERIES_44_FORMAT(DevPtr->devfn); + return DevFn; +} + +/************************************************************************/ +/* This is provides the mapping from the Linux bus and devfn to ISeries */ +/* Bus and Subbus. */ +/* Initialize to all FFs, translations will fail if FF entry found. */ +/************************************************************************/ +u8 iSeries_GlobalBusMap[256][2]; /* Global Bus Mapping */ +void __init iSeries_Initialize_GlobalBusMap(void) { + int Index; + for(Index = 0; Index < 256; ++Index) { + iSeries_GlobalBusMap[Index][_HVBUSNUMBER_] = 0xFF; + iSeries_GlobalBusMap[Index][_HVSUBBUSNUMBER_] = 0xFF; + } + ISERIES_PCI_FR("IntGlobalBusMap"); +} +/************************************************************************/ +/* Create the Flight Recorder */ +/************************************************************************/ +FlightRecorder PciFlightRecorder; /* Pci Flight Recorder */ +FlightRecorder* PciFr; /* Pointer to Fr */ +char PciFrBufferData[128]; /* Working buffer */ +char* PciFrBuffer; /* Pointer to buffer */ +int PciTraceFlag = 0; /* Trace Level Flag */ +struct pci_dev* PciDeviceTrace; /* Device Tracing */ + +void __init iSeries_Initialize_FlightRecorder(void) { + PciFr = &PciFlightRecorder; + PciFrBuffer = &PciFrBufferData[0]; + iSeries_Fr_Initialize(PciFr, "PciFlightRecord"); + ISERIES_PCI_FR("April 12,2000. "); + PciTraceFlag = 0; +} +/************************************************************************/ +/* Function to turn on and off the Flight Recorder Trace Flag */ +/************************************************************************/ +int iSeries_Set_PciTraceFlag(int TraceFlag) { + int TempFlag = PciTraceFlag; + PciTraceFlag = TraceFlag; + return TempFlag; +} +int iSeries_Get_PciTraceFlag(void) { + return PciTraceFlag; +} +void iSeries_Set_PciFilter(struct pci_dev* PciDevice) { + PciDeviceTrace = PciDevice; +} +/************************************************************************/ +/* Initialize the I/O Tables and maps */ +/************************************************************************/ +void __init iSeries_pci_Initialize(void) { + iSeries_Initialize_FlightRecorder(); /* Flight Recorder 1st. */ + iSeries_Initialize_GlobalBusMap(); /* Global Bus Map */ + iSeries_IoMmTable_Initialize(); /* Io Translate table. */ + iSeries_proc_callback(&iSeries_pci_proc_init); + iSeries_Set_PciErpFlag(4); /* Erp Level set to 4 */ +} + +/************************************************************************/ +/* Erp level when PCI I/O Errors are detected. */ +/* 0 = Be quiet about the errors. */ +/* 1 >= Log error information and continue on. */ +/* 2 = Printk the error information and continue on. */ +/* 3 = Printk the error information and put task to sleep. */ +/* 4 = Printk the error information and panic the kernel with no reboo*/ +/************************************************************************/ +int iSeries_pci_ErpLevel = 0; +/************************************************************************/ +/* Allows clients to set the Erp State */ +/************************************************************************/ +int iSeries_Set_PciErpFlag(int ErpFlag) { + int SavedState = iSeries_pci_ErpLevel; + printk("PCI: PciERPFlag set to %d.\n", ErpFlag); + iSeries_pci_ErpLevel = ErpFlag; + return SavedState; +} +extern int panic_timeout; /* Panic Timeout reference */ +/************************************************************************/ +/* Fatal I/O Error, crash the system. */ +/* PCI: Fatal I/O Error, Device 00/00, Error 0x0000, Status Reg 0x0000 */ +/* PCI: Kernel Panic called with reboot disabled. */ +/************************************************************************/ +void iSeries_pci_IoError(char* OpCode,iSeries_Device* Device) { + char DeviceInfo[128]; + char ErrorInfo[128]; + struct pci_dev* PciDev = Device->PciDevPtr; + + sprintf(ErrorInfo,"I/O Error Detected. Op: %s, Bus%3d, Device%3d Error: 0x%04X\n", + OpCode,PciDev->bus->number, PCI_SLOT(PciDev->devfn),Device->RCode); + iSeries_Device_Information(PciDev,DeviceInfo,128); + + /* Log the error in the flight recorder */ + if(iSeries_pci_ErpLevel > 0) { + if( Device->RCode != 0x0102) { /* Previous error */ + ISERIES_PCI_FR(ErrorInfo); + ISERIES_PCI_FR(DeviceInfo); + } + } + if(iSeries_pci_ErpLevel > 1) { + printk("PCI: %s",ErrorInfo); + printk("PCI: %s\n",DeviceInfo); + } + if(iSeries_pci_ErpLevel == 3) { + printk("PCI: Current process 0x%08X put to sleep for debug.\n",current->pid); + { + DECLARE_WAITQUEUE(WaitQueue, current); + add_wait_queue(¤t->wait_chldexit,&WaitQueue); + current->state = TASK_INTERRUPTIBLE; + schedule(); + current->state = TASK_RUNNING; + remove_wait_queue(¤t->wait_chldexit,&WaitQueue); + } + } + else if(iSeries_pci_ErpLevel == 4) { + mf_displaySrc(0xB6000103); + panic_timeout = 0; /* Don't reboot. */ + /* printk("PCI: Hardware I/O Error, SRC B6000103, Kernel Panic called.\n");*/ + /* panic("Automatic Reboot Disabled.") */ + panic("PCI: Hardware I/O Error, SRC B6000103, Automatic Reboot Disabled."); + } +} + +/************************************************************************/ +/* I/0 Memory copy MUST use mmio commands on iSeries */ +/************************************************************************/ +void* iSeries_memcpy_toio(void *dest, void *source, int n) +{ + char *dst = dest; + char *src = source; + + while (n--) { + writeb (*src++, dst++); + } + + return dest; +} + +void* iSeries_memcpy_fromio(void *dest, void *source, int n) +{ + char *dst = dest; + char *src = source; + + while (n--) + *dst++ = readb (src++); + + return dest; +} + + diff -Nru a/arch/ppc/iSeries/iSeries_pci.h b/arch/ppc/iSeries/iSeries_pci.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/iSeries_pci.h Sat Jun 16 06:00:30 2001 @@ -0,0 +1,139 @@ +#ifdef CONFIG_PPC_ISERIES +#ifndef _ISERIES_PCI_H +#define _ISERIES_PCI_H +/************************************************************************/ +/* File iSeries_pci.h created by Allan Trautman on Tue Jan 9 2001. */ +/************************************************************************/ +/* Define some useful macros for the iseries pci routines. */ +/* Copyright (C) 20yy Allan H Trautman, IBM Corporation */ +/* */ +/* 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 */ +/************************************************************************/ +/* Change Activity: */ +/* Created December 28, 2000 */ +/* Converted to iseries_pci.h Jan 25, 2001 */ +/* End Change Activity */ +/************************************************************************/ +#include +#include +#include +#include + +/************************************************************************************/ +/* Define some useful macros. */ +/* These macros started with Wayne, Al renamed and refined. */ +/************************************************************************************/ +/* Encodes SubBus address(seddddfff), Works only for bridges under EADS 1 and 2. */ +/************************************************************************************/ +/* #define ISERIES_ENCODE_SUBBUS(eads, bridge, device) \ + (0x80 | ((eads-1 & 0x01) << 6) | ((bridge & 0x0F) << 3) | (device & 0x07)) */ +#define ISERIES_ENCODE_SUBBUS(e, ef, df) (((0x80 | ((e&0x02)<<5) | ((ef & 0x07)<<3)) & 0xF8) | (df & 0x03)) // Al - Please Review + +/************************************************************************************/ +/* Combines IdSel and Function into Iseries 4.4 format */ +/* For Linux, see PCI_DEVFN(slot,func) in include/linux/pci.h */ +/************************************************************************************/ +// #define ISERIES_PCI_AGENTID(idsel,func) ((idsel & 0x0F) << 4) | (func & 0x07) +#define ISERIES_PCI_AGENTID(idsel,func) (((idsel & 0x0F) << 4) | (func & 0x0F)) // Al - Please Review + +/************************************************************************************/ +/* Converts DeviceFunction from Linux 5.3(dddddfff) to Iseries 4.4(dddd0fff) */ +/* Converts DeviceFunction from Iseries 4.4(dddd0fff) to Linux 5.3(dddddfff) */ +/************************************************************************************/ +#define ISERIES_44_FORMAT(devfn53) (((devfn53 & 0xF8) << 1) | (devfn53 & 0x07)) +#define ISERIES_53_FORMAT(devfn44) (((devfn44 & 0xF0) >> 1) | (devfn44 & 0x07)) + +/************************************************************************************/ +/* Tests for encoded subbus. */ +/************************************************************************************/ +#define ISERIES_IS_SUBBUS_ENCODED_IN_DEVFN(devfn) ((devfn & 0x80) == 0x80) + +/************************************************************************************/ +/* Decodes the Iseries subbus to devfn, ONLY Works for bus 0!! Use Table lookup. */ +/************************************************************************************/ +/* #define ISERIES_DEVFN_DECODE_SUBBUS(devfn) \ + ((((devfn & 0x40) >> 1) + 0x20) | ((devfn >> 1) & 0x1C)) */ +#define ISERIES_DEVFN_DECODE_SUBBUS(devfn) (((((devfn >> 6 ) & 0x1) + 1) << 5) | (((devfn >> 3) & 0x7) << 2)) // Al - Please Review + +/************************************************************************************/ +/* Decodes Linux DevFn to Iseries DevFn, bridge device, or function. */ +/* For Linux, see PCI_SLOT and PCI_FUNC in include/linux/pci.h */ +/************************************************************************************/ +#define ISERIES_DECODE_DEVFN(linuxdevfn) (((linuxdevfn & 0x71) << 1) | (linuxdevfn & 0x07)) +#define ISERIES_DECODE_DEVICE(linuxdevfn) (((linuxdevfn & 0x38) >> 3) |(((linuxdevfn & 0x40) >> 2) + 0x10)) +#define ISERIES_DECODE_FUNCTION(linuxdevfn) (linuxdevfn & 0x07) + +#define ISERIES_GET_DEVICE_FROM_SUBBUS(subbus) ((subbus >> 5) & 0x7) +#define ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus) ((subbus >> 2) & 0x7) +#define ISERIES_GET_HOSE_HV_BUSNUM(hose) (((struct iSeries_hose_arch_data *)(hose->arch_data))->hvBusNumber) + +/************************************************************************************/ +/* Retreives Iseries Bus and SubBus from GlobalBusMap */ +/************************************************************************************/ +#define ISERIES_GET_LPAR_BUS(linux_bus) iSeries_GlobalBusMap[linux_bus][_HVBUSNUMBER_] +#define ISERIES_GET_LPAR_SUBBUS(linux_bus) iSeries_GlobalBusMap[linux_bus][_HVSUBBUSNUMBER_] + +#define ISERIES_ADD_BUS_GLOBALBUSMAP(linuxbus, iseriesbus, iseriessubbus) \ + iSeries_GlobalBusMap[linuxbus][_HVBUSNUMBER_] = iseriesbus; \ + iSeries_GlobalBusMap[linuxbus][_HVSUBBUSNUMBER_] = iseriessubbus; + +/************************************************************************************/ +/* Global Bus map */ +/* Bus and Subbus index values into the global bus number map array. */ +/************************************************************************************/ +#define ISERIES_GLOBALBUSMAP_SIZE 256 +#define _HVBUSNUMBER_ 0 +#define _HVSUBBUSNUMBER_ 1 +extern u8 iSeries_GlobalBusMap[ISERIES_GLOBALBUSMAP_SIZE][2]; +void iSeries_Initialize_GlobalBusMap(void); +#define pci_assign_all_buses() 1 // Al - NEW + +/************************************************************************************/ +/* Converts Virtual Address to Real Address for Hypervisor calls */ +/************************************************************************************/ +#define REALADDR(virtaddr) (0x8000000000000000 | (virt_to_absolute((u32)virtaddr) )) + +/************************************************************************************/ +/* Define TRUE and FALSE Values for Al */ +/************************************************************************************/ +#ifndef TRUE +#define TRUE 1 +#endif +#ifndef FALSE +#define FALSE 0 +#endif + +typedef struct pci_dev pciDev; +/************************************************************************/ +/* Routines to build the iSeries_Device for the pci device. */ +/************************************************************************/ +extern void build_iSeries_Device(iSeries_Device* Device, struct pci_dev* DevPtr); +extern int build_iSeries_Device_From_IoAddress(iSeries_Device* Device, u32* IoAddress); +extern void iSeries_pci_Initialize(void); + +/************************************************************************/ +/* Flight Recorder Debug Support */ +/************************************************************************/ +extern int PciTraceFlag; /* Conditional Trace */ +void iSeries_Initialize_FlightRecorder(void); +int iSeries_Set_PciTraceFlag(int Flag); /* Sets flag, return old*/ +int iSeries_Get_PciTraceFlag(void); /* Gets Flag. */ +void iSeries_DumpDevice(char* Text, iSeries_Device* ); + +#endif /* _ISERIES_PCI_H */ +#endif /*CONFIG_PPC_ISERIES */ + diff -Nru a/arch/ppc/iSeries/iSeries_pci_proc.c b/arch/ppc/iSeries/iSeries_pci_proc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/iSeries_pci_proc.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,185 @@ +/************************************************************************/ +/* File iSeries pci_proc.c created by Allan Trautman on Feb 27 2001. */ +/************************************************************************/ +/* Create /proc/iSeries/pci file that contains iSeries card location. */ +/* Copyright (C) 20yy */ +/* */ +/* 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 */ +/************************************************************************/ +/* Change Activity: */ +/* Created, Feb 27, 2001 */ +/* End Change Activity */ +/************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +static struct proc_dir_entry *pci_proc_root = NULL; +static struct proc_dir_entry *pciFr_proc_root = NULL; + +int iSeries_proc_pci_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data); +int iSeries_proc_pci_write_proc(struct file *file, const char *buffer, unsigned long count, void *data); +int iSeries_proc_pciFr_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data); +int iSeries_proc_pciFr_write_proc(struct file *file, const char *buffer, unsigned long count, void *data); + + +void iSeries_pci_proc_init(struct proc_dir_entry *iSeries_proc) { + printk("PCI: Creating /proc/iSeries/pci\n"); + + /* Read = User,Group,Other, Write User */ + pci_proc_root = create_proc_entry("pci", S_IFREG | S_IRUGO | S_IWUSR, iSeries_proc); + if (!pci_proc_root) return; + pci_proc_root->nlink = 1; + pci_proc_root->data = (void *)0; + pci_proc_root->read_proc = iSeries_proc_pci_read_proc; + pci_proc_root->write_proc = iSeries_proc_pci_write_proc; + + /* Read = User,Group,Other, Write User */ + printk("PCI: Creating /proc/iSeries/pciFr\n"); + pciFr_proc_root = create_proc_entry("pciFr", S_IFREG | S_IRUGO | S_IWUSR, iSeries_proc); + if (!pciFr_proc_root) return; + pciFr_proc_root->nlink = 1; + pciFr_proc_root->data = (void *)0; + pciFr_proc_root->read_proc = iSeries_proc_pciFr_read_proc; + pciFr_proc_root->write_proc = iSeries_proc_pciFr_write_proc; +} + +/*******************************************************************************/ +/* Get called when client reads the /proc/iSeries/pci file. The data returned */ +/* is the iSeries card locations for service. */ +/*******************************************************************************/ +int iSeries_proc_pci_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { + int LineLen; /* Size of new Data */ + struct pci_dev* PciDev; /* Device pointer */ + struct net_device *dev; /* net_device pointer */ + int DeviceCount; /* Device Number */ + /***************************************************************************/ + /* ### Bus Device Bus Dev Frm Card */ + /* 1. Linux: 0/ 28 iSeries: 24/ 36/ 1/C14 */ + /* 2. Linux: 0/ 30 iSeries: 24/ 38/ 2/C14 */ + /***************************************************************************/ + DeviceCount = 1; /* Count the devices listed. */ + LineLen = 0; /* Reset Length */ + + /***************************************************************************/ + /* List the devices */ + /***************************************************************************/ + pci_for_each_dev(PciDev) { + LineLen += sprintf(page+LineLen,"%3d. ",DeviceCount); + LineLen += iSeries_Device_Information(PciDev,page+LineLen,count-LineLen); + for (dev = dev_base; dev != NULL; dev = dev->next) + { + if (dev->base_addr == PciDev->resource[0].start ) { /* Yep, a net_device */ + LineLen += sprintf(page+LineLen, ", Net device: %s", dev->name); + } /* if */ + } /* for */ + LineLen += sprintf(page+LineLen,"\n"); + ++DeviceCount; /* Add for the list. */ + /************************************************************************/ + /* Run out of room in system buffer. */ + /************************************************************************/ + if(LineLen+80 >= count) { /* Room for another line? No. bail out */ + LineLen +=sprintf(page+LineLen,"/proc/pci file full!\n"); + break; + } + } + /***************************************************************************/ + /* If no devices, tell user that instead */ + /***************************************************************************/ + if(DeviceCount == 1) { + LineLen +=sprintf(page+LineLen,"No PCI devices found\n"); + } + /***************************************************************************/ + /* Update counts and return */ + /***************************************************************************/ + *eof = LineLen; + return LineLen; +} + +/*******************************************************************************/ +/* Do nothing, Nothing to support for the write */ +/*******************************************************************************/ +int iSeries_proc_pci_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) { + return count; +} + +/*******************************************************************************/ +/* Get called when client reads the /proc/iSeries/pci file. The data returned */ +/* is the iSeries card locations for service. */ +/*******************************************************************************/ +int iSeries_proc_pciFr_read_proc(char *page, char **start, off_t off, int count, int *eof, void *data) { + struct pci_dev* PciDev; /* Device pointer */ + int DeviceCount = 1; /* Device Number */ + int LineLen = 0; /* Size of new Data */ + + printk("PCI: Dump Flight Recorder!\n"); + /***************************************************************************/ + /* List the devices */ + /***************************************************************************/ + pci_for_each_dev(PciDev) { + LineLen += sprintf(page+LineLen,"%3d. 0x%08X ",DeviceCount,(int)PciDev); + LineLen += sprintf(page+LineLen,"Bus: %02X, Device: %02X ",PciDev->bus->number,PciDev->devfn); + LineLen += sprintf(page+LineLen,"\n"); + ++DeviceCount; /* Add for the list. */ + } + LineLen += sprintf(page+LineLen,"--\n"); + /***************************************************************************/ + /* The Flight Recorder */ + /* Someday handle wrap */ + /***************************************************************************/ + if (PciFr->StartingPointer != NULL) { + char* StartEntry = (char*)PciFr->StartingPointer; + char* EndEntry = (char*)PciFr->CurrentPointer; + while(EndEntry > StartEntry && LineLen+40 < count) { + LineLen += sprintf(page+LineLen,"%s\n",StartEntry); + StartEntry += strlen(StartEntry) + 1; + } + if(LineLen+40 >= count) { + printk("PCI: Max Count Hit %d and %d\n",LineLen,count); + } + } + /***************************************************************************/ + /* Update counts and return */ + /***************************************************************************/ + printk("PCI: End of File at %d\n",LineLen); + *eof = LineLen; + return LineLen; +} +/*******************************************************************************/ +/* Flight Recorder Controls */ +/*******************************************************************************/ +int iSeries_proc_pciFr_write_proc(struct file *file, const char *buffer, unsigned long count, void *data) { + if(buffer != 0 && strlen(buffer) > 0) { + if( strstr(buffer,"trace on") != NULL) { + iSeries_Set_PciTraceFlag(1); + ISERIES_PCI_FR_DATE("PCI Trace turned on!"); + } + else if(strstr(buffer,"trace off") != NULL) { + iSeries_Set_PciTraceFlag(0); + ISERIES_PCI_FR_DATE("PCI Trace turned off!"); + } + else { + ISERIES_PCI_FR_TIME("PCI Trace Option Invalid!"); + readl(0x00000000); + } + } + return count; +} diff -Nru a/arch/ppc/iSeries/iSeries_proc.c b/arch/ppc/iSeries/iSeries_proc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/iSeries_proc.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,154 @@ +/* + * iSeries_proc.c + * Copyright (C) 2001 Kyle A. Lucke IBM Corporation + * + * 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 + */ + + +/* Change Activity: */ +/* End Change Activity */ + +#include +#include +#ifndef _ISERIES_PROC_H +#include +#endif + + +static struct proc_dir_entry * iSeries_proc_root = NULL; +static int iSeries_proc_initializationDone = 0; +static spinlock_t iSeries_proc_lock; + +struct iSeries_proc_registration +{ + struct iSeries_proc_registration *next; + iSeriesProcFunction functionMember; +}; + + +struct iSeries_proc_registration preallocated[16]; +#define MYQUEUETYPE(T) struct MYQueue##T +#define MYQUEUE(T) \ +MYQUEUETYPE(T) \ +{ \ +struct T *head; \ +struct T *tail; \ +} +#define MYQUEUECTOR(q) do { (q)->head = NULL; (q)->tail = NULL; } while(0) +#define MYQUEUEENQ(q, p) \ +do { \ +(p)->next = NULL; \ +if ((q)->head != NULL) \ +{ \ +(q)->head->next = (p); \ +(q)->head = (p); \ +} \ +else \ +{ \ +(q)->tail = (q)->head = (p); \ +} \ +} while(0) + +#define MYQUEUEDEQ(q,p) \ +do { \ +(p) = (q)->tail; \ +if ((p) != NULL) \ +{ \ +(q)->tail = (p)->next; \ +(p)->next = NULL; \ +} \ +if ((q)->tail == NULL) \ +(q)->head = NULL; \ +} while(0) +MYQUEUE(iSeries_proc_registration); +typedef MYQUEUETYPE(iSeries_proc_registration) aQueue; + + +aQueue iSeries_free; +aQueue iSeries_queued; + +void iSeries_proc_early_init(void) +{ + int i = 0; + unsigned long flags; + iSeries_proc_initializationDone = 0; + spin_lock_init(&iSeries_proc_lock); + MYQUEUECTOR(&iSeries_free); + MYQUEUECTOR(&iSeries_queued); + + spin_lock_irqsave(&iSeries_proc_lock, flags); + for (i = 0; i < 16; ++i) + { + MYQUEUEENQ(&iSeries_free, preallocated+i); + } + spin_unlock_irqrestore(&iSeries_proc_lock, flags); +} + +void iSeries_proc_create(void) +{ + unsigned long flags; + struct iSeries_proc_registration *reg = NULL; + spin_lock_irqsave(&iSeries_proc_lock, flags); + printk("iSeries_proc: Creating /proc/iSeries\n"); + + iSeries_proc_root = proc_mkdir("iSeries", 0); + if (!iSeries_proc_root) return; + + MYQUEUEDEQ(&iSeries_queued, reg); + + while (reg != NULL) + { + (*(reg->functionMember))(iSeries_proc_root); + + MYQUEUEDEQ(&iSeries_queued, reg); + } + + iSeries_proc_initializationDone = 1; + spin_unlock_irqrestore(&iSeries_proc_lock, flags); +} + +void iSeries_proc_callback(iSeriesProcFunction initFunction) +{ + unsigned long flags; + spin_lock_irqsave(&iSeries_proc_lock, flags); + + if (iSeries_proc_initializationDone) + { + (*initFunction)(iSeries_proc_root); + } + else + { + struct iSeries_proc_registration *reg = NULL; + + MYQUEUEDEQ(&iSeries_free, reg); + + if (reg != NULL) + { +// printk("Registering %p in reg %p\n", initFunction, reg); + reg->functionMember = initFunction; + + MYQUEUEENQ(&iSeries_queued, reg); + } + else + { + printk("Couldn't get a queue entry\n"); + } + } + + spin_unlock_irqrestore(&iSeries_proc_lock, flags); +} + + diff -Nru a/arch/ppc/iSeries/iSeries_reset_device.c b/arch/ppc/iSeries/iSeries_reset_device.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/iSeries_reset_device.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,196 @@ +/************************************************************************/ +/* File iSeries_reset_device.c created by Allan Trautman on Mar 21 2001.*/ +/************************************************************************/ +/* This code supports the pci interface on the IBM iSeries systems. */ +/* Copyright (C) 20yy */ +/* */ +/* 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 */ +/************************************************************************/ +/* Change Activity: */ +/* Created, March 20, 2001 */ +/* April 30, 2001, Added return codes on functions. */ +/* End Change Activity */ +/************************************************************************/ +#include +#include +#include +#include +#include +/************************************************************************/ +/* Arch specific's */ +/************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include "iSeries_pci.h" + +/************************************************************************/ +/* Interface to Reset Device, see .h for parms and flavors. */ +/************************************************************************/ +int iSeries_Device_Reset_NoIrq(struct pci_dev* PciDev) { + return iSeries_Device_Reset(PciDev,0,0,1); +} +int iSeries_Device_Reset_Generic(struct pci_dev* PciDev) { + return iSeries_Device_Reset(PciDev,0,0,0); +} +int iSeries_Device_Reset(struct pci_dev* PciDev, int AssertTime, int DelayTime, int IrqState) { + int RCode = 0; + PciReqsSaveArea* RegSaveArea = NULL; + if(PciDev != 0) { + if(IrqState == 0) disable_irq(PciDev->irq); + RegSaveArea = iSeries_Device_SaveConfigRegs(PciDev); + if(RegSaveArea != NULL) { + RCode = iSeries_Device_ToggleReset(PciDev, AssertTime, DelayTime); + if(RCode == 0) { + RCode = iSeries_Device_RestoreConfigRegs(RegSaveArea); + } + } + else { + RCode = -1; + } + if(IrqState == 0) enable_irq(PciDev->irq); + } + return RCode; +} +/************************************************************************/ +/* Interface to toggle the reset line */ +/* Time is in .1 seconds, need for seconds. */ +/************************************************************************/ +int iSeries_Device_ToggleReset(struct pci_dev* PciDev, int AssertTime, int DelayTime) { + unsigned long AssertDelay = AssertTime; + unsigned long WaitDelay = DelayTime; + u16 Bus = ISERIES_GET_LPAR_BUS(PciDev->bus->number); + u8 Slot = ISERIES_DECODE_DEVICE(PciDev->devfn); + int RCode = 0; + + /* Set defaults */ + if(AssertTime < 5) AssertDelay = 5; /* Default is .5 second */ + if(WaitDelay < 30) WaitDelay = 30; /* Default is 3 seconds */ + + /* Assert reset for time specified */ + AssertDelay *= HZ; /* Convert to ticks. */ + AssertDelay /= 10; /* Adjust to whole count */ + RCode = HvCallPci_setSlotReset(Bus, 0x00, Slot, 1); + set_current_state(TASK_UNINTERRUPTIBLE); /* Only Wait. */ + schedule_timeout(AssertDelay); /* Sleep for the time */ + RCode += HvCallPci_setSlotReset(Bus, 0x00, Slot, 0); + + /* Wait for device to reset */ + WaitDelay *= HZ; /* Ticks */ + WaitDelay /= 10; /* Whole count */ + set_current_state(TASK_UNINTERRUPTIBLE); /* Only Wait. */ + schedule_timeout(WaitDelay); /* Sleep for the time */ + + if(RCode == 0) { + sprintf(PciFrBuffer,"Slot Reset on Bus%3d, Device%3d!\n",Bus, Slot); + } + else { + sprintf(PciFrBuffer,"Slot Reset on Bus%3d, Device%3d Failed! RCode: %04X\n",Bus, Slot, RCode); + } + ISERIES_PCI_FR_TIME(PciFrBuffer); + printk("PCI: %s\n",PciFrBuffer); + return RCode; +} + +/************************************************************************/ +/* Allocates space and save the config registers for a device. */ +/************************************************************************/ +/* Note: This does byte reads so the data may appear byte swapped */ +/* when compared to read word or dword. */ +/* The data returned is a structure and will be freed automatically on */ +/* the restore of the data. The is checking so if the save fails, the */ +/* data will not be restore. Yes I know, you are most likey toast. */ +/************************************************************************/ +PciReqsSaveArea* iSeries_Device_SaveConfigRegs(struct pci_dev* DevPtr) { + int Register = 0; + struct pci_dev* PciDev = DevPtr; + PciReqsSaveArea* RegSaveArea = (PciReqsSaveArea*)kmalloc(sizeof(PciReqsSaveArea), GFP_KERNEL); + /*printk("PCI: Save Configuration Registers. 0x%08X\n",(int)RegSaveArea); */ + if(RegSaveArea == 0) { + printk("PCI: Allocation failure in Save Configuration Registers.\n"); + } + /********************************************************************/ + /* Initialize Area. */ + /********************************************************************/ + else { + RegSaveArea->PciDev = DevPtr; + RegSaveArea->Flags = 0x01; + RegSaveArea->ByteCount = PCI_MAX_LAT+1; /* Number of Bytes */ + RegSaveArea->RCode = 0; + RegSaveArea->FailReg = 0; + /****************************************************************/ + /* Save All the Regs, NOTE: restore skips the first 16 bytes. */ + /****************************************************************/ + for(Register = 0;Register < RegSaveArea->ByteCount && RegSaveArea->RCode == 0; ++Register) { + RegSaveArea->RCode = pci_read_config_byte(PciDev, Register, &RegSaveArea->Regs[Register]); + } + /* Check for error during the save. */ + if(RegSaveArea->RCode != 0) { + printk("PCI: I/O Failure in Save Configuration Registers. 0x%02X, 0x%04X\n", + Register,RegSaveArea->RCode); + RegSaveArea->Flags |= 0x80; /* Ouch Flag. */ + RegSaveArea->FailReg = Register; /* Stuff this way */ + } + } + return RegSaveArea; +} +/************************************************************************/ +/* Restores the registers saved via the save function. See the save */ +/* function for details. */ +/************************************************************************/ +int iSeries_Device_RestoreConfigRegs(PciReqsSaveArea* SaveArea) { + int RCode = 0; + if(SaveArea == 0 || SaveArea->PciDev == 0 || + (SaveArea->Flags & 0x80) == 0x80 || SaveArea->RCode != 0) { + printk("PCI: Invalid SaveArea passed to Restore Configuration Registers. 0x%08X\n",(int)SaveArea); + RCode = -1; + } + else { + int Register; + struct pci_dev* PciDev = SaveArea->PciDev; + /***************************************************************/ + /* Don't touch the Cmd or BIST regs, user must restore those. */ + /* Restore PCI_CACHE_LINE_SIZE & PCI_LATENCY_TIMER */ + /* Restore Saved Regs from 0x10 to 0x3F */ + /***************************************************************/ + pci_write_config_byte(PciDev, PCI_CACHE_LINE_SIZE, SaveArea->Regs[PCI_CACHE_LINE_SIZE]); + pci_write_config_byte(PciDev, PCI_LATENCY_TIMER, SaveArea->Regs[PCI_LATENCY_TIMER]); + + for(Register = PCI_BASE_ADDRESS_0; Register < SaveArea->ByteCount && SaveArea->RCode == 0; ++Register) { + SaveArea->RCode = pci_write_config_byte(PciDev, Register, SaveArea->Regs[Register]); + } + if(SaveArea->RCode != 0) { + printk("PCI: I/O Failure in Restore Configuration Registers %d, %02X\n",Register,SaveArea->RCode); + SaveArea->FailReg = Register; + RCode = SaveArea->RCode; + } + else { + RCode = 0; + } + /***************************************************************/ + /* Is the Auto Free Flag on */ + /***************************************************************/ + if(SaveArea->Flags && 0x01 == 0x01 ) { + /* printk("PCI: Auto Free Register Save Area. 0x%08X\n",(int)SaveArea); */ + kfree(SaveArea); + } + } +} diff -Nru a/arch/ppc/iSeries/mf.c b/arch/ppc/iSeries/mf.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/mf.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,1195 @@ +/* + * mf.c + * Copyright (C) 2001 Troy D. Armstrong IBM Corporation + * + * This modules exists as an interface between a Linux secondary partition + * running on an iSeries and the primary partition's Virtual Service + * Processor (VSP) object. The VSP has final authority over powering on/off + * all partitions in the iSeries. It also provides miscellaneous low-level + * machine facility type operations. + * + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * This is the structure layout for the Machine Facilites LPAR event + * flows. + */ +struct VspCmdData; +struct CeMsgData; +union SafeCast +{ + u64 ptrAsU64; + void *ptr; +}; + + +typedef void (*CeMsgCompleteHandler)( void *token, struct CeMsgData *vspCmdRsp ); + +struct CeMsgCompleteData +{ + CeMsgCompleteHandler xHdlr; + void *xToken; +}; + +struct VspRspData +{ + struct semaphore *xSemaphore; + struct VspCmdData *xResponse; +}; + +struct IoMFLpEvent +{ + struct HvLpEvent xHvLpEvent; + + u16 xSubtypeRc; + u16 xRsvd1; + u32 xRsvd2; + + union + { + + struct AllocData + { + u16 xSize; + u16 xType; + u32 xCount; + u16 xRsvd3; + u8 xRsvd4; + HvLpIndex xTargetLp; + } xAllocData; + + struct CeMsgData + { + u8 xCEMsg[12]; + char xReserved[4]; + struct CeMsgCompleteData *xToken; + } xCEMsgData; + + struct VspCmdData + { + union SafeCast xTokenUnion; + u16 xCmd; + HvLpIndex xLpIndex; + u8 xRc; + u32 xReserved1; + + union VspCmdSubData + { + struct + { + u64 xState; + } xGetStateOut; + + struct + { + u64 xIplType; + } xGetIplTypeOut, xFunction02SelectIplTypeIn; + + struct + { + u64 xIplMode; + } xGetIplModeOut, xFunction02SelectIplModeIn; + + struct + { + u64 xPage[4]; + } xGetSrcHistoryIn; + + struct + { + u64 xFlag; + } xGetAutoIplWhenPrimaryIplsOut, xSetAutoIplWhenPrimaryIplsIn, xWhiteButtonPowerOffIn, xFunction08FastPowerOffIn, xIsSpcnRackPowerIncompleteOut; + + struct + { + u64 xToken; + u64 xAddressType; + u64 xSide; + u32 xTransferLength; + u32 xOffset; + } xSetKernelImageIn, xGetKernelImageIn, xSetKernelCmdLineIn, xGetKernelCmdLineIn; + + struct + { + u32 xTransferLength; + } xGetKernelImageOut,xGetKernelCmdLineOut; + + + u8 xReserved2[80]; + + } xSubData; + } xVspCmd; + } xUnion; +}; + + +/* + * All outgoing event traffic is kept on a FIFO queue. The first + * pointer points to the one that is outstanding, and all new + * requests get stuck on the end. Also, we keep a certain number of + * preallocated stack elements so that we can operate very early in + * the boot up sequence (before kmalloc is ready). + */ +struct StackElement +{ + struct StackElement * next; + struct IoMFLpEvent event; + MFCompleteHandler hdlr; + char dmaData[72]; + unsigned dmaDataLength; + unsigned remoteAddress; +}; +static spinlock_t spinlock; +static struct StackElement * head = NULL; +static struct StackElement * tail = NULL; +static struct StackElement * avail = NULL; +static struct StackElement prealloc[16]; + +/* + * Put a stack element onto the available queue, so it can get reused. + * Attention! You must have the spinlock before calling! + */ +void free( struct StackElement * element ) +{ + if( element != NULL ) + { + element->next = avail; + avail = element; + } +} + +/* + * Enqueue the outbound event onto the stack. If the queue was + * empty to begin with, we must also issue it via the Hypervisor + * interface. There is a section of code below that will touch + * the first stack pointer without the protection of the spinlock. + * This is OK, because we know that nobody else will be modifying + * the first pointer when we do this. + */ +static int signalEvent( struct StackElement * newElement ) +{ + int rc = 0; + unsigned long flags; + int go = 1; + struct StackElement * element; + HvLpEvent_Rc hvRc; + + /* enqueue the event */ + if( newElement != NULL ) + { + spin_lock_irqsave( &spinlock, flags ); + if( head == NULL ) + head = newElement; + else + { + go = 0; + tail->next = newElement; + } + newElement->next = NULL; + tail = newElement; + spin_unlock_irqrestore( &spinlock, flags ); + } + + /* send the event */ + while( go ) + { + go = 0; + + /* any DMA data to send beforehand? */ + if( head->dmaDataLength > 0 ) + HvCallEvent_dmaToSp( head->dmaData, head->remoteAddress, head->dmaDataLength, HvLpDma_Direction_LocalToRemote ); + + hvRc = HvCallEvent_signalLpEvent(&head->event.xHvLpEvent); + if( hvRc != HvLpEvent_Rc_Good ) + { + printk( KERN_ERR "mf.c: HvCallEvent_signalLpEvent() failed with %d\n", (int)hvRc ); + + spin_lock_irqsave( &spinlock, flags ); + element = head; + head = head->next; + if( head != NULL ) + go = 1; + spin_unlock_irqrestore( &spinlock, flags ); + + if( element == newElement ) + rc = -EIO; + else + { + if( element->hdlr != NULL ) + { + union SafeCast mySafeCast; + mySafeCast.ptrAsU64 = element->event.xHvLpEvent.xCorrelationToken; + (*element->hdlr)( mySafeCast.ptr, -EIO ); + } + } + + spin_lock_irqsave( &spinlock, flags ); + free( element ); + spin_unlock_irqrestore( &spinlock, flags ); + } + } + + return rc; +} + +/* + * Allocate a new StackElement structure, and initialize it. + */ +static struct StackElement * newStackElement( void ) +{ + struct StackElement * newElement = NULL; + HvLpIndex primaryLp = HvLpConfig_getPrimaryLpIndex(); + unsigned long flags; + + if( newElement == NULL ) + { + spin_lock_irqsave( &spinlock, flags ); + if( avail != NULL ) + { + newElement = avail; + avail = avail->next; + } + spin_unlock_irqrestore( &spinlock, flags ); + } + + if( newElement == NULL ) + newElement = kmalloc(sizeof(struct StackElement),GFP_ATOMIC); + + if( newElement == NULL ) + { + printk( KERN_ERR "mf.c: unable to kmalloc %d bytes\n", sizeof(struct StackElement) ); + return NULL; + } + + memset( newElement, 0, sizeof(struct StackElement) ); + newElement->event.xHvLpEvent.xFlags.xValid = 1; + newElement->event.xHvLpEvent.xFlags.xAckType = HvLpEvent_AckType_ImmediateAck; + newElement->event.xHvLpEvent.xFlags.xAckInd = HvLpEvent_AckInd_DoAck; + newElement->event.xHvLpEvent.xFlags.xFunction = HvLpEvent_Function_Int; + newElement->event.xHvLpEvent.xType = HvLpEvent_Type_MachineFac; + newElement->event.xHvLpEvent.xSourceLp = HvLpConfig_getLpIndex(); + newElement->event.xHvLpEvent.xTargetLp = primaryLp; + newElement->event.xHvLpEvent.xSizeMinus1 = sizeof(newElement->event)-1; + newElement->event.xHvLpEvent.xRc = HvLpEvent_Rc_Good; + newElement->event.xHvLpEvent.xSourceInstanceId = HvCallEvent_getSourceLpInstanceId(primaryLp,HvLpEvent_Type_MachineFac); + newElement->event.xHvLpEvent.xTargetInstanceId = HvCallEvent_getTargetLpInstanceId(primaryLp,HvLpEvent_Type_MachineFac); + + return newElement; +} + +static int signalVspInstruction( struct VspCmdData *vspCmd ) +{ + struct StackElement * newElement = newStackElement(); + int rc = 0; + struct VspRspData response; + DECLARE_MUTEX_LOCKED(Semaphore); + response.xSemaphore = &Semaphore; + response.xResponse = vspCmd; + + if( newElement == NULL ) + rc = -ENOMEM; + else + { + newElement->event.xHvLpEvent.xSubtype = 6; + newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('V'<<8)+('I'<<0); + newElement->event.xUnion.xVspCmd.xTokenUnion.ptr = &response; + newElement->event.xUnion.xVspCmd.xCmd = vspCmd->xCmd; + newElement->event.xUnion.xVspCmd.xLpIndex = HvLpConfig_getLpIndex(); + newElement->event.xUnion.xVspCmd.xRc = 0xFF; + newElement->event.xUnion.xVspCmd.xReserved1 = 0; + memcpy(&(newElement->event.xUnion.xVspCmd.xSubData),&(vspCmd->xSubData), sizeof(vspCmd->xSubData)); + mb(); + + rc = signalEvent(newElement); + } + + if (rc == 0) + { + down(&Semaphore); + } + + return rc; +} + + +/* + * Send a 12-byte CE message to the primary partition VSP object + */ +static int signalCEMsg( char * ceMsg, void * token ) +{ + struct StackElement * newElement = newStackElement(); + int rc = 0; + + if( newElement == NULL ) + rc = -ENOMEM; + else + { + newElement->event.xHvLpEvent.xSubtype = 0; + newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('C'<<8)+('E'<<0); + memcpy( newElement->event.xUnion.xCEMsgData.xCEMsg, ceMsg, 12 ); + newElement->event.xUnion.xCEMsgData.xToken = token; + rc = signalEvent(newElement); + } + + return rc; +} + +/* + * Send a 12-byte CE message and DMA data to the primary partition VSP object + */ +static int dmaAndSignalCEMsg( char * ceMsg, void * token, void * dmaData, unsigned dmaDataLength, unsigned remoteAddress ) +{ + struct StackElement * newElement = newStackElement(); + int rc = 0; + + if( newElement == NULL ) + rc = -ENOMEM; + else + { + newElement->event.xHvLpEvent.xSubtype = 0; + newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('C'<<8)+('E'<<0); + memcpy( newElement->event.xUnion.xCEMsgData.xCEMsg, ceMsg, 12 ); + newElement->event.xUnion.xCEMsgData.xToken = token; + memcpy( newElement->dmaData, dmaData, dmaDataLength ); + newElement->dmaDataLength = dmaDataLength; + newElement->remoteAddress = remoteAddress; + rc = signalEvent(newElement); + } + + return rc; +} + +/* + * Initiate a nice (hopefully) shutdown of Linux. We simply are + * going to try and send the init process a SIGINT signal. If + * this fails (why?), we'll simply force it off in a not-so-nice + * manner. + */ +static int shutdown( void ) +{ + int rc = kill_proc(1,SIGINT,1); + + if( rc ) + { + printk( KERN_ALERT "mf.c: SIGINT to init failed (%d), hard shutdown commencing\n", rc ); + mf_powerOff(); + } + else + printk( KERN_ALERT "mf.c: init has been successfully notified to proceed with shutdown\n" ); + + return rc; +} + +/* + * The primary partition VSP object is sending us a new + * event flow. Handle it... + */ +static void intReceived( struct IoMFLpEvent * event ) +{ + int freeIt = 0; + struct StackElement * two = NULL; + /* ack the interrupt */ + event->xHvLpEvent.xRc = HvLpEvent_Rc_Good; + HvCallEvent_ackLpEvent( &event->xHvLpEvent ); + + /* process interrupt */ + switch( event->xHvLpEvent.xSubtype ) + { + case 0: /* CE message */ + switch( event->xUnion.xCEMsgData.xCEMsg[3] ) + { + case 0x5B: /* power control notification */ + if( (event->xUnion.xCEMsgData.xCEMsg[5]&0x20) != 0 ) + { + printk( KERN_ALERT "mf.c: Commencing partition shutdown\n" ); + if( shutdown() == 0 ) + signalCEMsg( "\x00\x00\x00\xDB\x00\x00\x00\x00\x00\x00\x00\x00", NULL ); + } + break; + case 0xC0: /* get time */ + { + if ( (head != NULL) && ( head->event.xUnion.xCEMsgData.xCEMsg[3] == 0x40 ) ) + { + freeIt = 1; + if ( head->event.xUnion.xCEMsgData.xToken != 0 ) + { + CeMsgCompleteHandler xHdlr = head->event.xUnion.xCEMsgData.xToken->xHdlr; + void * token = head->event.xUnion.xCEMsgData.xToken->xToken; + + if (xHdlr != NULL) + (*xHdlr)( token, &(event->xUnion.xCEMsgData) ); + } + } + } + break; + } + + /* remove from queue */ + if ( freeIt == 1 ) + { + unsigned long flags; + spin_lock_irqsave( &spinlock, flags ); + if( head != NULL ) + { + struct StackElement *oldHead = head; + head = head->next; + two = head; + free( oldHead ); + } + spin_unlock_irqrestore( &spinlock, flags ); + } + + /* send next waiting event */ + if( two != NULL ) + signalEvent( NULL ); + break; + case 1: /* IT sys shutdown */ + printk( KERN_ALERT "mf.c: Commencing system shutdown\n" ); + shutdown(); + break; + } +} + +/* + * The primary partition VSP object is acknowledging the receipt + * of a flow we sent to them. If there are other flows queued + * up, we must send another one now... + */ +static void ackReceived( struct IoMFLpEvent * event ) +{ + unsigned long flags; + struct StackElement * two = NULL; + unsigned long freeIt = 0; + + /* handle current event */ + if( head != NULL ) + { + switch( event->xHvLpEvent.xSubtype ) + { + case 0: /* CE msg */ + if( event->xUnion.xCEMsgData.xCEMsg[3] == 0x40 ) + { + if ( event->xUnion.xCEMsgData.xCEMsg[2] != 0 ) + { + freeIt = 1; + if ( head->event.xUnion.xCEMsgData.xToken != 0 ) + { + CeMsgCompleteHandler xHdlr = head->event.xUnion.xCEMsgData.xToken->xHdlr; + void * token = head->event.xUnion.xCEMsgData.xToken->xToken; + + if (xHdlr != NULL) + (*xHdlr)( token, &(event->xUnion.xCEMsgData) ); + } + } + } + else + { + freeIt = 1; + } + break; + case 4: /* allocate */ + case 5: /* deallocate */ + if( head->hdlr != NULL ) + { + union SafeCast mySafeCast; + mySafeCast.ptrAsU64 = event->xHvLpEvent.xCorrelationToken; + (*head->hdlr)( mySafeCast.ptr, event->xUnion.xAllocData.xCount ); + } + freeIt = 1; + break; + case 6: + { + struct VspRspData *rsp = (struct VspRspData *)event->xUnion.xVspCmd.xTokenUnion.ptr; + + if (rsp != NULL) + { + if (rsp->xResponse != NULL) + memcpy(rsp->xResponse, &(event->xUnion.xVspCmd), sizeof(event->xUnion.xVspCmd)); + if (rsp->xSemaphore != NULL) + up(rsp->xSemaphore); + } + else + { + printk( KERN_ERR "mf.c: no rsp\n"); + } + freeIt = 1; + } + break; + } + } + else + printk( KERN_ERR "mf.c: stack empty for receiving ack\n" ); + + /* remove from queue */ + spin_lock_irqsave( &spinlock, flags ); + if(( head != NULL ) && ( freeIt == 1 )) + { + struct StackElement *oldHead = head; + head = head->next; + two = head; + free( oldHead ); + } + spin_unlock_irqrestore( &spinlock, flags ); + + /* send next waiting event */ + if( two != NULL ) + signalEvent( NULL ); +} + +/* + * This is the generic event handler we are registering with + * the Hypervisor. Ensure the flows are for us, and then + * parse it enough to know if it is an interrupt or an + * acknowledge. + */ +static void hvHandler( struct HvLpEvent * event, struct pt_regs * regs ) +{ + if( (event != NULL) && (event->xType == HvLpEvent_Type_MachineFac) ) + { + switch( event->xFlags.xFunction ) + { + case HvLpEvent_Function_Ack: + ackReceived( (struct IoMFLpEvent *)event ); + break; + case HvLpEvent_Function_Int: + intReceived( (struct IoMFLpEvent *)event ); + break; + default: + printk( KERN_ERR "mf.c: non ack/int event received\n" ); + break; + } + } + else + printk( KERN_ERR "mf.c: alien event received\n" ); +} + +/* + * Global kernel interface to allocate and seed events into the + * Hypervisor. + */ +void mf_allocateLpEvents( HvLpIndex targetLp, + HvLpEvent_Type type, + unsigned size, + unsigned count, + MFCompleteHandler hdlr, + void * userToken ) +{ + struct StackElement * newElement = newStackElement(); + int rc = 0; + + if( newElement == NULL ) + rc = -ENOMEM; + else + { + union SafeCast mine; + mine.ptr = userToken; + newElement->event.xHvLpEvent.xSubtype = 4; + newElement->event.xHvLpEvent.xCorrelationToken = mine.ptrAsU64; + newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('M'<<8)+('A'<<0); + newElement->event.xUnion.xAllocData.xTargetLp = targetLp; + newElement->event.xUnion.xAllocData.xType = type; + newElement->event.xUnion.xAllocData.xSize = size; + newElement->event.xUnion.xAllocData.xCount = count; + newElement->hdlr = hdlr; + rc = signalEvent(newElement); + } + + if( (rc != 0) && (hdlr != NULL) ) + (*hdlr)( userToken, rc ); +} + +/* + * Global kernel interface to unseed and deallocate events already in + * Hypervisor. + */ +void mf_deallocateLpEvents( HvLpIndex targetLp, + HvLpEvent_Type type, + unsigned count, + MFCompleteHandler hdlr, + void * userToken ) +{ + struct StackElement * newElement = newStackElement(); + int rc = 0; + + if( newElement == NULL ) + rc = -ENOMEM; + else + { + union SafeCast mine; + mine.ptr = userToken; + newElement->event.xHvLpEvent.xSubtype = 5; + newElement->event.xHvLpEvent.xCorrelationToken = mine.ptrAsU64; + newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('M'<<8)+('D'<<0); + newElement->event.xUnion.xAllocData.xTargetLp = targetLp; + newElement->event.xUnion.xAllocData.xType = type; + newElement->event.xUnion.xAllocData.xCount = count; + newElement->hdlr = hdlr; + rc = signalEvent(newElement); + } + + if( (rc != 0) && (hdlr != NULL) ) + (*hdlr)( userToken, rc ); +} + +/* + * Global kernel interface to tell the VSP object in the primary + * partition to power this partition off. + */ +void mf_powerOff( void ) +{ + printk( KERN_ALERT "mf.c: Down it goes...\n" ); + signalCEMsg( "\x00\x00\x00\x4D\x00\x00\x00\x00\x00\x00\x00\x00", NULL ); + for(;;); +} + +/* + * Global kernel interface to tell the VSP object in the primary + * partition to reboot this partition. + */ +void mf_reboot( void ) +{ + printk( KERN_ALERT "mf.c: Preparing to bounce...\n" ); + signalCEMsg( "\x00\x00\x00\x4E\x00\x00\x00\x00\x00\x00\x00\x00", NULL ); + for(;;); +} + +/* + * Display a single word SRC onto the VSP control panel. + */ +void mf_displaySrc( u32 word ) +{ + u8 ce[12]; + + memcpy( ce, "\x00\x00\x00\x4A\x00\x00\x00\x01\x00\x00\x00\x00", 12 ); + ce[8] = word>>24; + ce[9] = word>>16; + ce[10] = word>>8; + ce[11] = word; + signalCEMsg( ce, NULL ); +} + +/* + * Display a single word SRC of the form "PROGXXXX" on the VSP control panel. + */ +void mf_displayProgress( u16 value ) +{ + u8 ce[12]; + u8 src[72]; + + memcpy( ce, "\x00\x00\x04\x4A\x00\x00\x00\x48\x00\x00\x00\x00", 12 ); + memcpy( src, + "\x01\x00\x00\x01" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "\x00\x00\x00\x00" + "PROGxxxx" + " ", + 72 ); + src[6] = value>>8; + src[7] = value&255; + src[44] = "0123456789ABCDEF"[(value>>12)&15]; + src[45] = "0123456789ABCDEF"[(value>>8)&15]; + src[46] = "0123456789ABCDEF"[(value>>4)&15]; + src[47] = "0123456789ABCDEF"[value&15]; + dmaAndSignalCEMsg( ce, NULL, src, sizeof(src), 9*64*1024 ); +} + +/* + * Clear the VSP control panel. Used to "erase" an SRC that was + * previously displayed. + */ +void mf_clearSrc( void ) +{ + signalCEMsg( "\x00\x00\x00\x4B\x00\x00\x00\x00\x00\x00\x00\x00", NULL ); +} + +/* + * Initialization code here. + */ +void mf_init( void ) +{ + int i; + + /* initialize */ + spin_lock_init( &spinlock ); + for( i = 0; i < sizeof(prealloc)/sizeof(*prealloc); ++i ) + free( &prealloc[i] ); + HvLpEvent_registerHandler( HvLpEvent_Type_MachineFac, &hvHandler ); + + /* virtual continue ack */ + signalCEMsg( "\x00\x00\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00", NULL ); + + /* initialization complete */ + printk( KERN_NOTICE "mf.c: iSeries Linux LPAR Machine Facilities initialized\n" ); + + iSeries_proc_callback(&mf_proc_init); +} + +void mf_setSide(char side) +{ + int rc = 0; + u64 newSide = 0; + struct VspCmdData myVspCmd; + + memset(&myVspCmd, 0, sizeof(myVspCmd)); + if (side == 'A') + newSide = 0; + else if (side == 'B') + newSide = 1; + else if (side == 'C') + newSide = 2; + else + newSide = 3; + + myVspCmd.xSubData.xFunction02SelectIplTypeIn.xIplType = newSide; + myVspCmd.xCmd = 10; + + rc = signalVspInstruction(&myVspCmd); +} + +char mf_getSide(void) +{ + char returnValue = ' '; + int rc = 0; + struct VspCmdData myVspCmd; + + memset(&myVspCmd, 0, sizeof(myVspCmd)); + myVspCmd.xCmd = 2; + myVspCmd.xSubData.xFunction02SelectIplTypeIn.xIplType = 0; + mb(); + rc = signalVspInstruction(&myVspCmd); + + if(rc != 0) + { + return returnValue; + } + else + { + if (myVspCmd.xRc == 0) + { + if (myVspCmd.xSubData.xGetIplTypeOut.xIplType == 0) + returnValue = 'A'; + else if (myVspCmd.xSubData.xGetIplTypeOut.xIplType == 1) + returnValue = 'B'; + else if (myVspCmd.xSubData.xGetIplTypeOut.xIplType == 2) + returnValue = 'C'; + else + returnValue = 'D'; + } + } + + return returnValue; +} + +void mf_getSrcHistory(char *buffer, int size) +{ + /* struct IplTypeReturnStuff returnStuff; + struct StackElement * newElement = newStackElement(); + int rc = 0; + char *pages[4]; + + pages[0] = kmalloc(4096, GFP_ATOMIC); + pages[1] = kmalloc(4096, GFP_ATOMIC); + pages[2] = kmalloc(4096, GFP_ATOMIC); + pages[3] = kmalloc(4096, GFP_ATOMIC); + if(( newElement == NULL ) || (pages[0] == NULL) || (pages[1] == NULL) || (pages[2] == NULL) || (pages[3] == NULL)) + rc = -ENOMEM; + else + { + returnStuff.xType = 0; + returnStuff.xRc = 0; + returnStuff.xDone = 0; + newElement->event.xHvLpEvent.xSubtype = 6; + newElement->event.xHvLpEvent.x.xSubtypeData = ('M'<<24)+('F'<<16)+('V'<<8)+('I'<<0); + newElement->event.xUnion.xVspCmd.xEvent = &returnStuff; + newElement->event.xUnion.xVspCmd.xCmd = 4; + newElement->event.xUnion.xVspCmd.xLpIndex = HvLpConfig_getLpIndex(); + newElement->event.xUnion.xVspCmd.xRc = 0xFF; + newElement->event.xUnion.xVspCmd.xReserved1 = 0; + newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[0] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[0])); + newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[1] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[1])); + newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[2] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[2])); + newElement->event.xUnion.xVspCmd.xSubData.xGetSrcHistoryIn.xPage[3] = (0x8000000000000000ULL | virt_to_absolute((unsigned long)pages[3])); + mb(); + rc = signalEvent(newElement); + } + + if(rc != 0) + { + return; + } + else + { + while (returnStuff.xDone != 1) + { + udelay(10); + } + + if (returnStuff.xRc == 0) + { + memcpy(buffer, pages[0], size); + } + } + + kfree(pages[0]); + kfree(pages[1]); + kfree(pages[2]); + kfree(pages[3]);*/ +} + +void mf_setCmdLine(const char *cmdline, int size, u64 side) +{ + struct VspCmdData myVspCmd; + int rc = 0; + dma_addr_t dma_addr = 0; + char *page = pci_alloc_consistent(NULL, size, &dma_addr); + + if (page == NULL) { + printk(KERN_ERR "mf.c: couldn't allocate memory to set command line\n"); + return; + } + + copy_from_user(page, cmdline, size); + + memset(&myVspCmd, 0, sizeof(myVspCmd)); + myVspCmd.xCmd = 31; + myVspCmd.xSubData.xSetKernelCmdLineIn.xToken = dma_addr; + myVspCmd.xSubData.xSetKernelCmdLineIn.xAddressType = HvLpDma_AddressType_TceIndex; + myVspCmd.xSubData.xSetKernelCmdLineIn.xSide = side; + myVspCmd.xSubData.xSetKernelCmdLineIn.xTransferLength = size; + mb(); + rc = signalVspInstruction(&myVspCmd); + + pci_free_consistent(NULL, size, page, dma_addr); +} + +int mf_getCmdLine(char *cmdline, int *size, u64 side) +{ + struct VspCmdData myVspCmd; + int rc = 0; + int len = *size; + dma_addr_t dma_addr = pci_map_single(NULL, cmdline, *size, PCI_DMA_FROMDEVICE); + + memset(cmdline, 0, *size); + memset(&myVspCmd, 0, sizeof(myVspCmd)); + myVspCmd.xCmd = 33; + myVspCmd.xSubData.xGetKernelCmdLineIn.xToken = dma_addr; + myVspCmd.xSubData.xGetKernelCmdLineIn.xAddressType = HvLpDma_AddressType_TceIndex; + myVspCmd.xSubData.xGetKernelCmdLineIn.xSide = side; + myVspCmd.xSubData.xGetKernelCmdLineIn.xTransferLength = *size; + mb(); + rc = signalVspInstruction(&myVspCmd); + + if ( ! rc ) { + + if (myVspCmd.xRc == 0) + { + len = myVspCmd.xSubData.xGetKernelCmdLineOut.xTransferLength; + } + // else + // { + // memcpy(cmdline, "Bad cmdline", 11); + // } + } + + pci_unmap_single(NULL, dma_addr, *size, PCI_DMA_FROMDEVICE); + + return len; +} + + +int mf_setVmlinuxChunk(const char *buffer, int size, int offset, u64 side) +{ + struct VspCmdData myVspCmd; + int rc = 0; + + dma_addr_t dma_addr = 0; + + char *page = pci_alloc_consistent(NULL, size, &dma_addr); + + if (page == NULL) { + printk(KERN_ERR "mf.c: couldn't allocate memory to set vmlinux chunk\n"); + return -ENOMEM; + } + + copy_from_user(page, buffer, size); + memset(&myVspCmd, 0, sizeof(myVspCmd)); + + myVspCmd.xCmd = 30; + myVspCmd.xSubData.xGetKernelImageIn.xToken = dma_addr; + myVspCmd.xSubData.xGetKernelImageIn.xAddressType = HvLpDma_AddressType_TceIndex; + myVspCmd.xSubData.xGetKernelImageIn.xSide = side; + myVspCmd.xSubData.xGetKernelImageIn.xOffset = offset; + myVspCmd.xSubData.xGetKernelImageIn.xTransferLength = size; + mb(); + rc = signalVspInstruction(&myVspCmd); + + if(rc == 0) + { + if (myVspCmd.xRc == 0) + { + rc = 0; + } + else + { + rc = -ENOMEM; + } + } + + pci_free_consistent(NULL, size, page, dma_addr); + + return rc; +} + +int mf_getVmlinuxChunk(char *buffer, int *size, int offset, u64 side) +{ + struct VspCmdData myVspCmd; + int rc = 0; + int len = *size; + + dma_addr_t dma_addr = pci_map_single(NULL, buffer, *size, PCI_DMA_FROMDEVICE); + + memset(buffer, 0, len); + + memset(&myVspCmd, 0, sizeof(myVspCmd)); + myVspCmd.xCmd = 32; + myVspCmd.xSubData.xGetKernelImageIn.xToken = dma_addr; + myVspCmd.xSubData.xGetKernelImageIn.xAddressType = HvLpDma_AddressType_TceIndex; + myVspCmd.xSubData.xGetKernelImageIn.xSide = side; + myVspCmd.xSubData.xGetKernelImageIn.xOffset = offset; + myVspCmd.xSubData.xGetKernelImageIn.xTransferLength = len; + mb(); + rc = signalVspInstruction(&myVspCmd); + + if(rc == 0) + { + if (myVspCmd.xRc == 0) + { + *size = myVspCmd.xSubData.xGetKernelImageOut.xTransferLength; + } + else + { + rc = -ENOMEM; + } + } + + pci_unmap_single(NULL, dma_addr, *size, PCI_DMA_FROMDEVICE); + + return rc; +} + +int mf_setRtcTime(unsigned long time) +{ + struct rtc_time tm; + + to_tm(time, &tm); + + return mf_setRtc( &tm ); +} + +struct RtcTimeData +{ + struct semaphore *xSemaphore; + struct CeMsgData xCeMsg; + int xRc; +}; + +void getRtcTimeComplete(void * token, struct CeMsgData *ceMsg) +{ + struct RtcTimeData *rtc = (struct RtcTimeData *)token; + + memcpy(&(rtc->xCeMsg), ceMsg, sizeof(rtc->xCeMsg)); + + rtc->xRc = 0; + up(rtc->xSemaphore); +} + +static unsigned long lastsec = 1; + +int mf_getRtcTime(unsigned long *time) +{ +// unsigned long usec, tsec; + + u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart)); + u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1); + int year = 1970; + int year1 = ( dataWord1 >> 24 ) & 0x000000FF; + int year2 = ( dataWord1 >> 16 ) & 0x000000FF; + int sec = ( dataWord1 >> 8 ) & 0x000000FF; + int min = dataWord1 & 0x000000FF; + int hour = ( dataWord2 >> 24 ) & 0x000000FF; + int day = ( dataWord2 >> 8 ) & 0x000000FF; + int mon = dataWord2 & 0x000000FF; + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year1); + BCD_TO_BIN(year2); + year = year1 * 100 + year2; + + *time = mktime(year, mon, day, hour, min, sec); + + *time += ( jiffies / HZ ); + + // Now THIS is a nasty hack! + // It ensures that the first two calls to mf_getRtcTime get different + // answers. That way the loop in init_time (time.c) will not think + // the clock is stuck. + if ( lastsec ) { + *time -= lastsec; + --lastsec; + } + + return 0; + +} + +int mf_getRtc( struct rtc_time * tm ) +{ + + struct CeMsgCompleteData ceComplete; + struct RtcTimeData rtcData; + int rc = 0; + DECLARE_MUTEX_LOCKED(Semaphore); + + memset(&ceComplete, 0, sizeof(ceComplete)); + memset(&rtcData, 0, sizeof(rtcData)); + + rtcData.xSemaphore = &Semaphore; + + ceComplete.xHdlr = &getRtcTimeComplete; + ceComplete.xToken = (void *)&rtcData; + + rc = signalCEMsg( "\x00\x00\x00\x40\x00\x00\x00\x00\x00\x00\x00\x00", &ceComplete ); + + if ( rc == 0 ) + { + down(&Semaphore); + + if ( rtcData.xRc == 0) + { + u32 dataWord1 = *((u32 *)(rtcData.xCeMsg.xCEMsg+4)); + u32 dataWord2 = *((u32 *)(rtcData.xCeMsg.xCEMsg+8)); + u8 year = (dataWord1 >> 16 ) & 0x000000FF; + u8 sec = ( dataWord1 >> 8 ) & 0x000000FF; + u8 min = dataWord1 & 0x000000FF; + u8 hour = ( dataWord2 >> 24 ) & 0x000000FF; + u8 day = ( dataWord2 >> 8 ) & 0x000000FF; + u8 mon = dataWord2 & 0x000000FF; + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + + if ( year <= 69 ) + year += 100; + + tm->tm_sec = sec; + tm->tm_min = min; + tm->tm_hour = hour; + tm->tm_mday = day; + tm->tm_mon = mon; + tm->tm_year = year; + + } + else + { + rc = rtcData.xRc; + tm->tm_sec = 0; + tm->tm_min = 0; + tm->tm_hour = 0; + tm->tm_mday = 15; + tm->tm_mon = 5; + tm->tm_year = 52; + + } + } + + return rc; + +} + +int mf_setRtc(struct rtc_time * tm) +{ + char ceTime[12] = "\x00\x00\x00\x41\x00\x00\x00\x00\x00\x00\x00\x00"; + int rc = 0; + u8 day, mon, hour, min, sec, y1, y2; + unsigned year; + + year = 1900 + tm->tm_year; + y1 = year / 100; + y2 = year % 100; + + sec = tm->tm_sec; + min = tm->tm_min; + hour = tm->tm_hour; + day = tm->tm_mday; + mon = tm->tm_mon + 1; + + BIN_TO_BCD(sec); + BIN_TO_BCD(min); + BIN_TO_BCD(hour); + BIN_TO_BCD(mon); + BIN_TO_BCD(day); + BIN_TO_BCD(y1); + BIN_TO_BCD(y2); + + ceTime[4] = y1; + ceTime[5] = y2; + ceTime[6] = sec; + ceTime[7] = min; + ceTime[8] = hour; + ceTime[10] = day; + ceTime[11] = mon; + + rc = signalCEMsg( ceTime, NULL ); + + return rc; +} + + + diff -Nru a/arch/ppc/iSeries/mf_proc.c b/arch/ppc/iSeries/mf_proc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/mf_proc.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,309 @@ +/* + * mf_proc.c + * Copyright (C) 2001 Kyle A. Lucke IBM Corporation + * + * 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 + */ + + +/* Change Activity: */ +/* End Change Activity */ + +#ifndef _MF_PROC_H +#include +#endif +#ifndef MF_H_INCLUDED +#include +#endif +#include + +static struct proc_dir_entry *mf_proc_root = NULL; + +int proc_mf_dump_cmdline +(char *page, char **start, off_t off, int count, int *eof, void *data); + +int proc_mf_dump_vmlinux +(char *page, char **start, off_t off, int count, int *eof, void *data); + +int proc_mf_dump_side +(char *page, char **start, off_t off, int count, int *eof, void *data); + +int proc_mf_change_side +(struct file *file, const char *buffer, unsigned long count, void *data); + +int proc_mf_dump_src +(char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_mf_change_src (struct file *file, const char *buffer, unsigned long count, void *data); +int proc_mf_change_cmdline(struct file *file, const char *buffer, unsigned long count, void *data); +int proc_mf_change_vmlinux(struct file *file, const char *buffer, unsigned long count, void *data); + + +void mf_proc_init(struct proc_dir_entry *iSeries_proc) +{ + struct proc_dir_entry *ent = NULL; + struct proc_dir_entry *mf_a = NULL; + struct proc_dir_entry *mf_b = NULL; + struct proc_dir_entry *mf_c = NULL; + struct proc_dir_entry *mf_d = NULL; + + mf_proc_root = proc_mkdir("mf", iSeries_proc); + if (!mf_proc_root) return; + + mf_a = proc_mkdir("A", mf_proc_root); + if (!mf_a) return; + + ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_a); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_mf_dump_cmdline; + ent->write_proc = proc_mf_change_cmdline; + + ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR|S_IWUSR, mf_a); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_mf_dump_vmlinux; + ent->write_proc = proc_mf_change_vmlinux; + + mf_b = proc_mkdir("B", mf_proc_root); + if (!mf_b) return; + + ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_b); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)1; + ent->read_proc = proc_mf_dump_cmdline; + ent->write_proc = proc_mf_change_cmdline; + + ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR|S_IWUSR, mf_b); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)1; + ent->read_proc = proc_mf_dump_vmlinux; + ent->write_proc = proc_mf_change_vmlinux; + + mf_c = proc_mkdir("C", mf_proc_root); + if (!mf_c) return; + + ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_c); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)2; + ent->read_proc = proc_mf_dump_cmdline; + ent->write_proc = proc_mf_change_cmdline; + + ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR|S_IWUSR, mf_c); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)2; + ent->read_proc = proc_mf_dump_vmlinux; + ent->write_proc = proc_mf_change_vmlinux; + + mf_d = proc_mkdir("D", mf_proc_root); + if (!mf_d) return; + + + ent = create_proc_entry("cmdline", S_IFREG|S_IRUSR|S_IWUSR, mf_d); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)3; + ent->read_proc = proc_mf_dump_cmdline; + ent->write_proc = proc_mf_change_cmdline; + + ent = create_proc_entry("vmlinux", S_IFREG|S_IRUSR, mf_d); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)3; + ent->read_proc = proc_mf_dump_vmlinux; + ent->write_proc = NULL; + + ent = create_proc_entry("side", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_mf_dump_side; + ent->write_proc = proc_mf_change_side; + + ent = create_proc_entry("src", S_IFREG|S_IRUSR|S_IWUSR, mf_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_mf_dump_src; + ent->write_proc = proc_mf_change_src; + + +} + +int proc_mf_dump_cmdline +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = count; + char *p; + + len = mf_getCmdLine(page, &len, (u64)(int)data); + + p = page + len - 1; + while ( p > page ) { + if ( (*p == 0) || (*p == ' ') ) + --p; + else + break; + } + if ( *p != '\n' ) { + ++p; + *p = '\n'; + } + ++p; + *p = 0; + len = p - page; + + len -= off; + if (len < count) { + *eof = 1; + if (len <= 0) + return 0; + } else + len = count; + *start = page + off; + return len; +} + +int proc_mf_dump_vmlinux +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int sizeToGet = count; + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (mf_getVmlinuxChunk(page, &sizeToGet, off, (u64)(int)data) == 0) + { + if (sizeToGet != 0) + { + *start = page + off; + printk("mf_proc.c: got count %d off %d\n", sizeToGet, (int)off); + return sizeToGet; + } + else + { + printk("mf_proc.c: eof\n"); + *eof = 1; + return 0; + } + } + else + { + printk("mf_proc.c: eof\n"); + *eof = 1; + return 0; + } +} + + +int proc_mf_dump_side +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = 0; + + char mf_current_side = mf_getSide(); + len = sprintf(page, "%c\n", mf_current_side); + + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +int proc_mf_change_side(struct file *file, const char *buffer, unsigned long count, void *data) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if ((*buffer != 'A') && + (*buffer != 'B') && + (*buffer != 'C') && + (*buffer != 'D')) + { + printk(KERN_ERR "mf_proc.c: proc_mf_change_side: invalid side\n"); + return -EINVAL; + } + + mf_setSide(*buffer); + + return count; +} + +int proc_mf_dump_src +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = 0; + mf_getSrcHistory(page, count); + len = count; + len -= off; + if (len < count) { + *eof = 1; + if (len <= 0) + return 0; + } else + len = count; + *start = page + off; + return len; +} + +int proc_mf_change_src(struct file *file, const char *buffer, unsigned long count, void *data) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if ((count < 4) && (count != 1)) + { + printk(KERN_ERR "mf_proc: invalid src\n"); + return -EINVAL; + } + + if ((count == 1) && ((*buffer) == '\0')) + { + mf_clearSrc(); + } + else + { + mf_displaySrc(*(u32 *)buffer); + } + + return count; +} + +int proc_mf_change_cmdline(struct file *file, const char *buffer, unsigned long count, void *data) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + mf_setCmdLine(buffer, count, (u64)(int)data); + + return count; +} + +int proc_mf_change_vmlinux(struct file *file, const char *buffer, unsigned long count, void *data) +{ + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + mf_setVmlinuxChunk(buffer, count, file->f_pos, (u64)(int)data); + file->f_pos += count; + + return count; +} diff -Nru a/arch/ppc/iSeries/pmc_proc.c b/arch/ppc/iSeries/pmc_proc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/pmc_proc.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,647 @@ +/* + * pmc_proc.c + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * 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 + */ + + +/* Change Activity: */ +/* End Change Activity */ + +#ifndef _PMC_PROC_H +#include +#endif + +#include +#include +#include +#include + +#define MMCR0 795 +#define MMCR1 798 +#define MMCRA 786 +#define PMC1 787 +#define PMC2 788 +#define PMC3 789 +#define PMC4 790 +#define PMC5 791 +#define PMC6 792 +#define PMC7 793 +#define PMC8 794 + +static int proc_pmc_control_mode = 0; +#define PMC_CONTROL_CPI 1 +#define PMC_CONTROL_TLB 2 + +static struct proc_dir_entry *pmc_proc_root = NULL; + +int proc_get_lpevents( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_reset_lpevents( struct file *file, const char *buffer, unsigned long count, void *data); + +int proc_pmc_get_control( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_mmcr0( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_mmcr1( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_mmcra( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc1( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc2( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc3( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc4( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc5( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc6( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc7( char *page, char **start, off_t off, int count, int *eof, void *data); +int proc_pmc_get_pmc8( char *page, char **start, off_t off, int count, int *eof, void *data); + +int proc_pmc_set_control( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_mmcr0( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_mmcr1( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_mmcra( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc1( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc2( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc3( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc4( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc5( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc6( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc7( struct file *file, const char *buffer, unsigned long count, void *data); +int proc_pmc_set_pmc8( struct file *file, const char *buffer, unsigned long count, void *data); + +void pmc_proc_init(struct proc_dir_entry *iSeries_proc) +{ + struct proc_dir_entry *ent = NULL; + + ent = create_proc_entry("lpevents", S_IFREG|S_IRUGO, iSeries_proc); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_get_lpevents; + ent->write_proc = proc_reset_lpevents; + + pmc_proc_root = proc_mkdir("pmc", iSeries_proc); + if (!pmc_proc_root) return; + + ent = create_proc_entry("control", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_control; + ent->write_proc = proc_pmc_set_control; + + ent = create_proc_entry("mmcr0", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_mmcr0; + ent->write_proc = proc_pmc_set_mmcr0; + + ent = create_proc_entry("mmcr1", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_mmcr1; + ent->write_proc = proc_pmc_set_mmcr1; + + ent = create_proc_entry("mmcra", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_mmcra; + ent->write_proc = proc_pmc_set_mmcra; + + ent = create_proc_entry("pmc1", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc1; + ent->write_proc = proc_pmc_set_pmc1; + + ent = create_proc_entry("pmc2", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc2; + ent->write_proc = proc_pmc_set_pmc2; + + ent = create_proc_entry("pmc3", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc3; + ent->write_proc = proc_pmc_set_pmc3; + + ent = create_proc_entry("pmc4", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc4; + ent->write_proc = proc_pmc_set_pmc4; + + ent = create_proc_entry("pmc5", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc5; + ent->write_proc = proc_pmc_set_pmc5; + + ent = create_proc_entry("pmc6", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc6; + ent->write_proc = proc_pmc_set_pmc6; + + ent = create_proc_entry("pmc7", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc7; + ent->write_proc = proc_pmc_set_pmc7; + + ent = create_proc_entry("pmc8", S_IFREG|S_IRUSR|S_IWUSR, pmc_proc_root); + if (!ent) return; + ent->nlink = 1; + ent->data = (void *)0; + ent->read_proc = proc_pmc_get_pmc8; + ent->write_proc = proc_pmc_set_pmc8; + + +} + +static int pmc_calc_metrics( char *page, char **start, off_t off, int count, int *eof, int len) +{ + if ( len <= off+count) + *eof = 1; + *start = page+off; + len -= off; + if ( len > count ) + len = count; + if ( len < 0 ) + len = 0; + return len; +} + +static char * lpEventTypes[9] = { + "Hypervisor\t\t", + "Machine Facilities\t", + "Session Manager\t", + "SPD I/O\t\t", + "Virtual Bus\t\t", + "PCI I/O\t\t", + "RIO I/O\t\t", + "Virtual Lan\t\t", + "Virtual I/O\t\t" + }; + + +int proc_get_lpevents +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + unsigned i; + int len = 0; + + len += sprintf( page+len, "LpEventQueue 0\n" ); + len += sprintf( page+len, " events processed:\t%lu\n", + (unsigned long)xItLpQueue.xLpIntCount ); + for (i=0; i<9; ++i) { + len += sprintf( page+len, " %s %10lu\n", + lpEventTypes[i], + (unsigned long)xItLpQueue.xLpIntCountByType[i] ); + } + return pmc_calc_metrics( page, start, off, count, eof, len ); + +} + +int proc_reset_lpevents( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + return count; +} + +int proc_pmc_get_control +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = 0; + + if ( proc_pmc_control_mode == PMC_CONTROL_CPI ) { + unsigned long mach_cycles = mfspr( PMC5 ); + unsigned long inst_complete = mfspr( PMC4 ); + unsigned long inst_dispatch = mfspr( PMC3 ); + unsigned long thread_active_run = mfspr( PMC1 ); + unsigned long thread_active = mfspr( PMC2 ); + unsigned long cpi = 0; + unsigned long cpithou = 0; + unsigned long remain; + + if ( inst_complete ) { + cpi = thread_active_run / inst_complete; + remain = thread_active_run % inst_complete; + if ( inst_complete > 1000000 ) + cpithou = remain / ( inst_complete / 1000 ); + else + cpithou = ( remain * 1000 ) / inst_complete; + } + len += sprintf( page+len, "PMC CPI Mode\nRaw Counts\n" ); + len += sprintf( page+len, "machine cycles : %12lu\n", mach_cycles ); + len += sprintf( page+len, "thread active cycles : %12lu\n\n", thread_active ); + + len += sprintf( page+len, "instructions completed : %12lu\n", inst_complete ); + len += sprintf( page+len, "instructions dispatched : %12lu\n", inst_dispatch ); + len += sprintf( page+len, "thread active run cycles : %12lu\n", thread_active_run ); + + len += sprintf( page+len, "thread active run cycles/instructions completed\n" ); + len += sprintf( page+len, "CPI = %lu.%03lu\n", cpi, cpithou ); + + } + else if ( proc_pmc_control_mode == PMC_CONTROL_TLB ) { + len += sprintf( page+len, "PMC TLB Mode\n" ); + len += sprintf( page+len, "I-miss count : %12u\n", mfspr( PMC1 ) ); + len += sprintf( page+len, "I-miss latency : %12u\n", mfspr( PMC2 ) ); + len += sprintf( page+len, "D-miss count : %12u\n", mfspr( PMC3 ) ); + len += sprintf( page+len, "D-miss latency : %12u\n", mfspr( PMC4 ) ); + len += sprintf( page+len, "IERAT miss count : %12u\n", mfspr( PMC5 ) ); + len += sprintf( page+len, "D-reference count : %12u\n", mfspr( PMC6 ) ); + len += sprintf( page+len, "miss PTEs searched : %12u\n", mfspr( PMC7 ) ); + len += sprintf( page+len, "miss >8 PTEs searched : %12u\n", mfspr( PMC8 ) ); + } + /* IMPLEMENT ME */ + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_mmcr0 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(MMCR0) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_mmcr1 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(MMCR1) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_mmcra +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(MMCRA) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc1 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC1) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc2 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC2) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc3 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC3) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc4 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC4) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc5 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC5) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc6 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC6) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc7 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC7) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +int proc_pmc_get_pmc8 +(char *page, char **start, off_t off, int count, int *eof, void *data) +{ + int len = sprintf( page, "0x%08x", mfspr(PMC8) ); + return pmc_calc_metrics( page, start, off, count, eof, len ); +} + +unsigned long proc_pmc_conv_int( const char *buf, unsigned count ) +{ + const char * p; + char b0, b1; + unsigned v, multiplier, mult, i; + unsigned long val; + multiplier = 10; + p = buf; + if ( count >= 3 ) { + b0 = buf[0]; + b1 = buf[1]; + if ( ( b0 == '0' ) && + ( ( b1 == 'x' ) || ( b1 == 'X' ) ) ) { + p = buf + 2; + count -= 2; + multiplier = 16; + } + + } + val = 0; + for ( i=0; i= '0' ) && ( b0 <= '9' ) ) + v = b0 - '0'; + else if ( multiplier == 16 ) { + if ( ( b0 >= 'a' ) && ( b0 <= 'f' ) ) + v = b0 - 'a' + 10; + else if ( ( b0 >= 'A' ) && ( b0 <= 'F' ) ) + v = b0 - 'A' + 10; + else + mult = 1; + } + else + mult = 1; + val *= mult; + val += v; + } + + return val; + +} + +static inline void proc_pmc_stop(void) +{ + // Freeze all counters, leave everything else alone + mtspr( MMCR0, mfspr( MMCR0 ) | 0x80000000 ); +} + +static inline void proc_pmc_start(void) +{ + // Unfreeze all counters, leave everything else alone + mtspr( MMCR0, mfspr( MMCR0 ) & ~0x80000000 ); + +} + +static inline void proc_pmc_reset(void) +{ + // Clear all the PMCs to zero + // Assume a "stop" has already frozen the counters + // Clear all the PMCs + mtspr( PMC1, 0 ); + mtspr( PMC2, 0 ); + mtspr( PMC3, 0 ); + mtspr( PMC4, 0 ); + mtspr( PMC5, 0 ); + mtspr( PMC6, 0 ); + mtspr( PMC7, 0 ); + mtspr( PMC8, 0 ); + +} + +static inline void proc_pmc_cpi(void) +{ + /* Configure the PMC registers to count cycles and instructions */ + /* so we can compute cpi */ + /* + * MMCRA[30] = 1 Don't count in wait state (CTRL[31]=0) + * MMCR0[6] = 1 Freeze counters when any overflow + * MMCR0[19:25] = 0x01 PMC1 counts Thread Active Run Cycles + * MMCR0[26:31] = 0x05 PMC2 counts Thread Active Cycles + * MMCR1[0:4] = 0x07 PMC3 counts Instructions Dispatched + * MMCR1[5:9] = 0x03 PMC4 counts Instructions Completed + * MMCR1[10:14] = 0x06 PMC5 counts Machine Cycles + * + */ + + proc_pmc_control_mode = PMC_CONTROL_CPI; + + // Indicate to hypervisor that we are using the PMCs + ((struct Paca *)mfspr(SPRG1))->xLpPacaPtr->xPMCRegsInUse = 1; + + // Freeze all counters + mtspr( MMCR0, 0x80000000 ); + mtspr( MMCR1, 0x00000000 ); + + // Clear all the PMCs + mtspr( PMC1, 0 ); + mtspr( PMC2, 0 ); + mtspr( PMC3, 0 ); + mtspr( PMC4, 0 ); + mtspr( PMC5, 0 ); + mtspr( PMC6, 0 ); + mtspr( PMC7, 0 ); + mtspr( PMC8, 0 ); + + // Freeze counters in Wait State (CTRL[31]=0) + mtspr( MMCRA, 0x00000002 ); + + // PMC3<-0x07, PMC4<-0x03, PMC5<-0x06 + mtspr( MMCR1, 0x38cc0000 ); + + mb(); + + // PMC1<-0x01, PMC2<-0x05 + // Start all counters + mtspr( MMCR0, 0x02000045 ); + +} + +static inline void proc_pmc_tlb(void) +{ + /* Configure the PMC registers to count tlb misses */ + /* + * MMCR0[6] = 1 Freeze counters when any overflow + * MMCR0[19:25] = 0x55 Group count + * PMC1 counts I misses + * PMC2 counts I miss duration (latency) + * PMC3 counts D misses + * PMC4 counts D miss duration (latency) + * PMC5 counts IERAT misses + * PMC6 counts D references (including PMC7) + * PMC7 counts miss PTEs searched + * PMC8 counts miss >8 PTEs searched + * + */ + + proc_pmc_control_mode = PMC_CONTROL_TLB; + + // Indicate to hypervisor that we are using the PMCs + ((struct Paca *)mfspr(SPRG1))->xLpPacaPtr->xPMCRegsInUse = 1; + + // Freeze all counters + mtspr( MMCR0, 0x80000000 ); + mtspr( MMCR1, 0x00000000 ); + + // Clear all the PMCs + mtspr( PMC1, 0 ); + mtspr( PMC2, 0 ); + mtspr( PMC3, 0 ); + mtspr( PMC4, 0 ); + mtspr( PMC5, 0 ); + mtspr( PMC6, 0 ); + mtspr( PMC7, 0 ); + mtspr( PMC8, 0 ); + + mtspr( MMCRA, 0x00000000 ); + + mb(); + + // PMC1<-0x55 + // Start all counters + mtspr( MMCR0, 0x02001540 ); + +} + +int proc_pmc_set_control( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + if ( ! strncmp( buffer, "stop", 4 ) ) + proc_pmc_stop(); + else if ( ! strncmp( buffer, "start", 5 ) ) + proc_pmc_start(); + else if ( ! strncmp( buffer, "reset", 5 ) ) + proc_pmc_reset(); + else if ( ! strncmp( buffer, "cpi", 3 ) ) + proc_pmc_cpi(); + else if ( ! strncmp( buffer, "tlb", 3 ) ) + proc_pmc_tlb(); + + /* IMPLEMENT ME */ + return count; +} + +int proc_pmc_set_mmcr0( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + v = v & ~0x04000000; /* Don't allow interrupts for now */ + if ( v & ~0x80000000 ) /* Inform hypervisor we are using PMCs */ + ((struct Paca *)mfspr(SPRG1))->xLpPacaPtr->xPMCRegsInUse = 1; + else + ((struct Paca *)mfspr(SPRG1))->xLpPacaPtr->xPMCRegsInUse = 0; + mtspr( MMCR0, v ); + + return count; +} + +int proc_pmc_set_mmcr1( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( MMCR1, v ); + + return count; +} + +int proc_pmc_set_mmcra( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + v = v & ~0x00008000; /* Don't allow interrupts for now */ + mtspr( MMCRA, v ); + + return count; +} + + +int proc_pmc_set_pmc1( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC1, v ); + + return count; +} + +int proc_pmc_set_pmc2( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC2, v ); + + return count; +} + +int proc_pmc_set_pmc3( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC3, v ); + + return count; +} + +int proc_pmc_set_pmc4( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC4, v ); + + return count; +} + +int proc_pmc_set_pmc5( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC5, v ); + + return count; +} + +int proc_pmc_set_pmc6( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC6, v ); + + return count; +} + +int proc_pmc_set_pmc7( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC7, v ); + + return count; +} + +int proc_pmc_set_pmc8( struct file *file, const char *buffer, unsigned long count, void *data ) +{ + unsigned long v; + v = proc_pmc_conv_int( buffer, count ); + mtspr( PMC8, v ); + + return count; +} + + diff -Nru a/arch/ppc/iSeries/rtc.c b/arch/ppc/iSeries/rtc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/rtc.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,265 @@ +/* + * Real Time Clock interface for IBM iSeries + * + * Based on rtc.c by Paul Gortmaker + * + * This driver allows use of the real time clock + * from user space. It exports the /dev/rtc + * interface supporting various ioctl() and also the + * /proc/driver/rtc pseudo-file for status information. + * + * iSeries does not support RTC interrupts nor an alarm. + * + * 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. + * + * 1.0 Mike Corrigan: IBM iSeries rtc support + */ + +#define RTC_VERSION "1.0" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +/* + * We sponge a minor off of the misc major. No need slurping + * up another valuable major dev number for this. If you add + * an ioctl, make sure you don't conflict with SPARC's RTC + * ioctls. + */ + +static loff_t rtc_llseek(struct file *file, loff_t offset, int origin); + +static ssize_t rtc_read(struct file *file, char *buf, + size_t count, loff_t *ppos); + +static int rtc_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg); + +static void get_rtc_time (struct rtc_time *rtc_tm); + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data); + +/* + * If this driver ever becomes modularised, it will be really nice + * to make the epoch retain its value across module reload... + */ + +static unsigned long epoch = 1900; /* year corresponding to 0x00 */ + +static const unsigned char days_in_mo[] = +{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +/* + * Now all the various file operations that we export. + */ + +static loff_t rtc_llseek(struct file *file, loff_t offset, int origin) +{ + return -ESPIPE; +} + +static ssize_t rtc_read(struct file *file, char *buf, + size_t count, loff_t *ppos) +{ + return -EIO; +} + +static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) +{ + struct rtc_time wtime; + + switch (cmd) { + case RTC_RD_TIME: /* Read the time/date from RTC */ + { + get_rtc_time(&wtime); + break; + } + case RTC_SET_TIME: /* Set the RTC */ + { + struct rtc_time rtc_tm; + unsigned char mon, day, hrs, min, sec, leap_yr; + unsigned int yrs; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, + sizeof(struct rtc_time))) + return -EFAULT; + + yrs = rtc_tm.tm_year; + mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */ + day = rtc_tm.tm_mday; + hrs = rtc_tm.tm_hour; + min = rtc_tm.tm_min; + sec = rtc_tm.tm_sec; + + if (yrs < 70) + return -EINVAL; + + leap_yr = ((!(yrs % 4) && (yrs % 100)) || !(yrs % 400)); + + if ((mon > 12) || (day == 0)) + return -EINVAL; + + if (day > (days_in_mo[mon] + ((mon == 2) && leap_yr))) + return -EINVAL; + + if ((hrs >= 24) || (min >= 60) || (sec >= 60)) + return -EINVAL; + + if ( yrs > 169 ) + return -EINVAL; + + mf_setRtc( &rtc_tm ); + + return 0; + } + case RTC_EPOCH_READ: /* Read the epoch. */ + { + return put_user (epoch, (unsigned long *)arg); + } + case RTC_EPOCH_SET: /* Set the epoch. */ + { + /* + * There were no RTC clocks before 1900. + */ + if (arg < 1900) + return -EINVAL; + + if (!capable(CAP_SYS_TIME)) + return -EACCES; + + epoch = arg; + return 0; + } + default: + return -EINVAL; + } + return copy_to_user((void *)arg, &wtime, sizeof wtime) ? -EFAULT : 0; +} + +static int rtc_open(struct inode *inode, struct file *file) +{ + return 0; +} + +static int rtc_release(struct inode *inode, struct file *file) +{ + return 0; +} + +/* + * The various file operations we support. + */ + +static struct file_operations rtc_fops = { + owner: THIS_MODULE, + llseek: rtc_llseek, + read: rtc_read, + ioctl: rtc_ioctl, + open: rtc_open, + release: rtc_release, +}; + +static struct miscdevice rtc_dev= +{ + RTC_MINOR, + "rtc", + &rtc_fops +}; + +static int __init rtc_init(void) +{ + misc_register(&rtc_dev); + create_proc_read_entry ("driver/rtc", 0, 0, rtc_read_proc, NULL); + + printk(KERN_INFO "iSeries Real Time Clock Driver v" RTC_VERSION "\n"); + + return 0; +} + +static void __exit rtc_exit (void) +{ + remove_proc_entry ("driver/rtc", NULL); + misc_deregister(&rtc_dev); +} + +module_init(rtc_init); +module_exit(rtc_exit); +EXPORT_NO_SYMBOLS; + +/* + * Info exported via "/proc/driver/rtc". + */ + +static int rtc_proc_output (char *buf) +{ + + char *p; + struct rtc_time tm; + + p = buf; + + get_rtc_time(&tm); + + /* + * There is no way to tell if the luser has the RTC set for local + * time or for Universal Standard Time (GMT). Probably local though. + */ + p += sprintf(p, + "rtc_time\t: %02d:%02d:%02d\n" + "rtc_date\t: %04d-%02d-%02d\n" + "rtc_epoch\t: %04lu\n", + tm.tm_hour, tm.tm_min, tm.tm_sec, + tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, epoch); + + p += sprintf(p, + "DST_enable\t: no\n" + "BCD\t\t: yes\n" + "24hr\t\t: yes\n" ); + + return p - buf; +} + +static int rtc_read_proc(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len = rtc_proc_output (page); + if (len <= off+count) *eof = 1; + *start = page + off; + len -= off; + if (len>count) len = count; + if (len<0) len = 0; + return len; +} + +static void get_rtc_time(struct rtc_time *rtc_tm) +{ + mf_getRtc( rtc_tm ); + + rtc_tm->tm_mon--; +} + + diff -Nru a/arch/ppc/iSeries/viopath.c b/arch/ppc/iSeries/viopath.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/iSeries/viopath.c Sat Jun 16 06:00:32 2001 @@ -0,0 +1,711 @@ +/* + * arch/ppc/iSeries/viopath.c + * + * iSeries Virtual I/O Message Path code + * + * Author: Dave Boutcher + * (C) Copyright 2000 IBM Corporation + * + * 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) anyu 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 + * + */ +#ifndef _HVLPEVENT_H +#include +#endif +#ifndef _HVLPConfig_H +#include +#endif +#ifndef _HVCallCfg_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef _VIO_H +#include "asm/iSeries/vio.h" +#endif +#ifndef _MF_H +#include "asm/iSeries/mf.h" +#endif +#ifndef _ISERIES_PROC_H +#include +#endif + +/* Status of the path to each other partition in the system. + * This is overkill, since we will only ever establish connections + * to our hosting partition and the primary partition on the system. + * But this allows for other support in the future. + */ +static struct viopathStatus { + int isOpen:1; /* Did we open the path? */ + int isActive:1; /* Do we have a mon msg outstanding */ +#if defined(CONFIG_VIOCONS) + int xCharUsers; +#endif +#if defined(CONFIG_VIODASD) + int xBlockUsers; +#endif +#if defined(CONFIG_VIOCD) + int xCDUsers; +#endif +#if defined(CONFIG_VIOTAPE) + int xTapeUsers; +#endif + int xConfigUsers; + HvLpInstanceId mSourceInst; + HvLpInstanceId mTargetInst; + int numberAllocated; + spinlock_t statuslock; + unsigned long statuslockFlags; +} viopathStatus[HVMAXARCHITECTEDLPS]; + +/* We use this structure to handle asynchronous responses. The caller + * blocks on the semaphore and the handler posts the semaphore. + */ +struct doneAllocParms_t { + struct semaphore *sem; + int number; +}; + +/* Put a sequence number in each mon msg. The value is not + * important. Start at something other than 0 just for + * readability. wrapping this is ok. + */ +static u8 viomonseq = 22; + +/* Our hosting logical partition. We get this at startup + * time, and different modules access this variable directly. + */ +HvLpIndex viopath_hostLp; + +/* For each kind of incoming event we set a pointer to a + * routine to call. + */ +static vio_event_handler_t *vio_handleCharEvent; +static vio_event_handler_t *vio_handleBlockEvent; +static vio_event_handler_t *vio_handleCDEvent; +static vio_event_handler_t *vio_handleTapeEvent; + +/* + * For each kind of event we allocate a buffer that is + * guaranteed not to cross a page boundary + */ +void * vio_char_event_buffer; +void * vio_block_event_buffer; +void * vio_cd_event_buffer; +void * vio_tape_event_buffer; + +/*************************************************************************** + * A page to build an lp event in + ***************************************************************************/ +unsigned long VIOReqPage; + +/*************************************************************************** + * Handle reads from the proc file system + ***************************************************************************/ +static int proc_read(char *buf, char **start, off_t offset, + int blen, int *eof, void *data) +{ + HvLpEvent_Rc hvrc; + DECLARE_MUTEX_LOCKED(Semaphore); + dma_addr_t dmaa = pci_map_single( NULL, buf, PAGE_SIZE, PCI_DMA_FROMDEVICE); + int len = PAGE_SIZE; + + if (len > blen) + len = blen; + + memset(buf,0x00,len); + hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp, + HvLpEvent_Type_VirtualIo, + viomajorsubtype_config | vioconfigget, + HvLpEvent_AckInd_DoAck, + HvLpEvent_AckType_ImmediateAck, + viopath_sourceinst(viopath_hostLp), + viopath_targetinst(viopath_hostLp), + (u64)(u32)&Semaphore, + VIOVERSION << 16, + ((u64)dmaa) << 32, + len, + 0, + 0); + if (hvrc != HvLpEvent_Rc_Good) + { + printk("viopath hv error on op %d\n",(int)hvrc); + } + + down(&Semaphore); + + pci_unmap_single( NULL, dmaa, PAGE_SIZE, PCI_DMA_FROMDEVICE); + + *eof = 1; + return strlen(buf); +} + +/*************************************************************************** + * Handle writes to our proc file system + ***************************************************************************/ +static int proc_write(struct file *file, const char *buffer, + unsigned long count, void *data) +{ + printk("viopath: in proc_write, got %ld bytes starting with %c\n", + count, buffer[0]); + return count; +} + +/*************************************************************************** + * setup our proc file system entries + ***************************************************************************/ +void vio_proc_init(struct proc_dir_entry *iSeries_proc) +{ + struct proc_dir_entry *ent; + ent = create_proc_entry("config", S_IFREG|S_IRUSR, iSeries_proc); + if (!ent) return; + ent->nlink = 1; + ent->data = NULL; + ent->read_proc = proc_read; + ent->write_proc = proc_write; +} + +/* Boot time initialization of the vio path code. Needs + * to be called before any VIO components start + */ +void viopath_init(void) +{ + int i; + memset(viopathStatus,0x00,sizeof(viopathStatus)); + for (i=0; ixFlags.xFunction == HvLpEvent_Function_Int) + { + printk("viopath: got monitor INT event\n"); + remoteLp = event->xSourceLp; + if (!viopathStatus[remoteLp].isActive) + sendMonMsg(remoteLp); + } + else + { + remoteLp = event->xTargetLp; + printk("viopath: got monitor ACK event %d, sinst %d, tinst %d\n", + (int)event->xCorrelationToken, + event->xSourceInstanceId, + event->xTargetInstanceId); + /* Other partition went away! */ + if ((event->xSourceInstanceId != viopathStatus[remoteLp].mSourceInst) || + (event->xTargetInstanceId != viopathStatus[remoteLp].mTargetInst)) + { + printk("viopath: ignoring ack....mismatched instances\n"); + } + else + { + printk("viopath: closing path %d\n",remoteLp); + + viopathStatus[remoteLp].isActive = 0; + + if (vio_handleBlockEvent!= NULL) + (*vio_handleBlockEvent)(NULL); + + if (vio_handleCharEvent != NULL) + (*vio_handleCharEvent)(NULL); + + if (vio_handleCDEvent != NULL) + (*vio_handleCDEvent)(NULL); + + if (vio_handleTapeEvent != NULL) + (*vio_handleTapeEvent)(NULL); + } + } +} + +void vio_setBlockHandler(vio_event_handler_t *beh) +{ + vio_handleBlockEvent = *beh; +} + +void vio_clearBlockHandler(void) +{ + vio_handleBlockEvent = NULL; +} + +void vio_setCharHandler(vio_event_handler_t *ceh) +{ + vio_handleCharEvent = *ceh; +} + +void vio_clearCharHandler(void) +{ + vio_handleCharEvent = NULL; +} + +void vio_setCDHandler(vio_event_handler_t *ceh) +{ + vio_handleCDEvent = *ceh; +} + +void vio_clearCDHandler(void) +{ + vio_handleCDEvent = NULL; +} + +void vio_setTapeHandler(vio_event_handler_t *ceh) +{ + vio_handleTapeEvent = *ceh; +} + +void vio_clearTapeHandler(void) +{ + vio_handleTapeEvent = NULL; +} + +static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs) +{ + HvLpIndex remoteLp; + if (event->xFlags.xFunction == HvLpEvent_Function_Int) + { + remoteLp = event->xSourceLp; + if (event->xSourceInstanceId != viopathStatus[remoteLp].mTargetInst) + { + printk("viopath: int msg rcvd, source inst (%d) doesnt match (%d)\n", + viopathStatus[remoteLp].mTargetInst, + event->xSourceInstanceId); + return; + } + + if (event->xTargetInstanceId != viopathStatus[remoteLp].mSourceInst) + { + printk("viopath: int msg rcvd, target inst (%d) doesnt match (%d)\n", + viopathStatus[remoteLp].mSourceInst, + event->xTargetInstanceId); + return; + } + } + else + { + remoteLp = event->xTargetLp; + if (event->xSourceInstanceId != viopathStatus[remoteLp].mSourceInst) + { + printk("viopath: ack msg rcvd, source inst (%d) doesnt match (%d)\n", + viopathStatus[remoteLp].mSourceInst, + event->xSourceInstanceId); + return; + } + + if (event->xTargetInstanceId != viopathStatus[remoteLp].mTargetInst) + { + printk("viopath: ack msg rcvd, target inst (%d) doesnt match (%d)\n", + viopathStatus[remoteLp].mTargetInst, + event->xTargetInstanceId); + return; + } + } + + + switch (event->xSubtype & VIOMAJOR_SUBTYPE_MASK) { + case viomajorsubtype_config: + up((struct semaphore *)(u32)event->xCorrelationToken); + break; + + case viomajorsubtype_monitor: + handleMonitorEvent(event); + break; + case viomajorsubtype_blockio: + if (vio_handleBlockEvent) + { + (*vio_handleBlockEvent)(event); + } + else + { + printk("vio: unexpected virtual blockio event\n"); + if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) + { + event->xRc = HvLpEvent_Rc_InvalidSubtype; + HvCallEvent_ackLpEvent(event); + } + } + break; + case viomajorsubtype_chario: + if (vio_handleCharEvent) + { + (*vio_handleCharEvent)(event); + } + else + { + printk("vio: unexpected virtual chario event\n"); + if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) + { + event->xRc = HvLpEvent_Rc_InvalidSubtype; + HvCallEvent_ackLpEvent(event); + } + } + break; + case viomajorsubtype_cdio: + if (vio_handleCDEvent) + { + (*vio_handleCDEvent)(event); + } + else + { + printk("vio: unexpected virtual cd event\n"); + if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) + { + event->xRc = HvLpEvent_Rc_InvalidSubtype; + HvCallEvent_ackLpEvent(event); + } + } + break; + case viomajorsubtype_tape: + if (vio_handleTapeEvent) + { + (*vio_handleTapeEvent)(event); + } + else + { + printk("vio: unexpected virtual tape event\n"); + if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) + { + event->xRc = HvLpEvent_Rc_InvalidSubtype; + HvCallEvent_ackLpEvent(event); + } + } + break; + default: + printk("vio: unexpected virtual io event subtype %d\n",event->xSubtype); + if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) + { + event->xRc = HvLpEvent_Rc_InvalidSubtype; + HvCallEvent_ackLpEvent(event); + } + } +} + + +static void viopath_donealloc(void *parm, int number) +{ + struct doneAllocParms_t *doneAllocParmsp = (struct doneAllocParms_t *)parm; + doneAllocParmsp->number = number; + up(doneAllocParmsp->sem); +} + +int viopath_open(HvLpIndex remoteLp, int subtype) +{ + HvLpEvent_Rc hvrc; + struct doneAllocParms_t doneAllocParms; + DECLARE_MUTEX_LOCKED(Semaphore); + + if ((remoteLp >= HvMaxArchitectedLps) || (remoteLp == HvLpIndexInvalid)) + return -EINVAL; + + if (VIOReqPage == 0) + { + /* Get a page to build read/write LP events in */ + VIOReqPage = get_free_page(GFP_KERNEL); + if (!VIOReqPage) + { + printk("viopath: error allocating I/O memory\n"); + return -ENOMEM; + } + + vio_char_event_buffer = (void *)VIOReqPage; + vio_block_event_buffer = (void *)(VIOReqPage+256); + vio_cd_event_buffer = (void *)(VIOReqPage+512); + vio_tape_event_buffer = (void *)(VIOReqPage+768); + } + + if ( (0) +#if defined(CONFIG_VIODASD) + || (subtype == viomajorsubtype_blockio) +#endif +#if defined(CONFIG_VIOCONS) + || (subtype == viomajorsubtype_chario) +#endif +#if defined(CONFIG_VIOCD) + || (subtype == viomajorsubtype_cdio) +#endif +#if defined(CONFIG_VIOTAPE) + || (subtype == viomajorsubtype_tape) +#endif + ) + { + viopath_statuslock(remoteLp); + switch (subtype) { +#if defined(CONFIG_VIODASD) + case viomajorsubtype_blockio: + viopathStatus[remoteLp].xBlockUsers++; + break; +#endif +#if defined(CONFIG_VIOCONS) + case viomajorsubtype_chario: + viopathStatus[remoteLp].xCharUsers++; + break; +#endif +#if defined(CONFIG_VIOCD) + case viomajorsubtype_cdio: + viopathStatus[remoteLp].xCDUsers++; + break; +#endif +#if defined(CONFIG_VIOTAPE) + case viomajorsubtype_tape: + viopathStatus[remoteLp].xTapeUsers++; + break; +#endif + default: + } + if (!viopathStatus[remoteLp].isOpen) + { + HvCallEvent_openLpEventPath(remoteLp, HvLpEvent_Type_VirtualIo); + + viopathStatus[remoteLp].mSourceInst = HvCallEvent_getSourceLpInstanceId(remoteLp, HvLpEvent_Type_VirtualIo); + viopathStatus[remoteLp].mTargetInst = HvCallEvent_getTargetLpInstanceId(remoteLp, HvLpEvent_Type_VirtualIo); + + printk("viopath: open, setting sinst %d, tinst %d\n", + viopathStatus[remoteLp].mSourceInst, + viopathStatus[remoteLp].mTargetInst); + + doneAllocParms.sem = &Semaphore; + + mf_allocateLpEvents(remoteLp, + HvLpEvent_Type_VirtualIo, + 250, /* TODO: Put a sizeof VIOLpEvent in here! */ + 25, /* TODO: Work out the real number */ + &viopath_donealloc, + &doneAllocParms); + + down(&Semaphore); + + viopathStatus[remoteLp].numberAllocated = doneAllocParms.number; + + HvLpEvent_registerHandler(HvLpEvent_Type_VirtualIo, &vio_handleEvent); + + viopathStatus[remoteLp].isOpen = 1; + + hvrc = HvCallEvent_signalLpEventFast(remoteLp, + HvLpEvent_Type_VirtualIo, + viomajorsubtype_monitor, + HvLpEvent_AckInd_DoAck, + HvLpEvent_AckType_DeferredAck, + viopathStatus[remoteLp].mSourceInst, + viopathStatus[remoteLp].mTargetInst, + 0, 0, 0, 0, 0, 0); + + if (hvrc == HvLpEvent_Rc_Good) + { + viopathStatus[remoteLp].isActive = 1; + } + else + { + viopathStatus[remoteLp].isActive = 0; + } + } + viopath_statusunlock(remoteLp); + + return 0; + } + else /* invalid subtype */ + { + printk("viopath: invalid path subtype %d\n",subtype); + return -EINVAL; + } +} + +int viopath_close(HvLpIndex remoteLp, int subtype) +{ + printk("viopath: close(%d,%4.4x)\n",remoteLp,subtype); + + if ((remoteLp >= HvMaxArchitectedLps) || (remoteLp == HvLpIndexInvalid)) + return -EINVAL; + + if ( (0) +#if defined(CONFIG_VIODASD) + || (subtype == viomajorsubtype_blockio) +#endif +#if defined(CONFIG_VIOCONS) + || (subtype == viomajorsubtype_chario) +#endif +#if defined(CONFIG_VIOCD) + || (subtype == viomajorsubtype_cdio) +#endif +#if defined(CONFIG_VIOTAPE) + || (subtype == viomajorsubtype_tape) +#endif + ) + { + viopath_statuslock(remoteLp); + switch (subtype) { +#if defined(CONFIG_VIODASD) + case viomajorsubtype_blockio: + viopathStatus[remoteLp].xBlockUsers--; + break; +#endif +#if defined(CONFIG_VIOCONS) + case viomajorsubtype_chario: + viopathStatus[remoteLp].xCharUsers--; + break; +#endif +#if defined(CONFIG_VIOCD) + case viomajorsubtype_cdio: + viopathStatus[remoteLp].xCDUsers--; + break; +#endif +#if defined(CONFIG_VIOTAPE) + case viomajorsubtype_tape: + viopathStatus[remoteLp].xTapeUsers--; + break; +#endif + default: + } + + if ((viopathStatus[remoteLp].isOpen) +#if defined(CONFIG_VIODASD) + && (viopathStatus[remoteLp].xBlockUsers == 0) +#endif +#if defined(CONFIG_VIOCONS) + && (viopathStatus[remoteLp].xCharUsers == 0) +#endif +#if defined(CONFIG_VIOCD) + && (viopathStatus[remoteLp].xCDUsers == 0) +#endif +#if defined(CONFIG_VIOTAPE) + && (viopathStatus[remoteLp].xTapeUsers == 0) +#endif + ) + { + printk("viopath: closing event path\n"); + HvCallEvent_closeLpEventPath(remoteLp, HvLpEvent_Type_VirtualIo); + viopathStatus[remoteLp].isOpen = 0; + viopathStatus[remoteLp].isActive = 0; + } + viopath_statusunlock(remoteLp); + + return 0; + } + else /* invalid subtype */ + { + printk("viopath: invalid path subtype %d\n",subtype); + return -EINVAL; + } +} diff -Nru a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile --- a/arch/ppc/kernel/Makefile Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/kernel/Makefile Sat Jun 16 06:00:20 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.19 05/26/01 14:48:14 paulus +# BK Id: SCCS/s.Makefile 1.29 06/13/01 16:09:13 paulus # # # Makefile for the linux kernel. @@ -29,21 +29,19 @@ O_TARGET := kernel.o -export-objs := ppc_ksyms.o prep_setup.o +export-objs := ppc_ksyms.o prep_setup.o ppc_stubs.o obj-y := entry.o traps.o irq.o idle.o time.o misc.o \ process.o signal.o ptrace.o \ ppc_htab.o semaphore.o syscalls.o \ - align.o setup.o + align.o setup.o cputable.o obj-$(CONFIG_MODULES) += ppc_ksyms.o -obj-$(CONFIG_POWER4) += xics.o obj-$(CONFIG_PCI) += pci.o pci-dma.o obj-$(CONFIG_KGDB) += ppc-stub.o -obj-$(CONFIG_PMAC_PBOOK) += sleep.o obj-$(CONFIG_SMP) += smp.o -obj-$(CONFIG_PPC_RTAS) += error_log.o proc_rtas.o +obj-$(CONFIG_POWER4) += xics.o obj-$(CONFIG_NVRAM) += pmac_nvram.o -obj-$(CONFIG_PREP_RESIDUAL) += residual.o +obj-$(CONFIG_TAU) += temp.o obj-$(CONFIG_4xx) += ppc4xx_pic.o obj-$(CONFIG_OAK) += oak_setup.o obj-$(CONFIG_WALNUT) += walnut_setup.o @@ -56,8 +54,6 @@ ifndef CONFIG_MATH_EMULATION obj-y += softemu8xx.o endif -else -obj-y += hashtable.o endif obj-$(CONFIG_MBX) += i8259.o obj-$(CONFIG_APUS) += apus_setup.o @@ -69,8 +65,38 @@ chrp_time.o chrp_pci.o open_pic.o \ indirect_pci.o i8259.o prep_pci.o \ prep_time.o prep_nvram.o prep_setup.o +ifndef CONFIG_ALL_PPC +obj-y += ppc_stubs.o +endif obj-$(CONFIG_PMAC_BACKLIGHT) += pmac_backlight.o +obj-$(CONFIG_PMAC_PBOOK) += sleep.o +obj-$(CONFIG_PREP_RESIDUAL) += residual.o +obj-$(CONFIG_PPC_RTAS) += error_log.o proc_rtas.o obj-$(CONFIG_GEMINI) += gemini_prom.o gemini_pci.o gemini_setup.o \ + open_pic.o +obj-$(CONFIG_K2) += k2_setup.o k2_pic.o k2_pci.o i8259.o \ + indirect_pci.o todc_time.o pci_auto.o +obj-$(CONFIG_MCPN765) += mcpn765_setup.o mcpn765_pci.o todc_time.o \ + indirect_pci.o pci_auto.o open_pic.o \ + i8259.o pplus_common.o +obj-$(CONFIG_MENF1) += menf1_setup.o menf1_pci.o todc_time.o \ + i8259.o mpc10x_common.o pci_auto.o \ + indirect_pci.o +obj-$(CONFIG_MVME5100) += mvme5100_setup.o mvme5100_pci.o open_pic.o \ + todc_time.o indirect_pci.o i8259.o \ + pplus_common.o +obj-$(CONFIG_PCORE) += pcore_setup.o pcore_pci.o mpc10x_common.o \ + todc_time.o i8259.o indirect_pci.o \ + pci_auto.o +obj-$(CONFIG_PRPMC750) += prpmc750_setup.o prpmc750_pci.o open_pic.o \ + indirect_pci.o pplus_common.o +obj-$(CONFIG_SANDPOINT) += sandpoint_setup.o sandpoint_pci.o i8259.o \ + open_pic.o mpc10x_common.o pci_auto.o \ + indirect_pci.o todc_time.o +obj-$(CONFIG_SPRUCE) += spruce_setup.o spruce_pic.o spruce_pci.o \ + indirect_pci.o pci_auto.o +obj-$(CONFIG_ZX4500) += zx4500_setup.o zx4500_pci.o indirect_pci.o \ + pci_auto.o mpc10x_common.o i8259.o \ open_pic.o obj-$(CONFIG_8260) += m8260_setup.o ppc8260_pic.o diff -Nru a/arch/ppc/kernel/align.c b/arch/ppc/kernel/align.c --- a/arch/ppc/kernel/align.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/kernel/align.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.align.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * align.c - handle alignment exceptions for the Power PC. diff -Nru a/arch/ppc/kernel/apus_pci.c b/arch/ppc/kernel/apus_pci.c --- a/arch/ppc/kernel/apus_pci.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/kernel/apus_pci.c Sat Jun 16 06:00:30 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.apus_pci.c 1.3 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) Michel Dänzer diff -Nru a/arch/ppc/kernel/apus_pci.h b/arch/ppc/kernel/apus_pci.h --- a/arch/ppc/kernel/apus_pci.h Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/kernel/apus_pci.h Sat Jun 16 06:00:32 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.apus_pci.h 1.4 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Phase5 CybervisionPPC (TVP4020) definitions for the Permedia2 framebuffer diff -Nru a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c --- a/arch/ppc/kernel/apus_setup.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/kernel/apus_setup.c Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.apus_setup.c 1.11 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/apus_setup.c diff -Nru a/arch/ppc/kernel/bitops.c b/arch/ppc/kernel/bitops.c --- a/arch/ppc/kernel/bitops.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/kernel/bitops.c Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.bitops.c 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) 1996 Paul Mackerras. diff -Nru a/arch/ppc/kernel/checks.c b/arch/ppc/kernel/checks.c --- a/arch/ppc/kernel/checks.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/kernel/checks.c Sat Jun 16 06:00:24 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.checks.c 1.6 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/kernel/chrp_pci.c b/arch/ppc/kernel/chrp_pci.c --- a/arch/ppc/kernel/chrp_pci.c Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/kernel/chrp_pci.c Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.chrp_pci.c 1.16 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * CHRP pci routines. @@ -314,14 +314,16 @@ struct pci_controller *hose; volatile unsigned char *cfg; unsigned int *dma; -#ifdef CONFIG_POWER3 struct device_node *root = find_path_device("/"); +#ifdef CONFIG_POWER3 unsigned int *opprop = (unsigned int *) get_property(root, "platform-open-pic", NULL); int i; #endif for(; dev != NULL; dev = dev->next, ++index) { + if (dev->parent != root) + continue; if (dev->n_addrs < 1) { printk(KERN_WARNING "Can't use %s: no address\n", dev->full_name); diff -Nru a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c --- a/arch/ppc/kernel/chrp_setup.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/kernel/chrp_setup.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.chrp_setup.c 1.20 06/05/01 21:22:02 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/setup.c diff -Nru a/arch/ppc/kernel/chrp_time.c b/arch/ppc/kernel/chrp_time.c --- a/arch/ppc/kernel/chrp_time.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/kernel/chrp_time.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.chrp_time.c 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/i386/kernel/time.c diff -Nru a/arch/ppc/kernel/cpc700.h b/arch/ppc/kernel/cpc700.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/cpc700.h Sat Jun 16 06:00:30 2001 @@ -0,0 +1,107 @@ +/* + * include/asm-ppc/cpc700.h + * + * Header file for IBM CPC700 Host Bridge, et. al. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * This file contains the defines and macros for the IBM CPC700 host bridge, + * memory controller, PIC, UARTs, IIC, and Timers. + */ + +#ifndef _ASMPPC_CPC700_H +#define _ASMPPC_CPC700_H + +#include +#include +#include + +#define CPC700_OUT_32(a,d) (*(u_int *)a = d) +#define CPC700_IN_32(a) (*(u_int *)a) + +/* + * PCI Section + */ +#define CPC700_PCI_CONFIG_ADDR 0xfec00000 +#define CPC700_PCI_CONFIG_DATA 0xfec00004 + +#define CPC700_PMM0_LOCAL 0xff400000 +#define CPC700_PMM0_MASK_ATTR 0xff400004 +#define CPC700_PMM0_PCI_LOW 0xff400008 +#define CPC700_PMM0_PCI_HIGH 0xff40000c +#define CPC700_PMM1_LOCAL 0xff400010 +#define CPC700_PMM1_MASK_ATTR 0xff400014 +#define CPC700_PMM1_PCI_LOW 0xff400018 +#define CPC700_PMM1_PCI_HIGH 0xff40001c +#define CPC700_PMM2_LOCAL 0xff400020 +#define CPC700_PMM2_MASK_ATTR 0xff400024 +#define CPC700_PMM2_PCI_LOW 0xff400028 +#define CPC700_PMM2_PCI_HIGH 0xff40002c +#define CPC700_PTM1_MEMSIZE 0xff400030 +#define CPC700_PTM1_LOCAL 0xff400034 +#define CPC700_PTM2_MEMSIZE 0xff400038 +#define CPC700_PTM2_LOCAL 0xff40003c + +/* + * PIC Section + * + * IBM calls the CPC700's programmable interrupt controller the Universal + * Interrupt Controller or UIC. + */ + +/* + * UIC Register Addresses. + */ +#define CPC700_UIC_UICSR 0xff500880 /* Status Reg (Rd/Clr)*/ +#define CPC700_UIC_UICSRS 0xff500884 /* Status Reg (Set) */ +#define CPC700_UIC_UICER 0xff500888 /* Enable Reg */ +#define CPC700_UIC_UICCR 0xff50088c /* Critical Reg */ +#define CPC700_UIC_UICPR 0xff500890 /* Polarity Reg */ +#define CPC700_UIC_UICTR 0xff500894 /* Trigger Reg */ +#define CPC700_UIC_UICMSR 0xff500898 /* Masked Status Reg */ +#define CPC700_UIC_UICVR 0xff50089c /* Vector Reg */ +#define CPC700_UIC_UICVCR 0xff5008a0 /* Vector Config Reg */ + +#define CPC700_UIC_UICER_ENABLE 0x00000001 /* Enable an IRQ */ + +#define CPC700_UIC_UICVCR_31_HI 0x00000000 /* IRQ 31 hi priority */ +#define CPC700_UIC_UICVCR_0_HI 0x00000001 /* IRQ 0 hi priority */ +#define CPC700_UIC_UICVCR_BASE_MASK 0xfffffffc +#define CPC700_UIC_UICVCR_ORDER_MASK 0x00000001 + +/* Specify value of a bit for an IRQ. */ +#define CPC700_UIC_IRQ_BIT(i) ((0x00000001) << (31 - (i))) + +/* + * UIC Exports... + */ +extern struct hw_interrupt_type cpc700_pic; + +void __init cpc700_pic_init(void); + +#endif /* _ASMPPC_CPC700_H */ diff -Nru a/arch/ppc/kernel/cpc710.h b/arch/ppc/kernel/cpc710.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/cpc710.h Sat Jun 16 06:00:30 2001 @@ -0,0 +1,59 @@ +/* + * arch/ppc/kernel/cpc710.h + * + * Definitions for the IBM CPC710 PCI Host Bridge + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PPC_KERNEL_CPC710_H +#define __PPC_KERNEL_CPC710_H + +/* General bridge and memory controller registers */ +#define PIDR 0xff000008 +#define CNFR 0xff00000c +#define RSTR 0xff000010 +#define UCTL 0xff001000 +#define MPSR 0xff001010 +#define SIOC 0xff001020 +#define ABCNTL 0xff001030 +#define SRST 0xff001040 +#define ERRC 0xff001050 +#define SESR 0xff001060 +#define SEAR 0xff001070 +#define PGCHP 0xff001100 +#define GPDIR 0xff001130 +#define ATAS 0xff001160 +#define AVDG 0xff001170 +#define MCCR 0xff001200 +#define MESR 0xff001220 +#define MEAR 0xff001230 +#define MCER0 0xff001300 +#define MCER1 0xff001310 +#define MCER2 0xff001320 +#define MCER3 0xff001330 +#define MCER4 0xff001340 +#define MCER5 0xff001350 +#define MCER6 0xff001360 +#define MCER7 0xff001370 + +/* System standard configuration registers space */ +#define DCR 0xff200000 +#define DID 0xff200004 +#define BAR 0xff200018 + +/* Device specific configuration space */ +#define PCIENB 0xff201000 + +/* Configuration space registers */ +#define CPC710_BUS_NUMBER 0x40 +#define CPC710_SUB_BUS_NUMBER 0x41 + +#endif /* __PPC_KERNEL_CPC710_H */ diff -Nru a/arch/ppc/kernel/cputable.c b/arch/ppc/kernel/cputable.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/cputable.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,249 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * arch/ppc/kernel/cputable.c + * + * Copyright (C) 2001 Ben. Herrenschmidt (benh@kernel.crashing.org) + * + * 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 +#include +#include +#include +#include +#include + +struct cpu_spec* cur_cpu_spec[NR_CPUS]; + +extern void __setup_cpu_601(int cpu_nr); +extern void __setup_cpu_603(int cpu_nr); +extern void __setup_cpu_604(int cpu_nr); +extern void __setup_cpu_750(int cpu_nr); +extern void __setup_cpu_7400(int cpu_nr); +extern void __setup_cpu_7450(int cpu_nr); +extern void __setup_cpu_power3(int cpu_nr); +extern void __setup_cpu_power4(int cpu_nr); +extern void __setup_cpu_generic(int cpu_nr); + +#define CLASSIC_PPC (!defined(CONFIG_8260) && !defined(CONFIG_8xx) && \ + !defined(CONFIG_4xx) && !defined(CONFIG_POWER3) && \ + !defined(CONFIG_POWER4)) + +/* This table only contains "desktop" CPUs, it need to be filled with embedded + * ones as well... + */ +#define COMMON_PPC (PPC_FEATURE_32 | PPC_FEATURE_HAS_FPU | \ + PPC_FEATURE_HAS_MMU) + +/* We only set the altivec features if the kernel was compiled with altivec + * support + */ +#ifdef CONFIG_ALTIVEC +#define CPU_FTR_ALTIVEC_COMP CPU_FTR_ALTIVEC +#else +#define CPU_FTR_ALTIVEC_COMP 0 +#endif + +struct cpu_spec cpu_specs[] = { +#if CLASSIC_PPC + { /* 601 */ + 0xffff0000, 0x00010000, "601", + CPU_FTR_601, + COMMON_PPC | PPC_FEATURE_601_INSTR | PPC_FEATURE_UNIFIED_CACHE, + 32, 32, + __setup_cpu_601 + }, + { /* 603 */ + 0xffff0000, 0x00030000, "603", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB, + COMMON_PPC, + 32, 32, + __setup_cpu_603 + }, + { /* 603e */ + 0xffff0000, 0x00060000, "603e", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB, + COMMON_PPC, + 32, 32, + __setup_cpu_603 + }, + { /* 603ev */ + 0xffff0000, 0x00070000, "603ev", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB, + COMMON_PPC, + 32, 32, + __setup_cpu_603 + }, + { /* 604 */ + 0xffff0000, 0x00040000, "604", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON, + COMMON_PPC, + 32, 32, + __setup_cpu_604 + }, + { /* 604e */ + 0xfffff000, 0x00090000, "604e", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON, + COMMON_PPC, + 32, 32, + __setup_cpu_604 + }, + { /* 604r */ + 0xffff0000, 0x00090000, "604r", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON, + COMMON_PPC, + 32, 32, + __setup_cpu_604 + }, + { /* 604ev */ + 0xffff0000, 0x000a0000, "604ev", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | CPU_FTR_604_PERF_MON, + COMMON_PPC, + 32, 32, + __setup_cpu_604 + }, + { /* 750 (0x4202, don't support TAU ?) */ + 0xffffffff, 0x00084202, "750", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_L2CR, + COMMON_PPC, + 32, 32, + __setup_cpu_750 + }, + { /* 750CX */ + 0xffffff00, 0x00082200, "750CX", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ONCHIP_L2, + COMMON_PPC, + 32, 32, + __setup_cpu_750 + }, + { /* 740/750 (L2CR bit need fixup for 740) */ + 0xffff0000, 0x00080000, "740/750", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_TAU, + COMMON_PPC, + 32, 32, + __setup_cpu_750 + }, + { /* 7400 rev 1.1 ? (no TAU) */ + 0xffffffff, 0x000c1101, "7400 (1.1)", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_ALTIVEC_COMP, + COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, + 32, 32, + __setup_cpu_7400 + }, + { /* 7400 */ + 0xffff0000, 0x000c0000, "7400", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP, + COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, + 32, 32, + __setup_cpu_7400 + }, + { /* 7410 */ + 0xffff0000, 0x800c0000, "7410", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_CAN_DOZE | CPU_FTR_USE_TB | + CPU_FTR_L2CR | CPU_FTR_TAU | CPU_FTR_ALTIVEC_COMP, + COMMON_PPC | PPC_FEATURE_HAS_ALTIVEC, + 32, 32, + __setup_cpu_7400 + }, + { /* default match, we assume split I/D cache & TB (non-601)... */ + 0x00000000, 0x00000000, "(generic PPC)", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + COMMON_PPC, + 32, 32, + __setup_cpu_generic + }, +#endif /* CLASSIC_PPC */ +#ifdef CONFIG_PPC64BRIDGE + { /* Power3 */ + 0xffff0000, 0x00400000, "Power3 (630)", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + COMMON_PPC | PPC_FEATURE_64, + 128, 128, + __setup_cpu_power3 + }, + { /* Power3+ */ + 0xffff0000, 0x00410000, "Power3 (630+)", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + COMMON_PPC | PPC_FEATURE_64, + 128, 128, + __setup_cpu_power3 + }, +#endif /* CONFIG_POWER3 */ +#ifdef CONFIG_POWER4 + { /* Power4 */ + 0xffff0000, 0x00350000, "Power4", + CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB, + COMMON_PPC | PPC_FEATURE_64, + 128, 128, + __setup_cpu_power4 + }, +#endif /* CONFIG_POWER4 */ +#ifdef CONFIG_8260 + { /* 8260 */ + 0xffff0000, 0x00810000, "8260", + 0, /* FixMe */ + PPC_FEATURE_32, + 32, 32, /* ??? */ + 0, /*__setup_cpu_8260 */ + }, +#endif /* CONFIG_8260 */ +#ifdef CONFIG_8xx + { /* 8xx */ + 0xffff0000, 0x00500000, "8xx", + 0, /* FixMe */ + PPC_FEATURE_32, + 16, 16, + 0, /*__setup_cpu_8xx */ + }, +#endif /* CONFIG_8xx */ +#ifdef CONFIG_4xx + { /* 403GC */ + 0xffffff00, 0x00200200, "403GC", + 0, /* FixMe */ + PPC_FEATURE_32, + 16, 16, + 0, /*__setup_cpu_403 */ + }, + { /* 403GCX */ + 0xffffff00, 0x00201400, "403GCX", + 0, /* FixMe */ + PPC_FEATURE_32, + 16, 16, + 0, /*__setup_cpu_403 */ + }, + { /* 403G ?? */ + 0xffff0000, 0x00200000, "403G ??", + 0, /* FixMe */ + PPC_FEATURE_32, + 16, 16, + 0, /*__setup_cpu_403 */ + }, + { /* 405GP */ + 0xffff0000, 0x40110000, "405GP", + 0, /* FixMe */ + PPC_FEATURE_32 | PPC_FEATURE_HAS_4xxMAC, + 16, 16, + 0, /*__setup_cpu_405 */ + }, +#endif /* CONFIG_4xx */ +#if !CLASSIC_PPC + { /* default match */ + 0x00000000, 0x00000000, "(generic PPC)", + 0, + PPC_FEATURE_32, + 32, 32, + 0, + } +#endif /* !CLASSIC_PPC */ +}; diff -Nru a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S --- a/arch/ppc/kernel/entry.S Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/kernel/entry.S Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.entry.S 1.15 06/09/01 22:16:38 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * PowerPC version @@ -23,12 +23,14 @@ */ #include "ppc_asm.h" +#include +#include +#include +#include #include #include #include -#include -#include -#include +#include #undef SHOW_SYSCALLS #undef SHOW_SYSCALLS_TASK @@ -217,7 +219,9 @@ mfmsr r22 li r0,MSR_FP /* Disable floating-point */ #ifdef CONFIG_ALTIVEC +BEGIN_FTR_SECTION oris r0,r0,MSR_VEC@h +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ andc r22,r22,r0 stw r20,_NIP(r1) @@ -351,13 +355,10 @@ 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 +BEGIN_FTR_SECTION lwz r0,THREAD+THREAD_VRSAVE(r2) - mtspr SPRN_VRSAVE,r0 /* if so, restore VRSAVE reg */ -2: + mtspr SPRN_VRSAVE,r0 /* if G4, restore VRSAVE reg */ +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ addi r0,r1,INT_FRAME_SIZE /* size of frame */ stw r0,THREAD+KSP(r2) /* save kernel stack pointer */ diff -Nru a/arch/ppc/kernel/error_log.c b/arch/ppc/kernel/error_log.c --- a/arch/ppc/kernel/error_log.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/kernel/error_log.c Sat Jun 16 06:00:31 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.error_log.c 1.6 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/error_log.c diff -Nru a/arch/ppc/kernel/error_log.h b/arch/ppc/kernel/error_log.h --- a/arch/ppc/kernel/error_log.h Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/kernel/error_log.h Sat Jun 16 06:00:31 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.error_log.h 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef __ERROR_LOG_H__ #define __ERROR_LOG_H__ diff -Nru a/arch/ppc/kernel/feature.c b/arch/ppc/kernel/feature.c --- a/arch/ppc/kernel/feature.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/kernel/feature.c Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.feature.c 1.10 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/feature.c diff -Nru a/arch/ppc/kernel/find_name.c b/arch/ppc/kernel/find_name.c --- a/arch/ppc/kernel/find_name.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/kernel/find_name.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.find_name.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/kernel/galaxy_pci.c b/arch/ppc/kernel/galaxy_pci.c --- a/arch/ppc/kernel/galaxy_pci.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/kernel/galaxy_pci.c Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.galaxy_pci.c 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * diff -Nru a/arch/ppc/kernel/gemini_pci.c b/arch/ppc/kernel/gemini_pci.c --- a/arch/ppc/kernel/gemini_pci.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/kernel/gemini_pci.c Sat Jun 16 06:00:32 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.gemini_pci.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/kernel/gemini_prom.S b/arch/ppc/kernel/gemini_prom.S --- a/arch/ppc/kernel/gemini_prom.S Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/kernel/gemini_prom.S Sat Jun 16 06:00:30 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.gemini_prom.S 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/gemini_prom.S diff -Nru a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c --- a/arch/ppc/kernel/gemini_setup.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/kernel/gemini_setup.c Sat Jun 16 06:00:32 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.gemini_setup.c 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/setup.c diff -Nru a/arch/ppc/kernel/hashtable.S b/arch/ppc/kernel/hashtable.S --- a/arch/ppc/kernel/hashtable.S Sat Jun 16 06:00:23 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,724 +0,0 @@ -/* - * BK Id: SCCS/s.hashtable.S 1.11 05/17/01 18:14:21 cort - */ -/* - * arch/ppc/kernel/hashtable.S - * - * PowerPC version - * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) - * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP - * Copyright (C) 1996 Cort Dougan - * Adapted for Power Macintosh by Paul Mackerras. - * Low-level exception handlers and MMU support - * rewritten by Paul Mackerras. - * Copyright (C) 1996 Paul Mackerras. - * - * This file contains low-level assembler routines for managing - * the PowerPC MMU hash table. (PPC 8xx processors don't use a - * hash table, so this file is not used on them.) - * - * 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 "ppc_asm.h" -#include -#include -#include - -/* - * Load a PTE into the hash table, if possible. - * The address is in r3, and r4 contains access flags: - * _PAGE_USER (4) if a user-mode access, ored with - * _PAGE_RW (2) if a write. r20 contains DSISR or SRR1, - * so bit 1 (0x40000000) is set if the exception was due - * to no matching PTE being found in the hash table. - * SPRG3 contains the physical address of the current task's thread. - * - * Returns to the caller if the access is illegal or there is no - * mapping for the address. Otherwise it places an appropriate PTE - * in the hash table and returns from the exception. - * Uses r0, r2 - r6, ctr, lr. - * - * For speed, 4 of the instructions get patched once the size and - * physical address of the hash table are known. These definitions - * of Hash_base and Hash_bits below are just an example. - */ -Hash_base = 0x180000 -Hash_bits = 12 /* e.g. 256kB hash table */ -Hash_msk = (((1 << Hash_bits) - 1) * 64) - - .globl hash_page -hash_page: -#ifdef CONFIG_PPC64BRIDGE - mfmsr r0 - clrldi r0,r0,1 /* make sure it's in 32-bit mode */ - MTMSRD(r0) - isync -#endif -#ifdef CONFIG_SMP - SAVE_2GPRS(7,r21) - eieio - lis r2,hash_table_lock@h - ori r2,r2,hash_table_lock@l - tophys(r2,r2) - lis r6,0x0fff0000@h - mtctr r6 - mfspr r5,SPRG3 - lwz r0,PROCESSOR-THREAD(r5) - or r0,r0,r6 -10: lwarx r6,0,r2 - cmpi 0,r6,0 - bne- 12f - stwcx. r0,0,r2 - beq+ 11f - /* spin here a bit */ -12: mfctr r7 - li r8,1000 - mtctr r8 -13: - bdnz 13b - mtctr r7 - cmpw r6,r0 - bdnzf 2,10b - tw 31,31,31 -11: eieio - REST_2GPRS(7, r21) -#endif - /* Get PTE (linux-style) and check access */ - lis r0,KERNELBASE@h /* check if kernel address */ - cmplw 0,r3,r0 - mfspr r2,SPRG3 /* current task's THREAD (phys) */ - lwz r5,PGDIR(r2) /* virt page-table root */ - blt+ 112f /* assume user more likely */ - lis r5,swapper_pg_dir@ha /* if kernel address, use */ - addi r5,r5,swapper_pg_dir@l /* kernel page table */ -112: tophys(r5,r5) /* convert to phys addr */ - rlwimi r5,r3,12,20,29 /* insert top 10 bits of address */ - lwz r5,0(r5) /* get pmd entry */ - rlwinm. r5,r5,0,0,19 /* extract address of pte page */ -#ifdef CONFIG_SMP - beq- hash_page_out /* return if no mapping */ -#else - /* XXX it seems like the 601 will give a machine fault on the - rfi if its alignment is wrong (bottom 4 bits of address are - 8 or 0xc) and we have had a not-taken conditional branch - to the address following the rfi. */ - beqlr- -#endif - tophys(r2,r5) - rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ - ori r4,r4,1 /* set _PAGE_PRESENT bit in access */ - rlwinm r5,r4,5,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ - rlwimi r5,r4,7,22,22 /* _PAGE_RW -> _PAGE_HWWRITE */ - ori r5,r5,0x100 /* set _PAGE_ACCESSED */ -retry: - lwz r6,0(r2) /* get linux-style pte */ - andc. r0,r4,r6 /* check access & ~permission */ -#ifdef CONFIG_SMP - bne- hash_page_out /* return if access not permitted */ -#else - bnelr- -#endif - andc. r0,r5,r6 /* any bits not yet set? */ - beq 2f - - /* Update the linux PTE atomically */ - lwarx r0,0,r2 /* refetch the pte and check */ - cmpw 0,r0,r6 /* that it hasn't been changed */ - bne- retry /* retry if it has */ - or r6,r6,r5 /* set accessed/dirty bits */ - stwcx. r6,0,r2 /* attempt to update PTE */ - bne- retry /* retry if someone got there first */ - - /* Convert linux-style PTE to low word of PPC-style PTE */ -2: rlwinm r4,r6,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */ - rlwimi r6,r6,32-1,31,31 /* _PAGE_USER -> PP (both bits now) */ - ori r4,r4,0xe04 /* clear out reserved bits */ - andc r6,r6,r4 /* PP=2 or 0, when _PAGE_HWWRITE */ - -#ifdef CONFIG_POWER4 - /* - * XXX hack hack hack - translate 32-bit "physical" addresses - * in the linux page tables to 42-bit real addresses in such - * a fashion that we can get at the I/O we need to access. - * -- paulus - */ - cmpwi 0,r6,0 - rlwinm r4,r6,16,16,30 - bge 57f - cmplwi 0,r4,0xfe00 - li r5,0x3fd - bne 56f - li r5,0x3ff -56: sldi r5,r5,32 - or r6,r6,r5 -57: -#endif - -#ifdef CONFIG_PPC64BRIDGE - /* Construct the high word of the PPC-style PTE */ - mfsrin r5,r3 /* get segment reg for segment */ - rlwinm r5,r5,0,5,31 - sldi r5,r5,12 - ori r5,r5,1 /* set V (valid) bit */ - rlwimi r5,r3,16,20,24 /* put in API (abbrev page index) */ - /* Get the address of the primary PTE group in the hash table */ - .globl hash_page_patch_A -hash_page_patch_A: - lis r4,Hash_base@h /* base address of hash table */ - rlwimi r4,r5,32-5,25-Hash_bits,24 /* (VSID & hash_mask) << 7 */ - rlwinm r0,r3,32-5,25-Hash_bits,24 /* (PI & hash_mask) << 7 */ - xor r4,r4,r0 /* make primary hash */ - li r2,8 /* PTEs/group */ - -#ifndef CONFIG_SMP - /* We don't do this for SMP - another cpu could have put in - the appropriate PTE since we took the exception. -- paulus. */ - /* See whether it was a PTE not found exception or a - protection violation. */ - andis. r0,r20,0x4000 - bne 10f /* no PTE: go look for an empty slot */ -#endif /* CONFIG_SMP */ - tlbie r3 /* invalidate TLB entry */ - - /* Search the primary PTEG for a PTE whose 1st dword matches r5 */ - mtctr r2 - addi r3,r4,-16 -1: ldu r0,16(r3) /* get next PTE */ - cmpd 0,r0,r5 - bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ - beq+ found_slot - - /* Search the secondary PTEG for a matching PTE */ - ori r5,r5,0x2 /* set H (secondary hash) bit */ - .globl hash_page_patch_B -hash_page_patch_B: - xoris r3,r4,Hash_msk>>16 /* compute secondary hash */ - xori r3,r3,0xff80 - addi r3,r3,-16 - mtctr r2 -2: ldu r0,16(r3) - cmpd 0,r0,r5 - bdnzf 2,2b - beq+ found_slot - xori r5,r5,0x2 /* clear H bit again */ - - /* Search the primary PTEG for an empty slot */ -10: mtctr r2 - addi r3,r4,-16 /* search primary PTEG */ -1: ldu r0,16(r3) /* get next PTE */ - andi. r0,r0,1 - bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ - beq+ found_empty - - /* Search the secondary PTEG for an empty slot */ - ori r5,r5,0x2 /* set H (secondary hash) bit */ - .globl hash_page_patch_C -hash_page_patch_C: - xoris r3,r4,Hash_msk>>16 /* compute secondary hash */ - xori r3,r3,0xff80 - addi r3,r3,-16 - mtctr r2 -2: ldu r0,16(r3) - andi. r0,r0,1 - bdnzf 2,2b - beq+ found_empty - - /* - * Choose an arbitrary slot in the primary PTEG to overwrite. - * Since both the primary and secondary PTEGs are full, and we - * have no information that the PTEs in the primary PTEG are - * more important or useful than those in the secondary PTEG, - * and we know there is a definite (although small) speed - * advantage to putting the PTE in the primary PTEG, we always - * put the PTE in the primary PTEG. - */ - xori r5,r5,0x2 /* clear H bit again */ - lis r3,next_slot@ha - tophys(r3,r3) - lwz r2,next_slot@l(r3) - addi r2,r2,16 - andi. r2,r2,0x70 -#ifdef CONFIG_POWER4 - /* - * Since we don't have BATs on POWER4, we rely on always having - * PTEs in the hash table to map the hash table and the code - * that manipulates it in virtual mode, namely flush_hash_page and - * flush_hash_segments. Otherwise we can get a DSI inside those - * routines which leads to a deadlock on the hash_table_lock on - * SMP machines. We avoid this by never overwriting the first - * PTE of each PTEG if it is already valid. - * -- paulus. - */ - bne 102f - li r2,0x10 -102: -#endif /* CONFIG_POWER4 */ - stw r2,next_slot@l(r3) - add r3,r4,r2 -11: - /* update counter of evicted pages */ - lis r2,htab_evicts@ha - tophys(r2,r2) - lwz r4,htab_evicts@l(r2) - addi r4,r4,1 - stw r4,htab_evicts@l(r2) - -#ifndef CONFIG_SMP - /* Store PTE in PTEG */ -found_empty: - std r5,0(r3) -found_slot: - std r6,8(r3) - -#else /* CONFIG_SMP */ -/* - * Between the tlbie above and updating the hash table entry below, - * another CPU could read the hash table entry and put it in its TLB. - * There are 3 cases: - * 1. using an empty slot - * 2. updating an earlier entry to change permissions (i.e. enable write) - * 3. taking over the PTE for an unrelated address - * - * In each case it doesn't really matter if the other CPUs have the old - * PTE in their TLB. So we don't need to bother with another tlbie here, - * which is convenient as we've overwritten the register that had the - * address. :-) The tlbie above is mainly to make sure that this CPU comes - * and gets the new PTE from the hash table. - * - * We do however have to make sure that the PTE is never in an invalid - * state with the V bit set. - */ -found_empty: -found_slot: - li r0,1 - andc r5,r5,r0 /* clear V (valid) bit in PTE */ - std r5,0(r3) - sync - tlbsync - sync - std r6,8(r3) /* put in correct RPN, WIMG, PP bits */ - sync - ori r5,r5,1 - std r5,0(r3) /* finally set V bit in PTE */ -#endif /* CONFIG_SMP */ - -#else /* CONFIG_PPC64BRIDGE */ - - /* Construct the high word of the PPC-style PTE */ - mfsrin r5,r3 /* get segment reg for segment */ - rlwinm r5,r5,7,1,24 /* put VSID in 0x7fffff80 bits */ - oris r5,r5,0x8000 /* set V (valid) bit */ - rlwimi r5,r3,10,26,31 /* put in API (abbrev page index) */ - /* Get the address of the primary PTE group in the hash table */ - .globl hash_page_patch_A -hash_page_patch_A: - lis r4,Hash_base@h /* base address of hash table */ - rlwimi r4,r5,32-1,26-Hash_bits,25 /* (VSID & hash_mask) << 6 */ - rlwinm r0,r3,32-6,26-Hash_bits,25 /* (PI & hash_mask) << 6 */ - xor r4,r4,r0 /* make primary hash */ - li r2,8 /* PTEs/group */ - -#ifndef CONFIG_SMP - /* We don't do this for SMP - another cpu could have put in - the appropriate PTE since we took the exception. -- paulus. */ - /* See whether it was a PTE not found exception or a - protection violation. */ - andis. r0,r20,0x4000 - bne 10f /* no PTE: go look for an empty slot */ -#endif /* CONFIG_SMP */ - tlbie r3 /* invalidate TLB entry */ - - /* Search the primary PTEG for a PTE whose 1st word matches r5 */ - mtctr r2 - addi r3,r4,-8 -1: lwzu r0,8(r3) /* get next PTE */ - cmp 0,r0,r5 - bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ - beq+ found_slot - - /* Search the secondary PTEG for a matching PTE */ - ori r5,r5,0x40 /* set H (secondary hash) bit */ - .globl hash_page_patch_B -hash_page_patch_B: - xoris r3,r4,Hash_msk>>16 /* compute secondary hash */ - xori r3,r3,0xffc0 - addi r3,r3,-8 - mtctr r2 -2: lwzu r0,8(r3) - cmp 0,r0,r5 - bdnzf 2,2b - beq+ found_slot - xori r5,r5,0x40 /* clear H bit again */ - - /* Search the primary PTEG for an empty slot */ -10: mtctr r2 - addi r3,r4,-8 /* search primary PTEG */ -1: lwzu r0,8(r3) /* get next PTE */ - rlwinm. r0,r0,0,0,0 /* only want to check valid bit */ - bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ - beq+ found_empty - - /* Search the secondary PTEG for an empty slot */ - ori r5,r5,0x40 /* set H (secondary hash) bit */ - .globl hash_page_patch_C -hash_page_patch_C: - xoris r3,r4,Hash_msk>>16 /* compute secondary hash */ - xori r3,r3,0xffc0 - addi r3,r3,-8 - mtctr r2 -2: - lwzu r0,8(r3) - rlwinm. r0,r0,0,0,0 /* only want to check valid bit */ - bdnzf 2,2b - beq+ found_empty - - /* - * Choose an arbitrary slot in the primary PTEG to overwrite. - * Since both the primary and secondary PTEGs are full, and we - * have no information that the PTEs in the primary PTEG are - * more important or useful than those in the secondary PTEG, - * and we know there is a definite (although small) speed - * advantage to putting the PTE in the primary PTEG, we always - * put the PTE in the primary PTEG. - */ - xori r5,r5,0x40 /* clear H bit again */ - lis r3,next_slot@ha - tophys(r3,r3) - lwz r2,next_slot@l(r3) - addi r2,r2,8 - andi. r2,r2,0x38 - stw r2,next_slot@l(r3) - add r3,r4,r2 -11: - /* update counter of evicted pages */ - lis r2,htab_evicts@ha - tophys(r2,r2) - lwz r4,htab_evicts@l(r2) - addi r4,r4,1 - stw r4,htab_evicts@l(r2) - -#ifndef CONFIG_SMP - /* Store PTE in PTEG */ -found_empty: - stw r5,0(r3) -found_slot: - stw r6,4(r3) - -#else /* CONFIG_SMP */ -/* - * Between the tlbie above and updating the hash table entry below, - * another CPU could read the hash table entry and put it in its TLB. - * There are 3 cases: - * 1. using an empty slot - * 2. updating an earlier entry to change permissions (i.e. enable write) - * 3. taking over the PTE for an unrelated address - * - * In each case it doesn't really matter if the other CPUs have the old - * PTE in their TLB. So we don't need to bother with another tlbie here, - * which is convenient as we've overwritten the register that had the - * address. :-) The tlbie above is mainly to make sure that this CPU comes - * and gets the new PTE from the hash table. - * - * We do however have to make sure that the PTE is never in an invalid - * state with the V bit set. - */ -found_empty: -found_slot: - rlwinm r5,r5,0,1,31 /* clear V (valid) bit in PTE */ - stw r5,0(r3) - sync - tlbsync - sync - stw r6,4(r3) /* put in correct RPN, WIMG, PP bits */ - sync - oris r5,r5,0x8000 - stw r5,0(r3) /* finally set V bit in PTE */ -#endif /* CONFIG_SMP */ -#endif /* CONFIG_PPC64BRIDGE */ - - sync /* make sure pte updates get to memory */ - -/* - * Update the hash table miss count. We only want misses here - * that _are_ valid addresses and have a pte otherwise we don't - * count it as a reload. do_page_fault() takes care of bad addrs - * and entries that need linux-style pte's created. - * - * safe to use r2 here since we're not using it as current yet - * update the htab misses count - * -- Cort - */ - lis r2,htab_reloads@ha - tophys(r2,r2) - lwz r3,htab_reloads@l(r2) - addi r3,r3,1 - stw r3,htab_reloads@l(r2) - -#ifdef CONFIG_SMP - lis r2,hash_table_lock@ha - tophys(r2,r2) - li r0,0 - stw r0,hash_table_lock@l(r2) - eieio -#endif - - /* Return from the exception */ - lwz r3,_CCR(r21) - lwz r4,_LINK(r21) - lwz r5,_CTR(r21) - mtcrf 0xff,r3 - mtlr r4 - mtctr r5 - lwz r0,GPR0(r21) - lwz r1,GPR1(r21) - lwz r2,GPR2(r21) - lwz r3,GPR3(r21) - lwz r4,GPR4(r21) - lwz r5,GPR5(r21) - lwz r6,GPR6(r21) - /* we haven't used xer */ - mtspr SRR1,r23 - mtspr SRR0,r22 - lwz r20,GPR20(r21) - lwz r22,GPR22(r21) - lwz r23,GPR23(r21) - lwz r21,GPR21(r21) - RFI - -#ifdef CONFIG_SMP -hash_page_out: - lis r2,hash_table_lock@ha - tophys(r2,r2) - li r0,0 - stw r0,hash_table_lock@l(r2) - eieio - blr - - .data - .globl hash_table_lock -hash_table_lock: - .long 0 -#endif /* CONFIG_SMP */ - - .data -next_slot: - .long 0 - - .text -/* - * Flush entries from the hash table with VSIDs in the range - * given. - */ -_GLOBAL(flush_hash_segments) - lis r5,Hash@ha - lwz r5,Hash@l(r5) /* base of hash table */ - cmpwi 0,r5,0 - bne+ 99f - tlbia - sync -#ifdef CONFIG_SMP - tlbsync - sync -#endif - blr -99: -#if defined(CONFIG_SMP) || defined(CONFIG_PPC64BRIDGE) - /* Note - we had better not do anything which could generate - a hash table miss while we have the hash table locked, - or we'll get a deadlock. -paulus */ - mfmsr r10 - SYNC - rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ - mtmsr r0 - SYNC -#endif -#ifdef CONFIG_SMP - lis r9,hash_table_lock@h - ori r9,r9,hash_table_lock@l - lwz r8,PROCESSOR(r2) - oris r8,r8,8 -10: lwarx r6,0,r9 - cmpi 0,r6,0 - bne- 10b - stwcx. r8,0,r9 - bne- 10b - eieio -#endif -#ifndef CONFIG_PPC64BRIDGE - rlwinm r3,r3,7,1,24 /* put VSID lower limit in position */ - oris r3,r3,0x8000 /* set V bit */ - rlwinm r4,r4,7,1,24 /* put VSID upper limit in position */ - oris r4,r4,0x8000 - ori r4,r4,0x7f - lis r6,Hash_size@ha - lwz r6,Hash_size@l(r6) /* size in bytes */ - srwi r6,r6,3 /* # PTEs */ - mtctr r6 - addi r5,r5,-8 - li r0,0 -1: lwzu r6,8(r5) /* get next tag word */ - cmplw 0,r6,r3 - cmplw 1,r6,r4 - cror 0,0,5 /* set cr0.lt if out of range */ - blt 2f /* branch if out of range */ - stw r0,0(r5) /* invalidate entry */ -2: bdnz 1b /* continue with loop */ -#else /* CONFIG_PPC64BRIDGE */ - rldic r3,r3,12,20 /* put VSID lower limit in position */ - ori r3,r3,1 /* set V bit */ - rldic r4,r4,12,20 /* put VSID upper limit in position */ - ori r4,r4,0xfff /* set V bit, API etc. */ - lis r6,Hash_size@ha - lwz r6,Hash_size@l(r6) /* size in bytes */ - srwi r6,r6,4 /* # PTEs */ - mtctr r6 - addi r5,r5,-16 - li r0,0 -1: ldu r6,16(r5) /* get next tag word */ - cmpld 0,r6,r3 - cmpld 1,r6,r4 - cror 0,0,5 /* set cr0.lt if out of range */ - blt 2f /* branch if out of range */ - std r0,0(r5) /* invalidate entry */ -2: bdnz 1b /* continue with loop */ -#endif /* CONFIG_PPC64BRIDGE */ - - sync - tlbia - sync -#ifdef CONFIG_SMP - tlbsync - sync - lis r3,hash_table_lock@ha - stw r0,hash_table_lock@l(r3) -#endif -#if defined(CONFIG_SMP) || defined(CONFIG_PPC64BRIDGE) - mtmsr r10 - SYNC -#endif - blr - -/* - * Flush the entry for a particular page from the hash table. - * - * flush_hash_page(unsigned context, unsigned long va) - */ -_GLOBAL(flush_hash_page) - lis r6,Hash@ha - lwz r6,Hash@l(r6) /* hash table base */ - cmpwi 0,r6,0 /* hash table in use? */ - bne+ 99f - tlbie r4 /* in hw tlb too */ - sync -#ifdef CONFIG_SMP - tlbsync - sync -#endif - blr -99: -#if defined(CONFIG_SMP) || defined(CONFIG_PPC64BRIDGE) - /* Note - we had better not do anything which could generate - a hash table miss while we have the hash table locked, - or we'll get a deadlock. -paulus */ - mfmsr r10 - SYNC - rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ - mtmsr r0 - SYNC -#endif -#ifdef CONFIG_SMP - lis r9,hash_table_lock@h - ori r9,r9,hash_table_lock@l - lwz r8,PROCESSOR(r2) - oris r8,r8,9 -10: lwarx r7,0,r9 - cmpi 0,r7,0 - bne- 11f - stwcx. r8,0,r9 - beq+ 12f -11: lwz r7,0(r9) - cmpi 0,r7,0 - beq 10b - b 11b -12: eieio -#endif -#ifndef CONFIG_PPC64BRIDGE - rlwinm r3,r3,11,1,20 /* put context into vsid */ - rlwimi r3,r4,11,21,24 /* put top 4 bits of va into vsid */ - oris r3,r3,0x8000 /* set V (valid) bit */ - rlwimi r3,r4,10,26,31 /* put in API (abbrev page index) */ - rlwinm r7,r4,32-6,10,25 /* get page index << 6 */ - rlwinm r5,r3,32-1,7,25 /* vsid << 6 */ - xor r7,r7,r5 /* primary hash << 6 */ - lis r5,Hash_mask@ha - lwz r5,Hash_mask@l(r5) /* hash mask */ - slwi r5,r5,6 /* << 6 */ - and r7,r7,r5 - add r6,r6,r7 /* address of primary PTEG */ - li r8,8 - mtctr r8 - addi r7,r6,-8 -1: lwzu r0,8(r7) /* get next PTE */ - cmpw 0,r0,r3 /* see if tag matches */ - bdnzf 2,1b /* while --ctr != 0 && !cr0.eq */ - beq 3f /* if we found it */ - ori r3,r3,0x40 /* set H (alt. hash) bit */ - xor r6,r6,r5 /* address of secondary PTEG */ - mtctr r8 - addi r7,r6,-8 -2: lwzu r0,8(r7) /* get next PTE */ - cmpw 0,r0,r3 /* see if tag matches */ - bdnzf 2,2b /* while --ctr != 0 && !cr0.eq */ - bne 4f /* if we didn't find it */ -3: li r0,0 - stw r0,0(r7) /* invalidate entry */ -#else /* CONFIG_PPC64BRIDGE */ - rldic r3,r3,16,16 /* put context into vsid (<< 12) */ - rlwimi r3,r4,16,16,24 /* top 4 bits of va and API */ - ori r3,r3,1 /* set V (valid) bit */ - rlwinm r7,r4,32-5,9,24 /* get page index << 7 */ - srdi r5,r3,5 /* vsid << 7 */ - rlwinm r5,r5,0,1,24 /* vsid << 7 (limited to 24 bits) */ - xor r7,r7,r5 /* primary hash << 7 */ - lis r5,Hash_mask@ha - lwz r5,Hash_mask@l(r5) /* hash mask */ - slwi r5,r5,7 /* << 7 */ - and r7,r7,r5 - add r6,r6,r7 /* address of primary PTEG */ - li r8,8 - mtctr r8 - addi r7,r6,-16 -1: ldu r0,16(r7) /* get next PTE */ - cmpd 0,r0,r3 /* see if tag matches */ - bdnzf 2,1b /* while --ctr != 0 && !cr0.eq */ - beq 3f /* if we found it */ - ori r3,r3,2 /* set H (alt. hash) bit */ - xor r6,r6,r5 /* address of secondary PTEG */ - mtctr r8 - addi r7,r6,-16 -2: ldu r0,16(r7) /* get next PTE */ - cmpd 0,r0,r3 /* see if tag matches */ - bdnzf 2,2b /* while --ctr != 0 && !cr0.eq */ - bne 4f /* if we didn't find it */ -3: li r0,0 - std r0,0(r7) /* invalidate entry */ -#endif /* CONFIG_PPC64BRIDGE */ -4: sync - tlbie r4 /* in hw tlb too */ - sync -#ifdef CONFIG_SMP - tlbsync - sync - li r0,0 - stw r0,0(r9) /* clear hash_table_lock */ -#endif -#if defined(CONFIG_SMP) || defined(CONFIG_PPC64BRIDGE) - mtmsr r10 - SYNC -#endif - blr diff -Nru a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S --- a/arch/ppc/kernel/head.S Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/kernel/head.S Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.head.S 1.21 05/23/01 00:38:42 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * PowerPC version @@ -25,11 +25,14 @@ * */ +#include +#include #include "ppc_asm.h" #include #include -#include #include +#include +#include #ifdef CONFIG_APUS #include @@ -150,6 +153,12 @@ bl fix_mem_constants #endif /* CONFIG_APUS */ + mr r26,r3 + bl reloc_offset + bl identify_cpu + bl do_cpu_ftr_fixups + mr r3,r26 + #ifndef CONFIG_GEMINI /* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains * the physical address we are running at, returned by prom_init() @@ -177,7 +186,7 @@ mtspr SDR1,r4 slbia lis r5,0x2000 /* set pseudo-segment reg 12 */ - ori r5,r5,12 + ori r5,r5,0x0ccc mtsr 12,r5 #endif /* CONFIG_POWER4 */ @@ -312,9 +321,8 @@ mfspr r20,DSISR andis. r0,r20,0xa470 /* weird error? */ bne 1f /* if not, try to put a PTE */ - mfspr r3,DAR /* into the hash table */ - rlwinm r4,r23,32-13,30,30 /* MSR_PR -> _PAGE_USER */ - rlwimi r4,r20,32-23,29,29 /* DSISR_STORE -> _PAGE_RW */ + mfspr r4,DAR /* into the hash table */ + rlwinm r3,r20,32-15,21,21 /* DSISR_STORE -> _PAGE_RW */ bl hash_page 1: stw r20,_DSISR(r21) mr r5,r20 @@ -354,9 +362,8 @@ #endif /* CONFIG_PPC64BRIDGE */ andis. r0,r23,0x4000 /* no pte found? */ beq 1f /* if so, try to put a PTE */ - mr r3,r22 /* into the hash table */ - rlwinm r4,r23,32-13,30,30 /* MSR_PR -> _PAGE_USER */ - mr r20,r23 /* SRR1 has reason bits */ + li r3,0 /* into the hash table */ + mr r4,r22 /* SRR0 is fault address */ bl hash_page 1: addi r3,r1,STACK_FRAME_OVERHEAD mr r4,r22 @@ -505,10 +512,13 @@ lis r1,KERNELBASE@h /* check if kernel address */ cmplw 0,r3,r1 mfspr r2,SPRG3 + li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */ lwz r2,PGDIR(r2) blt+ 112f lis r2,swapper_pg_dir@ha /* if kernel address, use */ addi r2,r2,swapper_pg_dir@l /* kernel page table */ + mfspr r1,SRR1 /* and MSR_PR bit from SRR1 */ + rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */ 112: tophys(r2,r2) rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ lwz r2,0(r2) /* get pmd entry */ @@ -516,21 +526,23 @@ beq- InstructionAddressInvalid /* return if no mapping */ tophys(r2,r2) rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ - lwz r1,0(r2) /* get linux-style pte */ - /* setup access flags in r3 */ - mfmsr r3 - rlwinm r3,r3,32-13,30,30 /* MSR_PR -> _PAGE_USER */ - ori r3,r3,1 /* set _PAGE_PRESENT bit in access */ - andc. r3,r3,r1 /* check access & ~permission */ + lwz r3,0(r2) /* get linux-style pte */ + andc. r1,r1,r3 /* check access & ~permission */ bne- InstructionAddressInvalid /* return if access not permitted */ - ori r1,r1,0x100 /* set _PAGE_ACCESSED in pte */ - stw r1,0(r2) /* update PTE (accessed bit) */ + ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */ + /* + * NOTE! We are assuming this is not an SMP system, otherwise + * we would need to update the pte atomically with lwarx/stwcx. + */ + stw r3,0(r2) /* update PTE (accessed bit) */ /* Convert linux-style PTE to low word of PPC-style PTE */ - /* this computation could be done better -- Cort */ - rlwinm r3,r1,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */ - rlwimi r1,r1,32-1,31,31 /* _PAGE_USER -> PP (both bits now) */ - ori r3,r3,0xe04 /* clear out reserved bits */ - andc r1,r1,r3 /* PP=2 or 0, when _PAGE_HWWRITE */ + rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */ + rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */ + and r1,r1,r2 /* writable if _RW and _DIRTY */ + rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ + rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ + ori r1,r1,0xe14 /* clear out reserved bits and M */ + andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ mtspr RPA,r1 mfspr r3,IMISS tlbli r3 @@ -576,10 +588,13 @@ lis r1,KERNELBASE@h /* check if kernel address */ cmplw 0,r3,r1 mfspr r2,SPRG3 + li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */ lwz r2,PGDIR(r2) blt+ 112f lis r2,swapper_pg_dir@ha /* if kernel address, use */ addi r2,r2,swapper_pg_dir@l /* kernel page table */ + mfspr r1,SRR1 /* and MSR_PR bit from SRR1 */ + rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */ 112: tophys(r2,r2) rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ lwz r2,0(r2) /* get pmd entry */ @@ -587,22 +602,23 @@ beq- DataAddressInvalid /* return if no mapping */ tophys(r2,r2) rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ - lwz r1,0(r2) /* get linux-style pte */ - /* setup access flags in r3 */ - mfmsr r3 - rlwinm r3,r3,32-13,30,30 /* MSR_PR -> _PAGE_USER */ - ori r3,r3,1 /* set _PAGE_PRESENT bit in access */ - /* save r2 and use it as scratch for the andc. */ - andc. r3,r3,r1 /* check access & ~permission */ + lwz r3,0(r2) /* get linux-style pte */ + andc. r1,r1,r3 /* check access & ~permission */ bne- DataAddressInvalid /* return if access not permitted */ - ori r1,r1,0x100 /* set _PAGE_ACCESSED in pte */ - stw r1,0(r2) /* update PTE (accessed bit) */ + ori r3,r3,_PAGE_ACCESSED /* set _PAGE_ACCESSED in pte */ + /* + * NOTE! We are assuming this is not an SMP system, otherwise + * we would need to update the pte atomically with lwarx/stwcx. + */ + stw r3,0(r2) /* update PTE (accessed bit) */ /* Convert linux-style PTE to low word of PPC-style PTE */ - /* this computation could be done better -- Cort */ - rlwinm r3,r1,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */ - rlwimi r1,r1,32-1,31,31 /* _PAGE_USER -> PP (both bits now) */ - ori r3,r3,0xe04 /* clear out reserved bits */ - andc r1,r1,r3 /* PP=2 or 0, when _PAGE_HWWRITE */ + rlwinm r1,r3,32-10,31,31 /* _PAGE_RW -> PP lsb */ + rlwinm r2,r3,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */ + and r1,r1,r2 /* writable if _RW and _DIRTY */ + rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ + rlwimi r3,r3,32-1,31,31 /* _PAGE_USER -> PP lsb */ + ori r1,r1,0xe14 /* clear out reserved bits and M */ + andc r1,r3,r1 /* PP = user? (rw&dirty? 2: 3): 0 */ mtspr RPA,r1 mfspr r3,DMISS tlbld r3 @@ -646,10 +662,13 @@ lis r1,KERNELBASE@h /* check if kernel address */ cmplw 0,r3,r1 mfspr r2,SPRG3 + li r1,_PAGE_RW|_PAGE_USER|_PAGE_PRESENT /* access flags */ lwz r2,PGDIR(r2) blt+ 112f lis r2,swapper_pg_dir@ha /* if kernel address, use */ addi r2,r2,swapper_pg_dir@l /* kernel page table */ + mfspr r1,SRR1 /* and MSR_PR bit from SRR1 */ + rlwinm r1,r1,32-12,29,29 /* shift MSR_PR to _PAGE_USER posn */ 112: tophys(r2,r2) rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ lwz r2,0(r2) /* get pmd entry */ @@ -657,22 +676,19 @@ beq- DataAddressInvalid /* return if no mapping */ tophys(r2,r2) rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ - lwz r1,0(r2) /* get linux-style pte */ - /* setup access flags in r3 */ - mfmsr r3 - rlwinm r3,r3,32-13,30,30 /* MSR_PR -> _PAGE_USER */ - ori r3,r3,0x5 /* _PAGE_PRESENT|_PAGE_RW */ - /* save r2 and use it as scratch for the andc. */ - andc. r3,r3,r1 /* check access & ~permission */ + lwz r3,0(r2) /* get linux-style pte */ + andc. r1,r1,r3 /* check access & ~permission */ bne- DataAddressInvalid /* return if access not permitted */ - ori r1,r1,0x384 /* set _PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_RW|_PAGE_HWWRITE in pte */ - stw r1,0(r2) /* update PTE (accessed bit) */ + ori r3,r3,_PAGE_ACCESSED|_PAGE_DIRTY + /* + * NOTE! We are assuming this is not an SMP system, otherwise + * we would need to update the pte atomically with lwarx/stwcx. + */ + stw r3,0(r2) /* update PTE (accessed/dirty bits) */ /* Convert linux-style PTE to low word of PPC-style PTE */ - /* this computation could be done better -- Cort */ - rlwinm r3,r1,32-9,31,31 /* _PAGE_HWWRITE -> PP lsb */ - rlwimi r1,r1,32-1,31,31 /* _PAGE_USER -> PP (both bits now) */ - ori r3,r3,0xe04 /* clear out reserved bits */ - andc r1,r1,r3 /* PP=2 or 0, when _PAGE_HWWRITE */ + rlwimi r3,r3,32-1,30,30 /* _PAGE_USER -> PP msb */ + li r1,0xe15 /* clear out reserved bits and M */ + andc r1,r3,r1 /* PP = user? 2: 0 */ mtspr RPA,r1 mfspr r3,DMISS tlbld r3 @@ -755,12 +771,10 @@ 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 */ +BEGIN_FTR_SECTION + mfspr r22,SPRN_VRSAVE /* if G4, save vrsave register value */ stw r22,THREAD_VRSAVE(r23) +END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) #endif /* CONFIG_ALTIVEC */ 2: addi r2,r23,-THREAD /* set r2 to current */ tovirt(r2,r2) @@ -988,7 +1002,15 @@ .globl giveup_altivec giveup_altivec: - mfmsr r5 + mfpvr r24 /* check if we are on a G4 */ + srwi r24,r24,16 + cmpwi r24,PVR_7400@h + beq 3f /* continue */ + mflr r24 + bl msr_vec_debug /* debug thingy in process.c */ + mtlr r24 + blr +3: mfmsr r5 oris r5,r5,MSR_VEC@h SYNC mtmsr r5 /* enable use of AltiVec now */ @@ -1274,10 +1296,25 @@ SYNC MTMSRD(r0) isync -#else - bl enable_caches #endif + lis r3,-KERNELBASE@h + bl identify_cpu + + /* Call setup_cpu for this CPU */ + mr r3,r24 + lis r5,cur_cpu_spec@ha + addi r5,r5,cur_cpu_spec@l + tophys(r5,r5) + slwi r4,r24,2 + add r5,r5,r4 + lwz r5,0(r5) + tophys(r5,r5) + lwz r6,CPU_SPEC_SETUP(r5) + tophys(r6,r6) + mtctr r6 + bctrl + /* get current */ lis r2,current_set@h ori r2,r2,current_set@l @@ -1315,54 +1352,87 @@ /* * Enable caches and 604-specific features if necessary. */ -enable_caches: - mfspr r9,PVR - rlwinm r9,r9,16,16,31 - cmpi 0,r9,1 - beq 6f /* not needed for 601 */ +_GLOBAL(__setup_cpu_601) + blr +_GLOBAL(__setup_cpu_603) + b setup_common_caches +_GLOBAL(__setup_cpu_604) + mflr r4 + bl setup_common_caches + bl setup_604_hid0 + mtlr r4 + blr +_GLOBAL(__setup_cpu_750) + mflr r4 + bl setup_common_caches + bl setup_750_7400_hid0 + mtlr r4 + blr +_GLOBAL(__setup_cpu_7400) + mflr r4 + bl setup_common_caches + bl setup_750_7400_hid0 + mtlr r4 + blr +_GLOBAL(__setup_cpu_7450) + blr +_GLOBAL(__setup_cpu_power3) + blr +_GLOBAL(__setup_cpu_power4) + blr +_GLOBAL(__setup_cpu_generic) + blr + +/* Enable caches for 603's, 604, 750 & 7400 */ +setup_common_caches: mfspr r11,HID0 andi. r0,r11,HID0_DCE ori r11,r11,HID0_ICE|HID0_DCE ori r8,r11,HID0_ICFI - bne 3f /* don't invalidate the D-cache */ + bne 1f /* don't invalidate the D-cache */ ori r8,r8,HID0_DCI /* unless it wasn't enabled */ -3: - sync +1: sync mtspr HID0,r8 /* enable and invalidate caches */ sync mtspr HID0,r11 /* enable caches */ sync isync - cmpi 0,r9,4 /* check for 604 */ - cmpi 1,r9,9 /* or 604e */ - 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|r], enable */ - bne 2,5f - ori r11,r11,HID0_BTCD /* superscalar exec & br history tbl */ - b 5f -4: - cror 14,14,18 - bne 3,6f - /* for G3/G4: - * enable Store Gathering (SGE), Address Brodcast (ABE), - * Branch History Table (BHTE), Branch Target ICache (BTIC) - */ + blr + +/* 604, 604e, 604ev, ... + * Enable superscalar execution & branch history table + */ +setup_604_hid0: + mfspr r11,HID0 + ori r11,r11,HID0_SIED|HID0_BHTE + ori r8,r11,HID0_BTCD + sync + mtspr HID0,r8 /* flush branch target address cache */ + sync /* on 604e/604r */ + mtspr HID0,r11 + sync + isync + blr + +/* 740/750/7400/7410 + * Enable Store Gathering (SGE), Address Brodcast (ABE), + * Branch History Table (BHTE), Branch Target ICache (BTIC) + * Dynamic Power Management (DPM), Speculative (SPD) + * Clear Instruction cache throttling (ICTC) + */ +setup_750_7400_hid0: + mfspr r11,HID0 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 /* Instruction Cache Throttling off */ -5: isync + isync mtspr HID0,r11 sync isync -6: blr + blr /* * Load stuff into the MMU. Intended to be called with @@ -1384,7 +1454,7 @@ lis r3,0x2000 /* Ku = 1, VSID = 0 */ li r4,0 3: mtsrin r3,r4 - addi r3,r3,1 /* increment VSID */ + addi r3,r3,0x111 /* increment VSID */ addis r4,r4,0x1000 /* address of next segment */ bdnz 3b #ifndef CONFIG_POWER4 @@ -1407,9 +1477,14 @@ * This is where the main kernel code starts. */ start_here: -#ifndef CONFIG_PPC64BRIDGE - bl enable_caches -#endif + /* Call setup_cpu for CPU 0 */ + li r3,0 /* cpu# */ + lis r5,cur_cpu_spec@ha + addi r5,r5,cur_cpu_spec@l + lwz r5,0(r5) + lwz r5,CPU_SPEC_SETUP(r5) + mtctr r5 + bctrl /* ptr to current */ lis r2,init_task_union@h @@ -1490,7 +1565,8 @@ * Set up the segment registers for a new context. */ _GLOBAL(set_context) - rlwinm r3,r3,4,8,27 /* VSID = context << 4 */ + mulli r3,r3,897 /* multiply context by skew factor */ + rlwinm r3,r3,4,8,27 /* VSID = (context & 0xfffff) << 4 */ addis r3,r3,0x6000 /* Set Ks, Ku bits */ li r0,12 /* TASK_SIZE / SEGMENT_SIZE */ mtctr r0 @@ -1500,7 +1576,8 @@ slbie r4 #endif /* CONFIG_PPC64BRIDGE */ mtsrin r3,r4 - addi r3,r3,1 /* next VSID */ + addi r3,r3,0x111 /* next VSID */ + rlwinm r3,r3,0,8,3 /* clear out any overflow from VSID field */ addis r4,r4,0x1000 /* address of next segment */ bdnz 3b SYNC @@ -1562,6 +1639,75 @@ sync RFI #endif + +/* identify_cpu, + * called with r3 = data offset and r24 = CPU number + */ +identify_cpu: + addis r8,r3,cpu_specs@ha + addi r8,r8,cpu_specs@l + mfpvr r7 +1: + lwz r5,CPU_SPEC_PVR_MASK(r8) + and r5,r5,r7 + lwz r6,CPU_SPEC_PVR_VALUE(r8) + cmplw 0,r6,r5 + beq 1f + addi r8,r8,CPU_SPEC_ENTRY_SIZE + b 1b +1: + addis r6,r3,cur_cpu_spec@ha + addi r6,r6,cur_cpu_spec@l + slwi r4,r24,2 + add r6,r6,r4 + sub r8,r8,r3 + stw r8,0(r6) + blr + +do_cpu_ftr_fixups: + /* Get CPU 0 features */ + addis r6,r3,cur_cpu_spec@ha + addi r6,r6,cur_cpu_spec@l + lwz r4,0(r6) + add r4,r4,r3 + lwz r4,CPU_SPEC_FEATURES(r4) + + /* Get the fixup table */ + addis r6,r3,__start___ftr_fixup@ha + addi r6,r6,__start___ftr_fixup@l + addis r7,r3,__stop___ftr_fixup@ha + addi r7,r7,__stop___ftr_fixup@l + + /* Do the fixup */ +1: cmplw 0,r6,r7 + bgelr + addi r6,r6,16 + lwz r8,-16(r6) /* mask */ + and r8,r8,r4 + lwz r9,-12(r6) /* value */ + cmplw 0,r8,r9 + beq 1b + lwz r8,-8(r6) /* section begin */ + lwz r9,-4(r6) /* section end */ + subf. r9,r8,r9 + beq 1b + /* write nops over the section of code */ + /* todo: if large section, add a branch at the start of it */ + srwi r9,r9,2 + mtctr r9 + add r8,r8,r3 + lis r0,0x60000000@h /* nop */ +3: stw r0,0(r8) + andi. r10,r4,CPU_FTR_SPLIT_ID_CACHE@l + beq 2f + dcbst 0,r8 /* suboptimal, but simpler */ + sync + icbi 0,r8 +2: addi r8,r8,4 + bdnz 3b + sync /* additional sync needed on g4 */ + isync + b 1b #ifndef CONFIG_POWER4 /* diff -Nru a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S --- a/arch/ppc/kernel/head_4xx.S Sat Jun 16 06:00:26 2001 +++ b/arch/ppc/kernel/head_4xx.S Sat Jun 16 06:00:26 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.head_4xx.S 1.6 05/21/01 11:50:00 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (c) 1995-1996 Gary Thomas diff -Nru a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S --- a/arch/ppc/kernel/head_8xx.S Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/kernel/head_8xx.S Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.head_8xx.S 1.11 05/21/01 11:50:00 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/except_8xx.S @@ -500,6 +500,11 @@ #endif mtspr MD_TWC, r21 + /* Set PP0 to PP1 (== _PAGE_USER) & ~_PAGE_RW */ + rlwimi r20, r20, 32-1, 21, 21 + rlwinm r21, r20, 4, 21, 21 + andc r20, r20, r21 + /* Set four subpage valid bits (24, 25, 26, and 27). * Clear bit 28 (which should be in the PTE, but we do this anyway). */ @@ -508,6 +513,7 @@ #else li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 + #endif #ifdef CONFIG_8xx_CPU6 li r3, 0x3d80 @@ -602,7 +608,7 @@ /* Update 'changed', among others. */ - ori r20, r20, _PAGE_DIRTY|_PAGE_HWWRITE|_PAGE_ACCESSED + ori r20, r20, _PAGE_DIRTY|_PAGE_ACCESSED mfspr r21, MD_TWC /* Get pte address again */ stw r20, 0(r21) /* and update pte in table */ @@ -939,6 +945,12 @@ * ASID compare register with the new "context". */ _GLOBAL(set_context) + /* fetch the pgd from the context_mm array */ + lis r5, context_mm@ha + slwi r6, r3, 2 + add r5, r5, r6 + lwz r5, context_mm@l(r5) /* get the mm */ + lwz r4, MM_PGD(r5) /* get the pgd from the mm */ #ifdef CONFIG_8xx_CPU6 lis r6, cpu6_errata_word@h ori r6, r6, cpu6_errata_word@l diff -Nru a/arch/ppc/kernel/i8259.c b/arch/ppc/kernel/i8259.c --- a/arch/ppc/kernel/i8259.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/kernel/i8259.c Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.i8259.c 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #include diff -Nru a/arch/ppc/kernel/i8259.h b/arch/ppc/kernel/i8259.h --- a/arch/ppc/kernel/i8259.h Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/kernel/i8259.h Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.i8259.h 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef _PPC_KERNEL_i8259_H diff -Nru a/arch/ppc/kernel/iSeries_dma.c b/arch/ppc/kernel/iSeries_dma.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/iSeries_dma.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,1037 @@ +/* + * iSeries_dma.c + * Copyright (C) 2001 Mike Corrigan IBM Corporation + * + * Dynamic DMA mapping support. + * + * Manages the TCE space assigned to this partition + * + * modeled from pci-dma.c + * + * 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 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct TceTable virtBusTceTable; /* Tce table for virtual bus */ + +struct TceTable * tceTables[256]; // Tce tables for 256 busses + // Bus 255 is the virtual bus + // zero indicates no bus defined + // allocates a contiguous range of tces (power-of-2 size) +static long alloc_tce_range( struct TceTable *, + unsigned order ); + // allocates a contiguous range of tces (power-of-2 size) + // assumes lock already held +static long alloc_tce_range_nolock( struct TceTable *, + unsigned order ); + // frees a contiguous range of tces (power-of-2 size) +static void free_tce_range( struct TceTable *, + long tcenum, + unsigned order ); + // frees a contiguous rnage of tces (power-of-2 size) + // assumes lock already held +static void free_tce_range_nolock( struct TceTable *, + long tcenum, + unsigned order ); + // allocates a range of tces and sets them to the + // pages +static dma_addr_t get_tces( struct TceTable *, + unsigned order, + void *page, + unsigned numPages, + int tceType, + int direction ); +static void free_tces( struct TceTable *, + dma_addr_t tce, + unsigned order, + unsigned numPages ); +static long test_tce_range( struct TceTable *, + long tcenum, + unsigned order ); + +static unsigned fill_scatterlist_sg( struct scatterlist *sg, int nents, + dma_addr_t dma_addr, unsigned long numTces ); + +static unsigned long num_tces_sg( struct scatterlist *sg, + int nents ); + +static dma_addr_t create_tces_sg( struct TceTable *tbl, + struct scatterlist *sg, + int nents, + unsigned numTces, + int tceType, + int direction ); + +static unsigned __inline__ count_leading_zeros32( unsigned long x ) +{ + unsigned lz; + asm("cntlzw %0,%1" : "=r"(lz) : "r"(x)); + return lz; +} + +static void __inline__ build_tce( struct TceTable * tbl, long tcenum, + unsigned long uaddr, int tceType, int direction ) +{ + union Tce tce; + + tce.wholeTce = 0; + tce.tceBits.rpn = (virt_to_absolute(uaddr)) >> PAGE_SHIFT; + // If for virtual bus + if ( tceType == TCE_VB ) { + tce.tceBits.valid = 1; + tce.tceBits.allIo = 1; + if ( direction != PCI_DMA_TODEVICE ) + tce.tceBits.readWrite = 1; + } + // If for PCI bus + else { + tce.tceBits.readWrite = 1; // Read allowed + if ( direction != PCI_DMA_TODEVICE ) + tce.tceBits.pciWrite = 1; + } + HvCallXm_setTce( (u64)tbl->index, (u64)tcenum, tce.wholeTce ); + +} + + + +// Build a TceTable structure. This contains a multi-level bit map which +// is used to manage allocation of the tce space. + +struct TceTable * build_tce_table( struct HvTceTableManagerCB * tceTableParms, + struct TceTable * tbl ) +{ + unsigned long bits, bytes, totalBytes; + unsigned long numBits[NUM_TCE_LEVELS], numBytes[NUM_TCE_LEVELS]; + unsigned i, k, m; + unsigned char * pos, * p, b; + + tbl->size = tceTableParms->size; + tbl->busNumber = tceTableParms->busNumber; + tbl->startOffset = tceTableParms->startOffset; + tbl->index = tceTableParms->index; + spin_lock_init( &(tbl->lock) ); + + tbl->mlbm.maxLevel = 0; + + // Compute number of bits and bytes for each level of the + // multi-level bit map + // + totalBytes = 0; + bits = tbl->size * (PAGE_SIZE / sizeof( union Tce )); + + for ( i=0; imlbm.level[i].map = pos; + tbl->mlbm.maxLevel = i; + + if ( numBits[i] & 1 ) { + p = pos + numBytes[i] - 1; + m = (( numBits[i] % 8) - 1) & 7; + *p = 0x80 >> m; +#ifdef DEBUG_TCE + printk("build_tce_table: level %d last bit %x\n", i, 0x80>>m ); +#endif + } + } + else + tbl->mlbm.level[i].map = 0; + pos += numBytes[i]; + tbl->mlbm.level[i].numBits = numBits[i]; + tbl->mlbm.level[i].numBytes = numBytes[i]; + + } + + // For the highest level, turn on all the bits + + i = tbl->mlbm.maxLevel; + p = tbl->mlbm.level[i].map; + m = numBits[i]; +#ifdef DEBUG_TCE + printk("build_tce_table: highest level (%d) has all bits set\n", i); +#endif + for (k=0; k= 8 ) { + // handle full bytes + *p++ = 0xff; + m -= 8; + } + else { + // handle the last partial byte + b = 0x80; + *p = 0; + while (m) { + *p |= b; + b >>= 1; + --m; + } + } + } + + return tbl; + +} + +static long alloc_tce_range( struct TceTable *tbl, unsigned order ) +{ + long retval; + unsigned long flags; + + // Lock the tce allocation bitmap + spin_lock_irqsave( &(tbl->lock), flags ); + + // Do the actual work + retval = alloc_tce_range_nolock( tbl, order ); + + // Unlock the tce allocation bitmap + spin_unlock_irqrestore( &(tbl->lock), flags ); + + return retval; +} + +static long alloc_tce_range_nolock( struct TceTable *tbl, unsigned order ) +{ + unsigned long numBits, numBytes; + unsigned long i, bit, block, mask; + long tcenum; + unsigned char * map; + + // If the order (power of 2 size) requested is larger than our + // biggest, indicate failure + if ( order > tbl->mlbm.maxLevel ) { +#ifdef DEBUG_TCE + printk("alloc_tce_range_nolock: invalid order requested, order = %d\n", order ); +#endif + return -1; + } + + numBits = tbl->mlbm.level[order].numBits; + numBytes = tbl->mlbm.level[order].numBytes; + map = tbl->mlbm.level[order].map; + + // Initialize return value to -1 (failure) + tcenum = -1; + + // Loop through the bytes of the bitmap + for (i=0; i> bit); + *map &= mask; + // compute the index into our tce table for + // the first tce in the block +#ifdef DEBUG_TCE + printk("alloc_tce_range_nolock: allocating block %ld, (byte=%ld, bit=%ld) order %d\n", block, i, bit, order ); +#endif + tcenum = block << order; + break; + } + ++map; + } + +#ifdef DEBUG_TCE + if ( tcenum == -1 ) { + printk("alloc_tce_range_nolock: no available blocks of order = %d\n", order ); + if ( order < tbl->mlbm.maxLevel ) + printk("alloc_tce_range_nolock: trying next bigger size\n" ); + else + printk("alloc_tce_range_nolock: maximum size reached...failing\n"); + } +#endif + + // If no block of the requested size was found, try the next + // size bigger. If one of those is found, return the second + // half of the block to freespace and keep the first half + if ( ( tcenum == -1 ) && ( order < tbl->mlbm.maxLevel ) ) { + tcenum = alloc_tce_range_nolock( tbl, order+1 ); + if ( tcenum != -1 ) { + free_tce_range_nolock( tbl, tcenum+(1<lock), flags ); + + // Do the actual work + free_tce_range_nolock( tbl, tcenum, order ); + + // Unlock the tce allocation bitmap + spin_unlock_irqrestore( &(tbl->lock), flags ); + +} + +static void free_tce_range_nolock( struct TceTable *tbl, long tcenum, unsigned order ) +{ + unsigned long block; + unsigned byte, bit, mask, b; + unsigned char * map, * bytep; + + if ( order > tbl->mlbm.maxLevel ) { + printk("free_tce_range: order too large, order = %d\n", order ); + return; + } + + block = tcenum >> order; + if ( tcenum != (block << order ) ) { + printk("free_tce_range: tcenum %lx is not on appropriate boundary for order %x\n", tcenum, order ); + return; + } + if ( block >= tbl->mlbm.level[order].numBits ) { + printk("free_tce_range: tcenum %lx is outside the range of this map (order %x, numBits %lx\n", tcenum, order, tbl->mlbm.level[order].numBits ); + return; + } +#ifdef DEBUG_TCE + if ( test_tce_range( tbl, tcenum, order ) ) { + printk("free_tce_range: freeing range not completely allocated.\n"); + printk("free_tce_range: TceTable %p, tcenum %lx, order %x\n", tbl, tcenum, order ); + } +#endif + map = tbl->mlbm.level[order].map; + byte = block / 8; + bit = block % 8; + mask = 0x80 >> bit; + bytep = map + byte; +#ifdef DEBUG_TCE + printk("free_tce_range_nolock: freeing block %ld (byte=%d, bit=%d) of order %d\n",block, byte, bit, order); + if ( *bytep & mask ) + printk("free_tce_range: already free: TceTable %p, tcenum %lx, order %x\n", tbl, tcenum, order ); +#endif + *bytep |= mask; + + // If there is a higher level in the bit map than this we may be + // able to buddy up this block with its partner. + // If this is the highest level we can't buddy up + // If this level has an odd number of bits and + // we are freeing the last block we can't buddy up + if ( ( order < tbl->mlbm.maxLevel ) && + ( ( 0 == ( tbl->mlbm.level[order].numBits & 1 ) ) || + ( block < tbl->mlbm.level[order].numBits-1 ) ) ) { + + // See if we can buddy up the block we just freed + bit &= 6; // get to the first of the buddy bits + mask = 0xc0 >> bit; // build two bit mask + b = *bytep & mask; // Get the two bits + if ( 0 == (b ^ mask) ) { // If both bits are on + // both of the buddy blocks are free we can combine them + *bytep ^= mask; // turn off the two bits + block = ( byte * 8 ) + bit; // block of first of buddies + tcenum = block << order; + // free the buddied block +#ifdef DEBUG_TCE + printk("free_tce_range: buddying up block %ld and block %ld\n", block, block+1); +#endif + free_tce_range_nolock( tbl, tcenum, order+1 ); + } + } +} + +static long test_tce_range( struct TceTable *tbl, long tcenum, unsigned order ) +{ + unsigned long block; + unsigned byte, bit, mask, b; + long retval, retLeft, retRight; + unsigned char * map; + + map = tbl->mlbm.level[order].map; + block = tcenum >> order; + byte = block / 8; // Byte within bitmap + bit = block % 8; // Bit within byte + mask = 0x80 >> bit; + b = (*(map+byte) & mask ); // 0 if block is allocated, else free + if ( b ) + retval = 1; // 1 == block is free + else + retval = 0; // 0 == block is allocated + // Test bits at all levels below this to ensure that all agree + + if (order) { + retLeft = test_tce_range( tbl, tcenum, order-1 ); + retRight = test_tce_range( tbl, tcenum+(1<<(order-1)), order-1 ); + if ( retLeft || retRight ) { + retval = 2; + } + } + + // Test bits at all levels above this to ensure that all agree + + return retval; +} + +static dma_addr_t get_tces( struct TceTable *tbl, unsigned order, void *page, unsigned numPages, int tceType, int direction ) +{ + long tcenum; + unsigned long uaddr; + unsigned i; + dma_addr_t retTce = NO_TCE; + + uaddr = (unsigned long)page & PAGE_MASK; + + // Allocate a range of tces + tcenum = alloc_tce_range( tbl, order ); + if ( tcenum != -1 ) { + // We got the tces we wanted + tcenum += tbl->startOffset; // Offset into real TCE table + retTce = tcenum << PAGE_SHIFT; // Set the return dma address + // Setup a tce for each page + for (i=0; isize * (PAGE_SIZE / sizeof(union Tce))) - 1; + + tcenum = dma_addr >> PAGE_SHIFT; + tcenum -= tbl->startOffset; + + if ( tcenum > maxTcenum ) { + printk("free_tces: tcenum > maxTcenum, tcenum = %ld, maxTcenum = %ld\n", + tcenum, maxTcenum ); + printk("free_tces: TCE Table at %16lx\n", (unsigned long)tbl ); + printk("free_tces: bus# %lu\n", (unsigned long)tbl->busNumber ); + printk("free_tces: size %lu\n", (unsigned long)tbl->size ); + printk("free_tces: startOff %lu\n", (unsigned long)tbl->startOffset ); + printk("free_tces: index %lu\n", (unsigned long)tbl->index ); + return; + } + + freeTce = tcenum; + + for (i=0; iindex, (u64)tcenum, tce.wholeTce ); + ++tcenum; + } + + free_tce_range( tbl, freeTce, order ); + +} + +void __init create_virtual_bus_tce_table(void) +{ + struct TceTable * t; + struct HvTceTableManagerCB virtBusTceTableParms; + u64 absParmsPtr; + + virtBusTceTableParms.busNumber = 255; /* Bus 255 is the virtual bus */ + virtBusTceTableParms.virtualBusFlag = 0xff; /* Ask for virtual bus */ + + absParmsPtr = virt_to_absolute( (u32)&virtBusTceTableParms ); + HvCallXm_getTceTableParms( absParmsPtr ); + + t = build_tce_table( &virtBusTceTableParms, &virtBusTceTable ); + if ( t ) { + tceTables[255] = t; + printk("Virtual Bus TCE table built successfully.\n"); + printk(" TCE table size = %ld entries\n", + (unsigned long)t->size*(PAGE_SIZE/sizeof(union Tce)) ); + printk(" TCE table token = %d\n", + (unsigned)t->index ); + printk(" TCE table start entry = 0x%lx\n", + (unsigned long)t->startOffset ); + } + else + printk("Virtual Bus TCE table failed.\n"); +} + +void __init create_pci_bus_tce_table( unsigned busNumber ) +{ + struct TceTable * t; + struct TceTable * newTceTable; + struct HvTceTableManagerCB pciBusTceTableParms; + u64 absParmsPtr; + unsigned i; + + if ( busNumber > 254 ) { + printk("PCI Bus TCE table failed.\n"); + printk(" Invalid bus number %u\n", busNumber ); + return; + } + + newTceTable = kmalloc( sizeof(struct TceTable), GFP_KERNEL ); + + pciBusTceTableParms.busNumber = busNumber; + pciBusTceTableParms.virtualBusFlag = 0; + + absParmsPtr = virt_to_absolute( (u32)&pciBusTceTableParms ); + HvCallXm_getTceTableParms( absParmsPtr ); + + // Determine if the table identified by the index and startOffset + // returned by the hypervisor for this bus has already been created. + + for ( i=0; i<255; ++i) { + t = tceTables[i]; + if ( t ) { + if ( ( t->index == pciBusTceTableParms.index ) && + ( t->startOffset == pciBusTceTableParms.startOffset ) ) { + if ( t->size != pciBusTceTableParms.size ) + printk("PCI Bus %d Shares a TCE table with Bus %d, but sizes differ\n", busNumber, i ); + else + printk("PCI Bus %d Shares a TCE table with bus %d\n", busNumber, i ); + tceTables[busNumber] = t; + break; + } + } + } + + if ( ! tceTables[busNumber] ) { + + t = build_tce_table( &pciBusTceTableParms, newTceTable ); + if ( t ) { + tceTables[busNumber] = t; + printk("PCI Bus %d TCE table built successfully.\n", busNumber); + printk(" TCE table size = %ld entries\n", + (unsigned long)t->size*(PAGE_SIZE/sizeof(union Tce)) ); + printk(" TCE table token = %d\n", + (unsigned)t->index ); + printk(" TCE table start entry = 0x%lx\n", + (unsigned long)t->startOffset ); + } + else { + kfree( newTceTable ); + printk("PCI Bus %d TCE table failed.\n", busNumber ); + } + } +} + + +// Allocates a contiguous real buffer and creates TCEs over it. +// Returns the virtual address of the buffer and sets dma_handle +// to the dma address (tce) of the first page. +void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t *dma_handle) +{ + struct TceTable * tbl; + void *ret = NULL; + unsigned order, nPages, bus; + dma_addr_t tce; + int tceType; + + size = PAGE_ALIGN(size); + order = get_order(size); + nPages = 1 << order; + + // If no pci_dev then use virtual bus + if (hwdev == NULL ) { + bus = 255; + tceType = TCE_VB; + } + else { +#ifdef CONFIG_PCI + // Get the iSeries bus # to use as an index + // into the TCE table array + bus = ISERIES_GET_BUS( hwdev ); + tceType = TCE_PCI; +#else + BUG(); + return NULL; +#endif /* CONFIG_PCI */ + } + + tbl = tceTables[bus]; + if ( tbl ) { + // Alloc enough pages (and possibly more) + ret = (void *)__get_free_pages( GFP_ATOMIC, order ); + if ( ret ) { + // Page allocation succeeded + memset(ret, 0, nPages << PAGE_SHIFT); + // Set up tces to cover the allocated range + tce = get_tces( tbl, order, ret, nPages, tceType, + PCI_DMA_BIDIRECTIONAL ); + if ( tce == NO_TCE ) { +#ifdef DEBUG_TCE + printk("pci_alloc_consistent: get_tces failed\n" ); +#endif + free_pages( (unsigned long)ret, order ); + ret = NULL; + } + else + { + *dma_handle = tce; + } + } +#ifdef DEBUG_TCE + else + printk("pci_alloc_consistent: __get_free_pages failed for order = %d\n", order); +#endif + } + + return ret; +} + +void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + struct TceTable * tbl; + unsigned order, nPages, bus; + + size = PAGE_ALIGN(size); + order = get_order(size); + nPages = 1 << order; + + // If no pci_dev then use virtual bus + if (hwdev == NULL ) + bus = 255; + else { +#ifdef CONFIG_PCI + // Get the iSeries bus # to use as an index + // into the TCE table array + bus = ISERIES_GET_BUS( hwdev ); +#else + BUG(); + return; +#endif /* CONFIG_PCI */ + } + + if ( bus > 255 ) { + printk("pci_free_consistent: invalid bus # %d\n", bus ); + printk("pci_free_consistent: hwdev = %08lx\n", (unsigned long)hwdev ); + } + + tbl = tceTables[bus]; + + if ( tbl ) { + free_tces( tbl, dma_handle, order, nPages ); + free_pages( (unsigned long)vaddr, order ); + } +} + +// Creates TCEs for a user provided buffer. The user buffer must be +// contiguous real kernel storage (not vmalloc). The address of the buffer +// passed here is the kernel (virtual) address of the buffer. The buffer +// need not be page aligned, the dma_addr_t returned will point to the same +// byte within the page as vaddr. +dma_addr_t pci_map_single( struct pci_dev *hwdev, void *vaddr, size_t size, int direction ) +{ + struct TceTable * tbl; + dma_addr_t dma_handle; + unsigned long uaddr; + unsigned order, nPages, bus; + int tceType; + + if ( direction == PCI_DMA_NONE ) + BUG(); + + dma_handle = NO_TCE; + + uaddr = (unsigned long)vaddr; + nPages = PAGE_ALIGN( uaddr + size ) - ( uaddr & PAGE_MASK ); + order = get_order( nPages & PAGE_MASK ); + nPages >>= PAGE_SHIFT; + + // If no pci_dev then use virtual bus + if (hwdev == NULL ) { + bus = 255; + tceType = TCE_VB; + } + else { +#ifdef CONFIG_PCI + // Get the iSeries bus # to use as an index + // into the TCE table array + bus = ISERIES_GET_BUS( hwdev ); + tceType = TCE_PCI; +#else + BUG(); + return NO_TCE; +#endif /* CONFIG_PCI */ + + } + + tbl = tceTables[bus]; + + if ( tbl ) { + dma_handle = get_tces( tbl, order, vaddr, nPages, tceType, + direction ); + dma_handle |= ( uaddr & ~PAGE_MASK ); + } + + return dma_handle; +} + +void pci_unmap_single( struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction ) +{ + struct TceTable * tbl; + unsigned order, nPages, bus; + + if ( direction == PCI_DMA_NONE ) + BUG(); + + nPages = PAGE_ALIGN( dma_handle + size ) - ( dma_handle & PAGE_MASK ); + order = get_order( nPages & PAGE_MASK ); + nPages >>= PAGE_SHIFT; + + // If no pci_dev then use virtual bus + if (hwdev == NULL ) + bus = 255; + else { +#ifdef CONFIG_PCI + // Get the iSeries bus # to use as an index + // into the TCE table array + bus = ISERIES_GET_BUS( hwdev ); +#else + BUG(); + return; +#endif /* CONFIG_PCI */ + } + + if ( bus > 255 ) { + printk("pci_unmap_single: invalid bus # %d\n", bus ); + printk("pci_unmap_single: hwdev = %08lx\n", (unsigned long)hwdev ); + } + + tbl = tceTables[bus]; + + if ( tbl ) + free_tces( tbl, dma_handle, order, nPages ); + +} + +// Figure out how many TCEs are actually going to be required +// to map this scatterlist. This code is not optimal. It +// takes into account the case where entry n ends in the same +// page in which entry n+1 starts. It does not handle the +// general case of entry n ending in the same page in which +// entry m starts. + +static unsigned long num_tces_sg( struct scatterlist *sg, int nents ) +{ + unsigned long nTces, numPages, startPage, endPage, prevEndPage; + unsigned i; + + prevEndPage = 0; + nTces = 0; + + for (i=0; iaddress >> PAGE_SHIFT; + endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT; + numPages = endPage - startPage + 1; + // Simple optimization: if the previous entry ended + // in the same page in which this entry starts + // then we can reduce the required pages by one. + // This matches assumptions in fill_scatterlist_sg and + // create_tces_sg + if ( startPage == prevEndPage ) + --numPages; + nTces += numPages; + prevEndPage = endPage; + sg++; + } + return nTces; +} + +// Fill in the dma data in the scatterlist +// return the number of dma sg entries created +static unsigned fill_scatterlist_sg( struct scatterlist *sg, int nents, + dma_addr_t dma_addr , unsigned long numTces) +{ + struct scatterlist *dma_sg; + u32 cur_start_dma; + unsigned long cur_len_dma, cur_end_virt, uaddr; + unsigned num_dma_ents; + + dma_sg = sg; + num_dma_ents = 1; + + // Process the first sg entry + cur_start_dma = dma_addr + ((unsigned long)sg->address & (~PAGE_MASK)); + cur_len_dma = sg->length; + // cur_end_virt holds the address of the byte immediately after the + // end of the current buffer. + cur_end_virt = (unsigned long)sg->address + cur_len_dma; + // Later code assumes that unused sg->dma_address and sg->dma_length + // fields will be zero. Other archs seem to assume that the user + // (device driver) guarantees that...I don't want to depend on that + sg->dma_address = sg->dma_length = 0; + + // Process the rest of the sg entries + while (--nents) { + ++sg; + // Clear possibly unused fields. Note: sg >= dma_sg so + // this can't be clearing a field we've already set + sg->dma_address = sg->dma_length = 0; + + // Check if it is possible to make this next entry + // contiguous (in dma space) with the previous entry. + + // The entries can be contiguous in dma space if + // the previous entry ends immediately before the + // start of the current entry (in virtual space) + // or if the previous entry ends at a page boundary + // and the current entry starts at a page boundary. + uaddr = (unsigned long)sg->address; + if ( ( uaddr != cur_end_virt ) && + ( ( ( uaddr | cur_end_virt ) & (~PAGE_MASK) ) || + ( ( uaddr & PAGE_MASK ) == ( ( cur_end_virt-1 ) & PAGE_MASK ) ) ) ) { + // This entry can not be contiguous in dma space. + // save the previous dma entry and start a new one + dma_sg->dma_address = cur_start_dma; + dma_sg->dma_length = cur_len_dma; + + ++dma_sg; + ++num_dma_ents; + + cur_start_dma += cur_len_dma-1; + // If the previous entry ends and this entry starts + // in the same page then they share a tce. In that + // case don't bump cur_start_dma to the next page + // in dma space. This matches assumptions made in + // num_tces_sg and create_tces_sg. + if ((uaddr & PAGE_MASK) == ((cur_end_virt-1) & PAGE_MASK)) + cur_start_dma &= PAGE_MASK; + else + cur_start_dma = PAGE_ALIGN(cur_start_dma+1); + cur_start_dma += ( uaddr & (~PAGE_MASK) ); + cur_len_dma = 0; + } + // Accumulate the length of this entry for the next + // dma entry + cur_len_dma += sg->length; + cur_end_virt = uaddr + sg->length; + } + // Fill in the last dma entry + dma_sg->dma_address = cur_start_dma; + dma_sg->dma_length = cur_len_dma; + + if ((((cur_start_dma +cur_len_dma - 1)>> PAGE_SHIFT) - (dma_addr >> PAGE_SHIFT) + 1) != numTces) + { + printk("fill_scatterlist_sg: numTces %ld, used tces %d\n", + numTces, + (unsigned)(((cur_start_dma + cur_len_dma - 1) >> PAGE_SHIFT) - (dma_addr >> PAGE_SHIFT) + 1)); + } + + + return num_dma_ents; +} + +// Call the hypervisor to create the TCE entries. +// return the number of TCEs created +static dma_addr_t create_tces_sg( struct TceTable *tbl, struct scatterlist *sg, + int nents, unsigned numTces, int tceType, int direction ) +{ + unsigned order, i, j; + unsigned long startPage, endPage, prevEndPage, numPages, uaddr; + long tcenum, starttcenum; + dma_addr_t dmaAddr; + + dmaAddr = NO_TCE; + + order = get_order( numTces << PAGE_SHIFT ); + // allocate a block of tces + tcenum = alloc_tce_range( tbl, order ); + if ( tcenum != -1 ) { + tcenum += tbl->startOffset; + starttcenum = tcenum; + dmaAddr = tcenum << PAGE_SHIFT; + prevEndPage = 0; + for (j=0; jaddress >> PAGE_SHIFT; + endPage = ((unsigned long)sg->address + sg->length - 1) >> PAGE_SHIFT; + numPages = endPage - startPage + 1; + + // If the previous entry ended in the same page that + // the current page starts then they share that + // tce and we reduce the number of tces we need + // by one. This matches assumptions made in + // num_tces_sg and fill_scatterlist_sg + if ( startPage == prevEndPage ) + --numPages; + + uaddr = (unsigned long)sg->address; + for (i=0; idma_address = pci_map_single( hwdev, sg->address, + sg->length, direction ); + sg->dma_length = sg->length; + return 1; + } + + if ( direction == PCI_DMA_NONE ) + BUG(); + + // If no pci_dev then use virtual bus + if (hwdev == NULL ) { + bus = 255; + tceType = TCE_VB; + } + else { +#ifdef CONFIG_PCI + // Get the iSeries bus # to use as an index + // into the TCE table array + bus = ISERIES_GET_BUS( hwdev ); + tceType = TCE_PCI; +#else + BUG(); + return 0; +#endif /* CONFIG_PCI */ + } + + tbl = tceTables[bus]; + + if ( tbl ) { + // Compute the number of tces required + numTces = num_tces_sg( sg, nents ); + // Create the tces and get the dma address + dma_handle = create_tces_sg( tbl, sg, nents, numTces, + tceType, direction ); + + // Fill in the dma scatterlist + num_dma = fill_scatterlist_sg( sg, nents, dma_handle, numTces ); + } + + return num_dma; +} + +void pci_unmap_sg( struct pci_dev *hwdev, struct scatterlist *sg, int nelms, int direction ) +{ + struct TceTable * tbl; + unsigned order, numTces, bus, i; + dma_addr_t dma_end_page, dma_start_page; + + if ( direction == PCI_DMA_NONE ) + BUG(); + + dma_start_page = sg->dma_address & PAGE_MASK; + for ( i=nelms; i>0; --i ) { + unsigned k = i - 1; + if ( sg[k].dma_length ) { + dma_end_page = ( sg[k].dma_address + + sg[k].dma_length - 1 ) & PAGE_MASK; + break; + } + } + + numTces = ((dma_end_page - dma_start_page ) >> PAGE_SHIFT) + 1; + order = get_order( numTces << PAGE_SHIFT ); + + // If no pci_dev then use virtual bus + if (hwdev == NULL ) + bus = 255; + else { +#ifdef CONFIG_PCI + // Get the iSeries bus # to use as an index + // into the TCE table array + bus = ISERIES_GET_BUS( hwdev ); +#else + BUG(); + return; +#endif /* CONFIG_PCI */ + } + + if ( bus > 255 ) { + printk("pci_unmap_sg: invalid bus # %d\n", bus ); + printk("pci_unmap_sg: hwdev = %08lx\n", (unsigned long)hwdev ); + } + + + tbl = tceTables[bus]; + + if ( tbl ) + free_tces( tbl, dma_start_page, order, numTces ); + +} + diff -Nru a/arch/ppc/kernel/iSeries_hashtable.c b/arch/ppc/kernel/iSeries_hashtable.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/iSeries_hashtable.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,336 @@ +/* + * + * + * Copyright (c) 2000 Mike Corrigan IBM Corporation + * + * Module name: iSeries_hashtable.c + * + * Description: + * Handles Hash Table faults for iSeries LPAR. + * + * 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 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +spinlock_t hash_table_lock __bolteddata = SPIN_LOCK_UNLOCKED; + +extern unsigned long htab_reloads; // Defined in ppc/kernel/ppc_htab.c +extern unsigned long htab_evicts; +unsigned long htab_pp_update = 0; +unsigned long htab_context_overflows = 0; +unsigned long htab_context_overflow_vsid = 0; +extern unsigned long Hash_mask; // Defined in ppc/mm/init.c +extern unsigned long end_of_DRAM; // Defined in ppc/mm/init.c + +unsigned long flush_hash_page_count __bolteddata = 0; + +static unsigned next_slot __bolteddata = 4; + +static inline u32 __bolted computeHptePP( unsigned long pte ) +{ + return ( pte & _PAGE_USER ) | + ( ( ( pte & _PAGE_USER ) >> 1 ) & + ( (~pte & _PAGE_HWWRITE ) >> 9 ) ); +} + +static inline u32 __bolted computeHpteHash( unsigned long vsid, + unsigned long pid ) +{ + return ( vsid ^ pid ) & Hash_mask; +} + +// Called from the Data/Instruction Store interrupt handlers +// in iSeries_head.S. +// +// This function is called from iSeries_head.S without using +// transfer_to_handler. Do not call any other kernel functions. +// +// va - the faulting value from the DAR (DSI) or SRR0 (ISI) +// access - contains the OR of _PAGE_USER (if problem state access) +// and _PAGE_RW (if store access) + +int __bolted hash_page( unsigned long va, unsigned long access ) +{ + + struct thread_struct *ts; + pgd_t * pg; + pmd_t * pm; + pte_t * pt; + pte_t pte, new_pte; + int rc; + unsigned flags; + PTE hpte; + u64 vpn, *hpte0Ptr, *hpte1Ptr; + u32 vsid, pi, newpp, gIndex; + u64 rtnIndex; + struct Paca * paca; + unsigned long tempContext; + + // return value of 1 indicates failure. do_fault will be called + rc = 1; + + // Check if this is a kernel address. If it is we want to + // handle this fault without touching a page table (which + // might cause a little fault) + if ( ( va >= KERNELBASE ) && ( va < end_of_DRAM ) ) { + pte_val(pte) = (__pa(va) & PAGE_MASK) | _PAGE_PRESENT | + _PAGE_ACCESSED | _PAGE_SHARED | _PAGE_RW | + _PAGE_DIRTY | _PAGE_HWWRITE; + pt = &new_pte; + } + // Not a kernel address, we need to look it up in a PGDIR + // If it is a vmalloc address we will look it up in + // swapper_pg_dir otherwise use the current process' PGDIR + else { + if ( va >= KERNELBASE ) + pg = swapper_pg_dir; + else { + // Get the thread structure + ts = (struct thread_struct *)mfspr(SPRG3); + // Get the page directory + pg = ts->pgdir; + } + + pg = pg + pgd_index( va ); // offset into first level + pm = pmd_offset( pg, va ); // offset into second level + if ( pmd_none( *pm ) ) // if no third level + return 1; // indicate failure + pt = pte_offset( pm, va ); // offset into third level + pte = *pt; // get page table entry + } + access |= _PAGE_PRESENT; // _PAGE_PRESENT also needed + // check if pte is in the required state + if ( 0 == ( access & ~(pte_val(pte)) ) ) { + + /* pte allows the access we are making */ + flags = _PAGE_ACCESSED; + if ( access & _PAGE_RW ) /* If write access */ + flags |= _PAGE_DIRTY | _PAGE_HWWRITE; + /* atomically update pte */ + pte_update( pt, 0, flags ); + + rc = 0; + + // Now update the PowerPC hashed page table + + newpp = computeHptePP( pte_val(pte) ); + + hpte0Ptr = (u64 *)&hpte; + hpte1Ptr = hpte0Ptr + 1; + *hpte0Ptr = *hpte1Ptr = 0; + + vsid = mfsrin( va ) & 0x07ffffff; + pi = (va >> 12) & 0xffff; + vpn = ((u64)vsid << 16) | pi; + spin_lock( &hash_table_lock ); + + /* HACK HACK HACK */ + /* Assign a new set of vsids (context) to this processor + * if we have just overflowed the context generator. The + * new set assigned here is a temporary set preassigned to + * this processor. + */ + + paca = (struct Paca *)mfspr(SPRG1); + if ( paca->xContextOverflow ) { + ++htab_context_overflows; + htab_context_overflow_vsid = vsid; + spin_unlock( &hash_table_lock ); + tempContext = MUNGE_CONTEXT(paca->xPacaIndex+1); + set_context( tempContext, 0 ); + return 0; + } + + ++htab_reloads; + + rtnIndex = HvCallHpt_findValid( &hpte, vpn ); + + if ( hpte.v ) { + // A matching valid entry was found + // Just update the pp bits + ++htab_pp_update; + HvCallHpt_setPp( rtnIndex, newpp ); + } + else { // No matching entry was found + // Build new hpte + *hpte0Ptr = *hpte1Ptr = 0; + hpte.vsid = vsid; + hpte.api = (va >> 23) & 0x1f; + hpte.v = 1; + hpte.rpn = physRpn_to_absRpn(pte_val(pte)>>12); + hpte.r = 1; + hpte.c = 1; + hpte.m = 1; + hpte.pp = newpp; + + // rtnIndex == 0xffffffffffffffff was supposed + // to mean no free entry found. Ken is + // passing 0x00000000ffffffff for this. + // rtnIndex == 0x80000000xxxxxxxx is supposed + // to mean free entry xxxxxxxx is in secondary + // group. I wonder if Ken is really setting + // it as 0x000000008xxxxxxx?? + +// if ( rtnIndex != ~0 ) { + if ( ( rtnIndex != ~0 ) && + ( rtnIndex != 0x00000000ffffffff ) ) { + // Free entry was found +// if ( rtnIndex >> 63 ) + if ( ( rtnIndex >> 63 ) || + ( rtnIndex & 0x80000000 ) ) + hpte.h = 1; + HvCallHpt_addValidate( + rtnIndex, + hpte.h, + &hpte ); + } + else { + // No free entry was found + gIndex = computeHpteHash( vsid, pi ); +// gIndex = (vsid ^ pi) & Hash_mask; + rtnIndex = gIndex*8 + next_slot; + if ( ++next_slot > 7 ) + next_slot = 1; + HvCallHpt_invalidateSetSwBitsGet( + rtnIndex, 0, 0 ); +// HvCallHpt_invalidateNoSyncICache( +// rtnIndex ); + HvCallHpt_addValidate( + rtnIndex, 0, &hpte ); + ++htab_evicts; + } + } + spin_unlock( &hash_table_lock ); + } + + return rc; + +} + +unsigned long flush_hash_range_count __bolteddata = 0; +unsigned long flush_hash_range_hv_finds __bolteddata = 0; +unsigned long flush_hash_range_hv_evicts __bolteddata = 0; + +#if 0 +static void __bolted flush_hash_range( u64 lVa, u64 hVa ) +{ + PTE hpte; + u64 hpteIndex, group, va; + unsigned long flags; + unsigned long pi; + + // We need to be disabled when we get the hash_table_lock + // because any interrupt (decrementer, external, etc.) + // could cause hash page table faults, resulting in a + // deadlock. + + // FIXME: This code should really run on a bolted stack + // (or without a stack) as any hash page table fault + // (on the stack for example) will cause a deadlock. + + spin_lock_irqsave( &hash_table_lock, flags ); + + hpteIndex = 0; + for (;;) { + ++flush_hash_range_hv_finds; + hpteIndex = HvCallHpt_findNextValid( &hpte, hpteIndex, 0, 0 ); + if ( hpte.v == 0 ) + break; + group = hpteIndex >> 3; + if ( hpte.h == 1 ) + group = ~group; + pi = (unsigned long)(hpte.vsid ^ group) & 0x7ff; + pi |= ( hpte.api << 11 ); + + va = ( ( hpte.vsid << 16 ) + pi) << 12; + if ( ( va >= lVa ) && ( va <= hVa ) ) { + ++flush_hash_range_hv_evicts; + HvCallHpt_invalidateSetSwBitsGet( hpteIndex, 0, 0 ); + } + ++hpteIndex; + } + + spin_unlock_irqrestore( &hash_table_lock, flags ); + +} +#endif + +extern void flush_hash_range( u64, u64, unsigned ); + +void __bolted flush_hash_all( void ) +{ + flush_hash_range( (u64)VMALLOC_START, (u64)0xffffffffffffffff, 0 ); +} + +void __bolted flush_hash_user( unsigned pacas ) +{ + flush_hash_range( (u64)0x0000000100000000, (u64)0xffffffffffffffff, pacas ); +} + +void __bolted flush_hash_kernel( void ) +{ + flush_hash_range( (u64)VMALLOC_START, (u64)0x00000000ffffffff, 0 ); +} + +#if 0 +void __bolted flush_hash_segments( u32 lVsid, u32 hVsid ) +{ + PTE hpte; + u64 hpteIndex; + u64 lowVsid, highVsid; + unsigned long flags; + + ++flush_hash_segments_count; + + lowVsid = lVsid; + highVsid = hVsid; + + // We need to be disabled when we get the hash_table_lock + // because any interrupt (decrementer, external, etc.) + // could cause hash page table faults, resulting in a + // deadlock. + + spin_lock_irqsave( &hash_table_lock, flags ); + + hpteIndex = 0; + for (;;) { + ++flush_hash_segments_hv_finds; + hpteIndex = HvCallHpt_findNextValid( &hpte, hpteIndex, 0, 0 ); + if ( hpte.v == 0 ) + break; + if ( ( hpte.vsid >= lowVsid ) && ( hpte.vsid <= highVsid ) ) { + ++flush_hash_segments_hv_evicts; + HvCallHpt_invalidateSetSwBitsGet( hpteIndex, 0, 0 ); + } + ++hpteIndex; + } + + spin_unlock_irqrestore( &hash_table_lock, flags ); + +} +#endif diff -Nru a/arch/ppc/kernel/iSeries_head.S b/arch/ppc/kernel/iSeries_head.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/iSeries_head.S Sat Jun 16 06:00:30 2001 @@ -0,0 +1,1755 @@ +/* + * arch/ppc/kernel/iSeries_head.S + * + * Adapted from arch/ppc/kernel/head.S + * + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP + * Copyright (C) 1996 Cort Dougan + * Adapted for Power Macintosh by Paul Mackerras. + * Low-level exception handlers and MMU support + * rewritten by Paul Mackerras. + * Copyright (C) 1996 Paul Mackerras. + * Adapted for iSeries by Mike Corrigan + * + * This file contains the low-level support and setup for the + * iSeries LPAR platform. + * + * 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 "ppc_asm.h" +#include +#include +#include +#include +#include + + + .text + .globl _stext +_stext: + + +/* iSeries LPAR + * + * In an iSeries partition, the operating system has no direct access + * to the hashed page table. The iSeries hypervisor manages the + * hashed page table, and is directed by the operating system in the + * partition. The partition, Linux in this case, always runs with + * MSR.IR and MSR.DR equal to 1. The hypervisor establishes + * addressibility for the first 64 MB of memory at 0xC0000000 by + * building a hashed page table and setting segment register 12. + * + * The partition memory is not physically contiguous, nor necessarily + * addressable with a 32-bit address. The hypervisor provides functions + * which the kernel can use to discover the layout of memory. The + * iSeries LPAR specific code in the kernel will build a table that maps + * contiguous pseudo-real addresses starting at zero to the actual + * physical addresses owned by this partition. In 32-bit mode we will + * restrict ourselves to no more than 768 MB (or maybe 1 GB) + * + * When Linux interrupt handlers get control, the hypervisor has + * already saved SRR0 and SRR1 into a control block shared between + * the hypervisor and Linux. This is know as the ItLpPaca. The values + * in the actual SRR0 and SRR1 are not valid. This requires a change in + * the way the SPRG registers are used. The definitions are: + * + * Register old definition new definition + * + * SPRG0 temp - used to save gpr reserved for hypervisor + * SPRG1 temp - used to save gpr addr of Paca + * SPRG2 0 or kernel stack frame temp - used to save gpr + * SPRG3 Linux thread Linux thread + * + * The Paca contains the address of the ItLpPaca. The Paca is known only + * to Linux, while the ItLpPaca is shared between Linux and the + * hypervisor. + * + * The value that used to be in SPRG2 will now be saved in the Paca, + * as will at least one GPR. + */ + + .globl __start +__start: + b start_here + + + . = 0x020 + + /* iSeries LPAR hypervisor expects a 64-bit offset of + the hvReleaseData structure (see HvReleaseData.h) + at offset 0x20. This is the base for all common + control blocks between the hypervisor and the kernel + */ + + .long 0 + .long hvReleaseData-KERNELBASE + .long 0 + .long msChunks-KERNELBASE + .long 0 + .long pidhash-KERNELBASE + /* Pointer to start of embedded System.map */ + .long 0 + .globl embedded_sysmap_start +embedded_sysmap_start: + .long 0 + /* Pointer to end of embedded System.map */ + .long 0 + .globl embedded_sysmap_end +embedded_sysmap_end: + .long 0 + + + . = 0x060 + + .globl ste_fault_count +ste_fault_count: + .long 0 + .globl set_context_count +set_context_count: + .long 0 + .globl yield_count +yield_count: + .long 0 + .globl update_times_count +update_times_count: + .long 0 + .globl update_wall_jiffies_count +update_wall_jiffies_count: + .long 0 + .globl update_wall_jiffies_ticks +update_wall_jiffies_ticks: + .long 0 + + +/* + * We assume SPRG1 has the address of the Paca and SPRG3 + * has the address of the task's thread_struct. + * SPRG2 is used as a scratch register (as required by the + * hypervisor). SPRG0 is reserved for the hypervisor. + * + * The ItLpPaca has the values of SRR0 and SRR1 that the + * hypervisor saved at the point of the actual interrupt. + * + * The Paca contains the value that the non-LPAR PPC Linux Kernel + * keeps in SPRG2, which is either zero (if the interrupt + * occurred in the kernel) or the address of the available + * space on the kernel stack (if the interrupt occurred + * in user code). +*/ + +#define EXCEPTION_PROLOG_1 \ + mtspr SPRG2,r20; /* use SPRG2 as scratch reg */\ + mfspr r20,SPRG1; /* get Paca */\ + /* must do std not stw because soft disable protects \ + * 64-bit register use (in HvCall, maybe others) \ + */\ + std r21,PACAR21(r20); /* Save GPR21 in Paca */\ + std r22,PACAR22(r20) /* Save GPR22 in Paca */ + +#define EXCEPTION_PROLOG_2 \ + lwz r21,PACABOLTEDSTACK(r20); /* Get bolted stack */\ + lwz r22,BOLTEDSTACKNEXT(r21); /* Get next bolted stack ptr */\ + stw r22,PACABOLTEDSTACK(r20); /* Dequeue my stack */\ + addi r21,r21,BOLTEDSTACKSIZE-INT_FRAME_SIZE; /* Make stack frame */\ + /* This code saves: CR, LR, CTR, XER, DAR, DSISR, SRR0, SRR1, */\ + /* r0-r13, r20-r24 */\ + mfcr r22; /* Get CR */\ + stw r22,_CCR(r21); /* save CR in stackframe */\ + ld r22,PACAR21(r20); /* Get GPR21 from Paca */\ + stw r22,GPR21(r21); /* Save GPR21 in stackframe */\ + ld r22,PACAR22(r20); /* Get GPR22 from Paca */\ + stw r22,GPR22(r21); /* Save GPR22 in stackframe */\ + stw r23,GPR23(r21); /* Save GPR23 in stackframe */\ + stw r24,GPR24(r21); /* Save GPR24 in stackframe */\ + mfspr r22,SPRG2; /* Get GPR20 from SPRG2 */\ + stw r22,GPR20(r21); /* Save GPR20 in stackframe */\ + mflr r22; \ + stw r22,_LINK(r21); \ + mfctr r22; \ + stw r22,_CTR(r21); \ + mfspr r22,XER; \ + stw r22,_XER(r21); \ + mfspr r22,DAR; /* Only needed for DSI */\ + stw r22,_DAR(r21); /* But its more convenient here*/\ + mfspr r22,DSISR; \ + stw r22,_DSISR(r21);\ + lbz r22,PACAPROCENABLED(r20); /* Get soft enabled/disabled */\ + stw r22,_SOFTE(r21);\ + ld r22,PACALPPACA+LPPACASRR0(r20); /* Get SRR0 from ItLpPaca */\ + ld r23,PACALPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca */\ + SAVE_8GPRS(0, r21); \ + SAVE_4GPRS(8, r21); \ + SAVE_2GPRS(12, r21) + +#define EXCEPTION_PROLOG_EXIT \ + mtcrf 0xff,r22; \ + ld r22,PACALPPACA+LPPACASRR0(r20); \ + ld r21,PACALPPACA+LPPACASRR1(r20); \ + mtspr SRR0,r22; \ + mtspr SRR1,r21; \ + ld r22,PACAR22(r20); \ + ld r21,PACAR21(r20); \ + mfspr r20,SPRG2; \ + RFI + +#define EXCEPTION_PROLOG \ + EXCEPTION_PROLOG_1; \ + EXCEPTION_PROLOG_2 + +#define SELECT_KSTACK \ + lwz r24,PACAKSAVE(r20); /* exception stack to use */\ + cmpwi 0,r24,0; /* user mode or kernel */\ + lwz r1,GPR1(r21); /* get original r1 */\ + bne 1f; /* 0 -> r1, else use PACAKSAVE */\ + subi r24,r1,INT_FRAME_SIZE; /* alloc exc. frame */\ +1: mr r1,r24 /* Now stack is at r1 */ + + +/* + * Note: code which follows this uses cr0.eq (set if from kernel), + * r21, r22 (SRR0), and r23 (SRR1). + */ + +/* + * Exception vectors. + */ +#define STD_EXCEPTION(n, label, hdlr) \ + . = n; \ +label: \ + EXCEPTION_PROLOG; \ + SELECT_KSTACK; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + li r20,0; /* soft disabled */\ + bl transfer_to_handler; \ + .long hdlr; \ + .long ret_from_except + +/* System reset */ + . = 0x100 +SystemReset: + mfspr r3,SPRG3 /* Get Paca address */ + mtspr SPRG1,r3 /* Set Linux SPRG1 -> Paca */ + lhz r24,PACAPACAINDEX(r3) /* Get processor # */ + cmpi 0,r24,0 /* Are we processor 0? */ + beq start_here /* Start up the first processor */ + mfspr r4,CTRLF + li r5,RUNLATCH + andc r4,r4,r5 /* Turn off the run light */ + mtspr CTRLT,r4 +1: + HMT_LOW +#ifdef CONFIG_SMP + lbz r23,PACAPROCSTART(r3) /* Test if this processor + * should start */ + cmpi 0,r23,0 +#if 1 + beq secondary_smp_loop /* Loop until told to go */ +#else + b secondary_smp_loop /* Loop forever */ +#endif + b secondary_start +secondary_smp_loop: + /* Let the Hypervisor know we are alive */ + /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */ + lis r3,0x8002 + rldicr r0,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */ + rldicl r3,r3,0,48 /* r3 = r3 & 0x000000000000ffff */ + or r3,r3,r0 /* r3 = r3 | r0 */ +#else /* CONFIG_SMP */ + /* Yield the processor. This is required for non-SMP kernels + which are running on multi-threaded machines. */ + lis r3,0x8000 + rldicr r3,r3,32,15 /* r3 = (r3 << 32) & 0xffff000000000000 */ + addi r3,r3,18 /* r3 = 0x8000000000000012 which is "yield" */ + li r4,0 /* "yield timed" */ + li r5,-1 /* "yield forever" */ +#endif /* CONFIG_SMP */ + li r0,-1 /* r0=-1 indicates a Hypervisor call */ + sc /* Invoke the hypervisor via a system call */ + mfspr r3,SPRG1 /* Put r3 back */ + b 1b /* If SMP not configured, secondaries + * loop forever */ + +/* Machine check */ + STD_EXCEPTION(0x200, MachineCheck, MachineCheckException) + +/* Data access exception. */ + . = 0x300 +DataAccess: + b _dataAccess + +_dataAccessContinue: + addi r3,r1,STACK_FRAME_OVERHEAD + lbz r20,PACAPROCENABLED(r20) /* preserve soft en/disabled */ + bl transfer_to_handler + .long do_page_fault + .long ret_from_except + + +/* Instruction access exception. */ + . = 0x400 +InstructionAccess: + b _instructionAccess + +_instructionAccessContinue: + addi r3,r1,STACK_FRAME_OVERHEAD + lbz r20,PACAPROCENABLED(r20) /* preserve soft en/disabled */ + bl transfer_to_handler + .long do_page_fault + .long ret_from_except + +/* External interrupt */ + . = 0x500; +HardwareInterrupt: + b _hardwareInterrupt + +_hardwareInterruptContinue: + addi r3,r1,STACK_FRAME_OVERHEAD + li r4,0 + li r20,0 /* Soft disabled */ + bl transfer_to_handler + .globl do_IRQ_intercept +do_IRQ_intercept: + .long do_IRQ; + .long ret_from_intercept + +/* Alignment exception */ + . = 0x600 +Alignment: + EXCEPTION_PROLOG + SELECT_KSTACK + lwz r4,_DAR(r21) + lwz r5,_DSISR(r21) + addi r3,r1,STACK_FRAME_OVERHEAD + lbz r20,PACAPROCENABLED(r20) /* preserve soft en/disabled */ + bl transfer_to_handler + .long AlignmentException + .long ret_from_except + +/* Program check exception */ + . = 0x700 +ProgramCheck: + EXCEPTION_PROLOG + SELECT_KSTACK + addi r3,r1,STACK_FRAME_OVERHEAD + lbz r20,PACAPROCENABLED(r20) /* preserve soft en/disabled */ + bl transfer_to_handler + .long ProgramCheckException + .long ret_from_except + +/* Floating-point unavailable */ + . = 0x800 +FPUnavailable: + EXCEPTION_PROLOG + SELECT_KSTACK + beq 1f + b load_up_fpu /* if from user, just load it up */ +1: + li r20,0 /* soft disabled */ + bl transfer_to_handler /* if from kernel, take a trap */ + .long KernelFP + .long ret_from_except + + . = 0x900 +Decrementer: + b _decrementerInterrupt + +_decrementerInterruptContinue: + addi r3,r1,STACK_FRAME_OVERHEAD + li r20,0 /* Soft disabled */ + bl transfer_to_handler + .globl timer_interrupt_intercept +timer_interrupt_intercept: + .long timer_interrupt + .long ret_from_intercept + + STD_EXCEPTION(0xa00, Trap_0a, UnknownException) + STD_EXCEPTION(0xb00, Trap_0b, UnknownException) + +/* System call */ + . = 0xc00 +SystemCall: + EXCEPTION_PROLOG + SELECT_KSTACK + /* Store r3 to the kernel stack - this may take a little fault */ + stw r3,ORIG_GPR3(r1) + lbz r20,PACAPROCENABLED(r20) /* preserve soft en/disabled */ + bl transfer_to_handler + .long DoSyscall + .long ret_from_except + +/* Single step - not used on 601 */ + STD_EXCEPTION(0xd00, SingleStep, SingleStepException) +/* + STD_EXCEPTION(0xe00, Trap_0e, UnknownException) + STD_EXCEPTION(0xf00, Trap_0f, UnknownException) +*/ + STD_EXCEPTION(0x1300, Trap_13, InstructionBreakpoint) +/* + STD_EXCEPTION(0x1400, SMI, SMIException) + STD_EXCEPTION(0x1500, Trap_15, UnknownException) + STD_EXCEPTION(0x1600, Trap_16, UnknownException) + STD_EXCEPTION(0x1700, Trap_17, TAUException) + STD_EXCEPTION(0x1800, Trap_18, UnknownException) + STD_EXCEPTION(0x1900, Trap_19, UnknownException) + STD_EXCEPTION(0x1a00, Trap_1a, UnknownException) + STD_EXCEPTION(0x1b00, Trap_1b, UnknownException) + STD_EXCEPTION(0x1c00, Trap_1c, UnknownException) + STD_EXCEPTION(0x1d00, Trap_1d, UnknownException) + STD_EXCEPTION(0x1e00, Trap_1e, UnknownException) + STD_EXCEPTION(0x1f00, Trap_1f, UnknownException) + STD_EXCEPTION(0x2000, RunMode, RunModeException) + STD_EXCEPTION(0x2100, Trap_21, UnknownException) + STD_EXCEPTION(0x2200, Trap_22, UnknownException) + STD_EXCEPTION(0x2300, Trap_23, UnknownException) + STD_EXCEPTION(0x2400, Trap_24, UnknownException) + STD_EXCEPTION(0x2500, Trap_25, UnknownException) + STD_EXCEPTION(0x2600, Trap_26, UnknownException) + STD_EXCEPTION(0x2700, Trap_27, UnknownException) + STD_EXCEPTION(0x2800, Trap_28, UnknownException) + STD_EXCEPTION(0x2900, Trap_29, UnknownException) + STD_EXCEPTION(0x2a00, Trap_2a, UnknownException) + STD_EXCEPTION(0x2b00, Trap_2b, UnknownException) + STD_EXCEPTION(0x2c00, Trap_2c, UnknownException) + STD_EXCEPTION(0x2d00, Trap_2d, UnknownException) + STD_EXCEPTION(0x2e00, Trap_2e, UnknownException) + STD_EXCEPTION(0x2f00, Trap_2f, UnknownException) +*/ + . = 0x3000 + + __BOLTEDCODE + +_hardwareInterrupt: + + EXCEPTION_PROLOG_1 + lbz r21,PACAPROCENABLED(r20) + mfcr r22 + cmpi 0,r21,0 + bne 1f + EXCEPTION_PROLOG_EXIT +1: + mtcrf 0xff,r22 + EXCEPTION_PROLOG_2 + SELECT_KSTACK + b _hardwareInterruptContinue + +_decrementerInterrupt: + + EXCEPTION_PROLOG_1 + lbz r21,PACAPROCENABLED(r20) + mfcr r22 + cmpi 0,r21,0 + bne 1f + + li r21,1 + stb r21,PACALPPACA+LPPACADECRINT(r20) + lis r21,iSeries_dec_value@ha + lwz r21,iSeries_dec_value@l(r21) + mtspr DEC,r21 + + EXCEPTION_PROLOG_EXIT +1: + mtcrf 0xff,r22 + EXCEPTION_PROLOG_2 + SELECT_KSTACK + b _decrementerInterruptContinue + + +_dataAccess: + + EXCEPTION_PROLOG + + /* + * At this point r0-r13, r20-r24, CCR, LINK, CTR, XER, DAR and DSISR + * have been saved to the bolted stack savearea + * + * r21 points to the bolted stack frame + * + * We may be handling a recursive fault on a kernel stack or + * page table. The saved registers represent the original + * interrupt, we get the "current" DAR and DSISR from the + * hardware registers + */ + + mfspr r3,DSISR /* Get most recent DSISR */ + + andis. r0,r3,0x0020 /* Is this a segment fault? */ + bne ste_fault /* Yes - go reload segment regs */ + + /* This should and with 0xd7ff */ + andis. r0,r3,0xa470 /* Can we handle as little fault? */ + bne 1f /* */ + + rlwinm r4,r3,32-23,29,29 /* DSISR_STORE -> _PAGE_RW */ + mfspr r3,DAR /* Get most recent DAR */ + stw r1,0(r21) /* Set stack linkage */ + mr r1,r21 /* Set stack pointer */ + + bl do_hash_page_DSI /* Try to handle as hpte fault */ +1: + lwz r4,_DAR(r21) /* Get original DAR */ + lwz r5,_DSISR(r21) /* and original DSISR */ + + SELECT_KSTACK + + b _dataAccessContinue /* do this so TRAP comes out right */ + +ste_fault: + + lis r3,ste_fault_count@ha + lwz r4,ste_fault_count@l(r3) + addi r4,r4,1 + stw r4,ste_fault_count@l(r3) + + mfspr r3,SPRG3 /* get thread */ + addi r3,r3,-THREAD /* get 'current' */ + lwz r3,MM(r3) /* get mm */ + cmpi 0,r3,0 /* if no mm */ + beq 1f /* then use context 0 (kernel) */ + lwz r3,CONTEXT(r3) /* get context */ +1: + /* set_context kills r0, r3, r4 and CTR */ + bl set_context + + b fault_exit + +_instructionAccess: + + EXCEPTION_PROLOG + /* + * At this point r0-r13, r20-r24, CCR, LINK, CTR, XER, DAR and DSISR + * have been saved to the bolted stack savearea + * + * r21 points to the bolted stack frame + * + * We won't get an instruction store interrupt which is a + * recursive fault, but an instruction store interrupt may + * result in a recursive data store interrupt. This means that + * + * We may be handling a recursive fault on a kernel stack or + * page table. The saved registers represent the original + * interrupt, we get the "current" DAR and DSISR from the + * hardware registers + */ + + andis. r0,r23,0x0020 /* Is this a segment fault? */ + bne ste_fault /* Yes - go reload segment regs */ + + andis. r0,r23,0x4000 /* no pte found? */ + beq 1f /* if so, try to put a PTE */ + mr r3,r22 /* into the hash table */ + stw r1,0(r21) /* Set stack linkage */ + mr r1,r21 /* Set stack pointer */ + + li r0,0 + stb r0,PACAPROCENABLED(r20) /* Soft disable because do_hash_page_ISI + will hard enable */ + + bl do_hash_page_ISI /* Try to handle as hpte fault */ +1: + SELECT_KSTACK + + mr r4,r22 + mr r5,r23 + b _instructionAccessContinue /* make TRAP come out right */ + + +/* + * This code finishes saving the registers to the exception frame + * and jumps to the appropriate handler for the exception, turning + * on address translation. + * + * At this point r0-r13, r20-r24, CCR, CTR, LINK, XER, DAR and DSISR + * are saved on a bolted stack. SRR0 is in r22, SRR1 is in r23 + * r21 points to the bolted stackframe, r1 points to the kernel stackframe + * We no longer have any dependency on data saved in the PACA, SRR0, SRR1 + * DAR or DSISR. We now copy the registers to the kernel stack (which + * might cause little faults). Any little fault will be handled without + * saving state. Thus when the little fault is completed, it will rfi + * back to the original faulting instruction. + */ + .globl transfer_to_handler +transfer_to_handler: + + /* + * Now we can start saving to the kernel stack + * and little faults will not be a problem + * because a recursive fault will not save any + * registers over the PTREGS on the bolted stack + */ + lwz r6,_CCR(r21) + lwz r7,_LINK(r21) + stw r6,_CCR(r1) + stw r7,_LINK(r1) + lwz r6,_CTR(r21) + lwz r7,_XER(r21) + stw r6,_CTR(r1) + stw r7,_XER(r1) + lwz r6,_DAR(r21) + lwz r7,_DSISR(r21) + stw r6,_DAR(r1) + stw r7,_DSISR(r1) + lwz r6,GPR20(r21) + lwz r7,GPR21(r21) + stw r6,GPR20(r1) + stw r7,GPR21(r1) + lwz r6,GPR22(r21) + lwz r7,GPR23(r21) + stw r6,GPR22(r1) + stw r7,GPR23(r1) + lwz r6,GPR24(r21) + stw r6,GPR24(r1) + lwz r6,GPR0(r21) + lwz r7,GPR1(r21) + stw r6,GPR0(r1) + stw r7,GPR1(r1) + lwz r6,GPR2(r21) + lwz r7,GPR3(r21) + stw r6,GPR2(r1) + stw r7,GPR3(r1) + lwz r6,GPR4(r21) + lwz r7,GPR5(r21) + stw r6,GPR4(r1) + stw r7,GPR5(r1) + lwz r6,GPR6(r21) + lwz r7,GPR7(r21) + stw r6,GPR6(r1) + stw r7,GPR7(r1) + lwz r6,GPR8(r21) + lwz r7,GPR9(r21) + stw r6,GPR8(r1) + stw r7,GPR9(r1) + lwz r6,GPR10(r21) + lwz r7,GPR11(r21) + stw r6,GPR10(r1) + stw r7,GPR11(r1) + lwz r6,GPR12(r21) + lwz r7,GPR13(r21) + stw r6,GPR12(r1) + stw r7,GPR13(r1) + lwz r6,_SOFTE(r21) + stw r6,_SOFTE(r1) + stw r22,_NIP(r1) + stw r23,_MSR(r1) + SAVE_4GPRS(14, r1) + SAVE_2GPRS(18, r1) + SAVE_4GPRS(25, r1) + SAVE_2GPRS(29, r1) + SAVE_GPR(31, r1) + + /* Restore the regs used above -- parameters to syscall */ + lwz r6,GPR6(r1) + lwz r7,GPR7(r1) + + /* + * We are now done with the bolted stack. Enqueue it back onto + * the queue of bolted stacks for this processor. + */ + + subi r21,r21,BOLTEDSTACKSIZE-INT_FRAME_SIZE + mfspr r22,SPRG1 /* Get Paca address */ + lwz r24,PACABOLTEDSTACK(r22) /* Get top of bolted stack list */ + stw r24,BOLTEDSTACKNEXT(r21) /* Link to our bolted stack */ + stw r21,PACABOLTEDSTACK(r22) /* Link our bolted stack first */ + + andi. r23,r23,MSR_PR + mfspr r23,SPRG3 /* if from user, fix up THREAD.regs */ + beq 2f + addi r24,r1,STACK_FRAME_OVERHEAD + stw r24,PT_REGS(r23) +2: addi r2,r23,-THREAD /* set r2 to current */ + li r22,RESULT + stwcx. r22,r22,r1 /* to clear the reservation */ + li r22,0 + stw r22,RESULT(r1) + mfspr r23,SPRG1 /* Get Paca address */ + stw r22,PACAKSAVE(r23) /* r1 is now kernel sp */ + stb r20,PACAPROCENABLED(r23) /* soft enable or disabled */ + mflr r23 + andi. r24,r23,0x3f00 /* get vector offset */ + stw r24,TRAP(r1) + addi r24,r2,TASK_STRUCT_SIZE /* check for kernel stack overflow */ + cmplw 0,r1,r2 + cmplw 1,r1,r24 + crand 1,1,4 + bgt- stack_ovf /* if r2 < r1 < r2+TASK_STRUCT_SIZE */ + lwz r24,0(r23) /* virtual address of handler */ + lwz r23,4(r23) /* where to go when done */ + li r20,MSR_KERNEL + ori r20,r20,MSR_EE /* Always hard enabled */ + FIX_SRR1(r20,r22) + mtspr SRR0,r24 + mtspr SRR1,r20 + mtlr r23 + SYNC + RFI /* jump to handler, enable MMU */ + +/* + * On kernel stack overflow, load up an initial stack pointer + * and call StackOverflow(regs), which should not return. + */ +stack_ovf: + addi r3,r1,STACK_FRAME_OVERHEAD + lis r1,init_task_union@ha + addi r1,r1,init_task_union@l + addi r1,r1,TASK_UNION_SIZE-STACK_FRAME_OVERHEAD + mfspr r24,SPRG1 + li r20,0 + stb r20,PACAPROCENABLED(r24) /* soft disable */ + lis r24,StackOverflow@ha + addi r24,r24,StackOverflow@l + li r20,MSR_KERNEL + ori r20,r20,MSR_EE /* Always hard enabled */ + FIX_SRR1(r20,r22) + mtspr SRR0,r24 + mtspr SRR1,r20 + SYNC + RFI + +/* + * Disable FP for the task which had the FPU previously, + * and save its floating-point registers in its thread_struct. + * Enables the FPU for use in the kernel on return. + * On SMP we know the fpu is free, since we give it up every + * switch. -- Cort + */ +load_up_fpu: + mfmsr r5 + ori r5,r5,MSR_FP + clrldi r5,r5,1 /* turn off 64-bit mode */ + SYNC + MTMSRD(r5) /* enable use of fpu now */ + SYNC +/* + * For SMP, we don't do lazy FPU switching because it just gets too + * horrendously complex, especially when a task switches from one CPU + * to another. Instead we call giveup_fpu in switch_to. + */ +#ifndef CONFIG_SMP + lis r3,last_task_used_math@ha + lwz r4,last_task_used_math@l(r3) + cmpi 0,r4,0 + beq 1f + addi r4,r4,THREAD /* want THREAD of last_task_used_math */ + SAVE_32FPRS(0, r4) + mffs fr0 + stfd fr0,THREAD_FPSCR-4(r4) /* could little fault */ + lwz r5,PT_REGS(r4) /* could little fault */ + lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) /* could little fault */ + li r20,MSR_FP|MSR_FE0|MSR_FE1 + andc r4,r4,r20 /* disable FP for previous task */ + stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) /* could little fault */ +1: +#endif /* CONFIG_SMP */ + /* enable use of FP after return */ + ori r23,r23,MSR_FP|MSR_FE0|MSR_FE1 + mfspr r5,SPRG3 /* current task's THREAD (phys) */ + lfd fr0,THREAD_FPSCR-4(r5) /* could little fault */ + mtfsf 0xff,fr0 + REST_32FPRS(0, r5) /* could little fault */ +#ifndef CONFIG_SMP + subi r4,r5,THREAD + stw r4,last_task_used_math@l(r3) +#endif /* CONFIG_SMP */ + + /* No more little faults after this point */ + /* we can free the bolted stack */ + + subi r3,r21,BOLTEDSTACKSIZE-INT_FRAME_SIZE /* Point to stack hdr */ + mfspr r4,SPRG1 /* Get Paca address */ + lwz r5,PACABOLTEDSTACK(r4) /* Get head of list */ + stw r5,BOLTEDSTACKNEXT(r3) /* Store in this stack */ + stw r3,PACABOLTEDSTACK(r4) /* Make this stack head of list */ + + /* restore registers and return */ + lwz r3,_CCR(r21) + lwz r4,_LINK(r21) + mtcrf 0xff,r3 + mtlr r4 + + REST_GPR(1, r21) + REST_4GPRS(3, r21) + /* we haven't used ctr or xer */ + mtspr SRR1,r23 + mtspr SRR0,r22 + REST_GPR(20, r21) + REST_2GPRS(22, r21) + REST_GPR(24, r21) + lwz r21,GPR21(r21) + SYNC + RFI + +/* + * FP unavailable trap from kernel - print a message, but let + * the task use FP in the kernel until it returns to user mode. + */ +KernelFP: + lwz r3,_MSR(r1) + ori r3,r3,MSR_FP + stw r3,_MSR(r1) /* enable use of FP after return */ + lis r3,86f@h + ori r3,r3,86f@l + mr r4,r2 /* current */ + lwz r5,_NIP(r1) + bl printk + b ret_from_except +86: .string "floating point used in kernel (task=%p, pc=%x)\n" + .align 4 + +/* + * giveup_fpu(tsk) + * Disable FP for the task given as the argument, + * and save the floating-point registers in its thread_struct. + * Enables the FPU for use in the kernel on return. + */ + .globl giveup_fpu +giveup_fpu: + mfmsr r5 + ori r5,r5,MSR_FP + SYNC + mtmsr r5 /* enable use of fpu now */ + SYNC + cmpi 0,r3,0 + beqlr- /* if no previous owner, done */ + addi r3,r3,THREAD /* want THREAD of task */ + lwz r5,PT_REGS(r3) + cmpi 0,r5,0 + SAVE_32FPRS(0, r3) + mffs fr0 + stfd fr0,THREAD_FPSCR-4(r3) + beq 1f + lwz r4,_MSR-STACK_FRAME_OVERHEAD(r5) + li r3,MSR_FP|MSR_FE0|MSR_FE1 + andc r4,r4,r3 /* disable FP for previous task */ + stw r4,_MSR-STACK_FRAME_OVERHEAD(r5) +1: +#ifndef CONFIG_SMP + li r5,0 + lis r4,last_task_used_math@ha + stw r5,last_task_used_math@l(r4) +#endif /* CONFIG_SMP */ + blr + +#ifdef CONFIG_SMP +secondary_start: + /* get current */ + HMT_MEDIUM /* Set thread priority to MEDIUM */ + lis r2,current_set@h + ori r2,r2,current_set@l + slwi r24,r24,2 /* get current_set[cpu#] */ + lwzx r2,r2,r24 + + /* stack */ + addi r1,r2,TASK_UNION_SIZE-STACK_FRAME_OVERHEAD + li r0,0 + stw r0,0(r1) + + /* load up the MMU */ + bl load_up_mmu + + /* ptr to phys current thread */ + addi r4,r2,THREAD /* phys address of our thread_struct */ + rlwinm r4,r4,0,0,31 + mtspr SPRG3,r4 + + /* Set up address of Paca in current thread */ + lis r23,xPaca@ha + addi r23,r23,xPaca@l + /* r24 has CPU # * 4 at this point. The Paca is 2048 bytes + long so multiply r24 by 512 to index into the array of Pacas */ + slwi r24,r24,9 + add r23,r23,r24 + rlwinm r23,r23,0,0,31 + mtspr SPRG1,r23 + + li r3,0 + stw r3,PACAKSAVE(r23) /* 0 => r1 has kernel sp */ + + stb r3,PACAPROCENABLED(r23) /* Soft disabled */ + + /* enable MMU and jump to start_secondary */ + + li r4,MSR_KERNEL + ori r4,r4,MSR_EE /* Hard enabled */ + lis r3,start_secondary@h + ori r3,r3,start_secondary@l + mtspr SRR0,r3 + FIX_SRR1(r4,r3) + mtspr SRR1,r4 + SYNC + RFI +#endif /* CONFIG_SMP */ + +/* + * Load stuff into the MMU. Intended to be called with + * IR=0 and DR=0. + */ +load_up_mmu: + li r0,16 /* load up segment register values */ + mtctr r0 /* for context 0 */ + lis r3,0x2000 /* Ku = 1, VSID = 0 */ + li r4,0 +3: mtsrin r3,r4 + addi r3,r3,1 /* increment VSID */ + addis r4,r4,0x1000 /* address of next segment */ + bdnz 3b + blr + + __ENDBOLTED + +/* + * This is where the main kernel code starts. + */ +start_here: + + /* ptr to current */ + + lis r2,init_task_union@h + ori r2,r2,init_task_union@l + + /* Set up for using our exception vectors */ + + addi r4,r2,THREAD /* init task's THREAD */ + rlwinm r4,r4,0,0,31 + mtspr SPRG3,r4 + + /* Get address of Paca for processor 0 */ + lis r11,xPaca@ha + addi r11,r11,xPaca@l + rlwinm r11,r11,0,0,31 + mtspr SPRG1,r11 + + li r3,0 + stw r3,PACAKSAVE(r11) /* 0 => r1 has kernel sp */ + + stb r3,PACAPROCENABLED(r11) /* Soft disabled */ + + /* Clear out the BSS */ + + lis r11,_end@ha + addi r11,r11,_end@l + lis r8,__bss_start@ha + addi r8,r8,__bss_start@l + subf r11,r8,r11 + addi r11,r11,3 + rlwinm. r11,r11,30,2,31 + beq 2f + addi r8,r8,-4 + mtctr r11 + li r0,0 +3: stwu r0,4(r8) + bdnz 3b +2: + /* stack */ + + addi r1,r2,TASK_UNION_SIZE + li r0,0 + stwu r0,-STACK_FRAME_OVERHEAD(r1) +/* + * Decide what sort of machine this is and initialize the MMU. + */ + mr r3,r31 + mr r4,r30 + mr r5,r29 + mr r6,r28 + mr r7,r27 + li r6,0 /* No cmdline parameters */ + bl iSeries_init + bl MMU_init + + bl load_up_mmu + + li r4,MSR_KERNEL + ori r4,r4,MSR_EE /* Hard enabled */ + FIX_SRR1(r4,r5) + lis r3,start_kernel@h + ori r3,r3,start_kernel@l + mtspr SRR0,r3 + mtspr SRR1,r4 + SYNC + RFI /* ensure correct MSR and jump to + start_kernel */ + + __BOLTEDCODE + +do_hash_page_ISI: + li r4,0 +do_hash_page_DSI: + /* Create the access parm */ + rlwimi r4,r23,32-13,30,30 /* Insert MSR_PR as _PAGE_USER */ + ori r4,r4,1 /* add _PAGE_PRESENT */ + + mfspr r21,SPRG3 /* Get current thread */ + addi r2,r21,-THREAD /* Fix "current" pointer */ + + mflr r21 /* Save LR in r21 */ + /* r21 restored later from r1 */ + + /* + * We hard enable here (but first soft disable) so that the hash_page + * code can spin on the hash_table_lock without problem on a shared + * processor + */ + li r0,0 + stb r0,PACAPROCENABLED(r20) /* Soft disable */ + + mfmsr r0 + ori r0,r0,MSR_EE + mtmsr r0 /* Hard enable */ + + /* + * r3 contains the faulting address + * r4 contains the required access permissions + * + * at return r3 = 0 for success + */ + + bl hash_page /* build hpte if possible */ + + /* + * Now go back to hard disabled + */ + mfmsr r0 + li r4,0 + ori r4,r4,MSR_EE + andc r0,r0,r4 + mtmsr r0 /* Hard disable */ + + lwz r0,_SOFTE(r1) + stb r0,PACAPROCENABLED(r20) /* Restore soft enable/disable */ + + mtlr r21 /* restore LR */ + mr r21,r1 /* restore r21 */ + + or. r3,r3,r3 /* Check return code */ + bnelr /* Return to DSI or ISI on failure */ + + /* + * The hpte has been created/updated. Release the bolted + * stack and retry the faulting instruction. + */ + +fault_exit: + + subi r3,r21,BOLTEDSTACKSIZE-INT_FRAME_SIZE /* Point to stack hdr */ + mfspr r4,SPRG1 /* Get Paca address */ + lwz r5,PACABOLTEDSTACK(r4) /* Get head of list */ + stw r5,BOLTEDSTACKNEXT(r3) /* Store in this stack */ + stw r3,PACABOLTEDSTACK(r4) /* Make this stack head of list */ + + lwz r3,_CCR(r21) + lwz r4,_LINK(r21) + lwz r5,_CTR(r21) + lwz r6,_XER(r21) + mtcrf 0xff,r3 + mtlr r4 + mtctr r5 + mtspr XER,r6 + REST_8GPRS(0, r21) + REST_4GPRS(8, r21) + REST_2GPRS(12, r21) + FIX_SRR1(r23,r20) + mtspr SRR1,r23 + mtspr SRR0,r22 + lwz r20,GPR20(r21) + lwz r22,GPR22(r21) + lwz r23,GPR23(r21) + lwz r21,GPR21(r21) + RFI + +/* + * Set up the segment registers for a new context. + * context in r3 + */ +_GLOBAL(set_context) + + mfspr r4,SPRG1 /* Get Paca */ + li r5,0 /* Clear context overflow flag */ + stb r5,PACACONTEXTOVERFLOW(r4) + + lis r4,set_context_count@ha + lwz r5,set_context_count@l(r4) + addi r5,r5,1 + stw r5,set_context_count@l(r4) + + rlwinm r3,r3,4,8,27 /* VSID = context << 4 */ + addis r3,r3,0x6000 /* Set Ks, Ku bits */ + li r0,12 /* TASK_SIZE / SEGMENT_SIZE */ + mtctr r0 + li r4,0 +3: mtsrin r3,r4 + addi r3,r3,1 /* next VSID */ + addis r4,r4,0x1000 /* address of next segment */ + bdnz 3b +/* + * Reload the last four segment registers because they + * might have been clobbered by the hypervisor if we + * are running on a shared processor + */ + lis r3,0x2000 /* Set Ku = 1 */ + addi r3,r3,12 /* Set VSID = 12 */ + lis r4,0xC000 /* Set SR = 12 */ + li r0,4 /* Load regs C, D, E and F */ + mtctr r0 +4: mtsrin r3,r4 + addi r3,r3,1 /* next VSID */ + addis r4,r4,0x1000 /* address of next segment */ + bdnz 4b + + SYNC + blr + +/* Hypervisor call + * + * Invoke the iSeries hypervisor (PLIC) via the System Call instruction. + * Parameters are passed to this routine in registers r3 - r10 and are + * converted to 64-bit by combining registers. eg. r3 <- r3 + * r4 <- r5,r6, r5 <- r7,r8, r6 <- r9,r10 + * + * r3 contains the HV function to be called + * r5,r6 contain the first 64-bit operand + * r7,r8 contain the second 64-bit operand + * r9,r10 contain the third 64-bit operand + * caller's stack frame +8 contains the fourth 64-bit operand + * caller's stack frame +16 contains the fifth 64-bit operand + * caller's stack frame +24 contains the sixth 64-bit operand + * caller's stack frame +32 contains the seventh 64-bit operand + * + */ + +_GLOBAL(HvCall) +_GLOBAL(HvCall0) +_GLOBAL(HvCall1) +_GLOBAL(HvCall2) +_GLOBAL(HvCall3) +_GLOBAL(HvCall4) +_GLOBAL(HvCall5) +_GLOBAL(HvCall6) +_GLOBAL(HvCall7) + /* + * Stack a frame and save one reg so we can hang on to + * the old MSR + */ + stwu r1,-64(r1) + stw r31,60(r1) + + /* + * The hypervisor assumes CR fields 0-4 are volatile, but + * gcc assumes CR fields 2-7 are non-volatile. + * We must save and restore the CR here + */ + mfcr r31 + stw r31,56(r1) + + /* Before we can convert to using 64-bit registers we must + * soft disable external interrupts as the interrupt handlers + * don't preserve the high half of the registers + */ + + mfspr r11,SPRG1 /* Get the Paca pointer */ + lbz r31,PACAPROCENABLED(r11) /* Get soft enable/disable flag */ + li r0,0 + stb r0,PACAPROCENABLED(r11) /* Soft disable */ + + /* Now it is safe to operate on 64-bit registers + * + * Format the operands into the 64-bit registers + */ + rldicr r5,r5,32,31 /* r5 = r5 << 32 */ + rldicl r6,r6,0,32 /* r6 = r6 & 0x00000000ffffffff */ + or r4,r5,r6 /* r4 = r5 | r6 */ + rldicr r7,r7,32,31 /* r7 = r7 << 32 */ + rldicl r8,r8,0,32 /* r8 = r8 & 0x00000000ffffffff */ + or r5,r7,r8 /* r5 = r7 | r8 */ + rldicr r9,r9,32,31 /* r9 = r9 << 32 */ + rldicl r10,r10,0,32 /* r10 = r10 & 0x00000000ffffffff */ + or r6,r9,r10 /* r6 = r9 | r10 */ + ld r7,72(r1) /* Get fourth u64 parameter */ + ld r8,80(r1) /* Get fifth u64 parameter */ + ld r9,88(r1) /* Get sixth u64 parameter */ + ld r10,96(r1) /* Get seventh u64 parameter */ + + /* + * Extract the hypervisor function call number from R3 + * and format it into the 64-bit R3. + */ + rldicr r0,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */ + rldicl r3,r3,0,48 /* r3 = r3 & 0x000000000000ffff */ + or r3,r3,r0 /* r3 = r3 | r0 */ + + /* + * r0 = 0xffffffffffffffff indicates a hypervisor call + */ + li r0,-1 /* r1 = 0xffffffffffffffff */ + + /* Invoke the hypervisor via the System Call instruction */ + + sc + + /* Return value in 64-bit R3 + * format it into R3 and R4 + */ + rldicl r4,r3,0,32 /* r4 = r3 & 0x00000000ffffffff */ + rldicl r3,r3,32,32 /* r3 = (r3 << 32) & 0x00000000ffffffff */ + + /* While we were running in the hypervisor, a decrementer or + * external interrupt may have occured. If we are about to + * enable here, we must check for these and process them + */ + + cmpi 0,r31,0 /* check if going to enable */ + beq 1f /* skip checks if staying disabled */ + + /* Save r3, r4 and LR */ + stw r3,52(r1) + stw r4,48(r1) + mflr r3 + stw r3,44(r1) + + /* enable and check for decrementers/lpEvents */ + mr r3,r31 + bl __restore_flags + + /* Restore r3, r4 and LR */ + lwz r3,44(r1) + mtlr r3 + lwz r3,52(r1) + lwz r4,48(r1) + +1: + /* + * Unstack the frame and restore r31 and the CR + */ + lwz r31,56(r1) + mtcrf 0xff,r31 + lwz r31,60(r1) + lwz r1,0(r1) + + blr + +/* Hypervisor call with return data + * + * Invoke the iSeries hypervisor (PLIC) via the System Call instruction. + * The Hv function ID is passed in r3 + * The address of the return data structure is passed in r4 + * Parameters are passed to this routine in registers r5 - r10 and are + * converted to 64-bit by combining registers. eg. r3 <- r3 + * r4 <- r5,r6, r5 <- r7,r8, r6 <- r9,r10 + * + * r3 contains the HV function to be called + * r4 contains the address of the return data structure + * r5,r6 contain the first 64-bit operand + * r7,r8 contain the second 64-bit operand + * r9,r10 contain the third 64-bit operand + * caller's stack frame +8 contains the fourth 64-bit operand + * caller's stack frame +16 contains the fifth 64-bit operand + * caller's stack frame +24 contains the sixth 64-bit operand + * caller's stack frame +32 contains the seventh 64-bit operand + * + */ + +_GLOBAL(HvCallRet16) +_GLOBAL(HvCall0Ret16) +_GLOBAL(HvCall1Ret16) +_GLOBAL(HvCall2Ret16) +_GLOBAL(HvCall3Ret16) +_GLOBAL(HvCall4Ret16) +_GLOBAL(HvCall5Ret16) +_GLOBAL(HvCall6Ret16) +_GLOBAL(HvCall7Ret16) + + /* + * Stack a frame and save two regs so we can hang on to the + * old MSR and the return data address + */ + stwu r1,-64(r1) + stw r31,60(r1) + stw r30,56(r1) + mr r30,r4 /* Save return data address */ + + /* + * The hypervisor assumes CR fields 0-4 are volatile, but + * gcc assumes CR fields 2-7 are non-volatile. + * We must save and restore the CR here + */ + mfcr r31 + stw r31,52(r1) + + /* Before we can convert to using 64-bit registers we must + * soft disable external interrupts as the interrupt handlers + * don't preserve the high half of the registers + */ + + mfspr r11,SPRG1 /* Get the Paca pointer */ + lbz r31,PACAPROCENABLED(r11) /* Get soft enable/disable flag */ + li r0,0 + stb r0,PACAPROCENABLED(r11) /* Soft disable */ + + /* Now it is safe to operate on 64-bit registers + */ + + /* + * Format the operands into the 64-bit registers + */ + + rldicr r5,r5,32,31 /* r5 = r5 << 32 */ + rldicl r6,r6,0,32 /* r6 = r6 & 0x00000000ffffffff */ + or r4,r5,r6 /* r4 = r5 | r6 */ + rldicr r7,r7,32,31 /* r7 = r7 << 32 */ + rldicl r8,r8,0,32 /* r8 = r8 & 0x00000000ffffffff */ + or r5,r7,r8 /* r5 = r7 | r8 */ + rldicr r9,r9,32,31 /* r9 = r9 << 32 */ + rldicl r10,r10,0,32 /* r10 = r10 & 0x00000000ffffffff */ + or r6,r9,r10 /* r6 = r9 | r10 */ + ld r7,76(r1) /* Get fourth u64 parameter */ + ld r8,84(r1) /* Get fifth u64 parameter */ + ld r9,92(r1) /* Get sixth u64 parameter */ + ld r10,100(r1) /* Get seventh u64 parameter */ + + /* + * Extract the hypervisor function call number from R3 + * and format it into the 64-bit R3. + */ + rldicr r0,r3,32,15 /* r4 = (r3 << 32) & 0xffff000000000000 */ + rldicl r3,r3,0,48 /* r3 = r3 & 0x000000000000ffff */ + or r3,r3,r0 /* r3 = r3 | r4 */ + + /* + * r0 = 0xffffffffffffffff indicates a hypervisor call + */ + li r0,-1 /* r1 = 0xffffffffffffffff */ + + /* Invoke the hypervisor via the System Call instruction */ + + sc + + /* Return values in 64-bit R3, R4, R5 and R6 + * place R3 and R4 into data structure, R5 into R3,R4 + */ + + std r3,0(r30) /* Save returned data */ + std r4,8(r30) + + rldicl r4,r5,0,32 /* r4 = r5 & 0x00000000ffffffff */ + rldicl r3,r5,32,32 /* r3 = (r5 << 32) & 0x00000000ffffffff */ + + /* While we were running in the hypervisor, a decrementer or + * external interrupt may have occured. If we are about to + * enable here, we must check for these and process them + */ + + cmpi 0,r31,0 /* check if going to enable */ + beq 1f /* skip checks if staying disabled */ + + /* Save r3, r4 and LR */ + stw r3,48(r1) + stw r4,44(r1) + mflr r3 + stw r3,40(r1) + + /* enable and check for decrementers/lpEvents */ + mr r3,r31 + bl __restore_flags + + lwz r3,40(r1) + mtlr r3 + lwz r3,48(r1) + lwz r4,44(r1) + +1: + /* + * Unstack the frame and restore r30, r31 and CR + */ + lwz r31,52(r1) + mtcrf 0xff,r31 + lwz r30,56(r1) + lwz r31,60(r1) + lwz r1,0(r1) + + blr + + +/* Hypervisor call (use no stack) + * + * These functions must be called with interrupts soft disabled. + * The caller is responsible for saving the non-volatile CR + * The operands should already be formatted into the 64-bit registers + * + * Invoke the iSeries hypervisor (PLIC) via the System Call instruction. + * + * r3 contains the HV function to be called + * r4 contains the first 64-bit operand + * r5 contains the second 64-bit operand + * r6 contains the third 64-bit operand + * r7 contains the fourth 64-bit operand + * r8 contains the fifth 64-bit operand + * r9 contains the sixth 64-bit operand + * r10 contains the seventh 64-bit operand + * + * data is returned in 64-bit registers r3-r6 + * + */ + +_GLOBAL(HvXCall) +_GLOBAL(HvXCall0) +_GLOBAL(HvXCall1) +_GLOBAL(HvXCall2) +_GLOBAL(HvXCall3) + /* + * Extract the hypervisor function call number from R3 + * and format it into the 64-bit R3. + */ + rldicr r0,r3,32,15 /* r0 = (r3 << 32) & 0xffff000000000000 */ + rldicl r3,r3,0,48 /* r3 = r3 & 0x000000000000ffff */ + or r3,r3,r0 /* r3 = r3 | r0 */ + + /* + * r0 = 0xffffffffffffffff indicates a hypervisor call + */ + li r0,-1 /* r1 = 0xffffffffffffffff */ + + /* Invoke the hypervisor via the System Call instruction */ + + sc + + blr + + +/* + * Flush the entry for a particular page from the hash table. + * + * flush_hash_page(unsigned context, unsigned long va) + * + * flush_hash_page must not touch any "non-bolted" pages + * "bolted" pages are the kernel text (code) and data (static) + * everything else is "non-bolted" in the HPT + * + * It must be disabled when it holds the hash_table_lock + * to prevent an interrupt (external or decrementer) which + * could then take a hpte missing fault which would result + * in a deadlock + * On uniprocessors it still must be disabled to prevent + * an interrupt (external or decrementer) which could + * then take a hpte missing fault (and which would update + * the HPT) + * + * The 'context' is a number which represents the set of + * 16 vsids assigned to this process. context * 16 is + * the first of the 16 vsids. + */ + + +_GLOBAL(flush_hash_page) + + stwu r1,-64(r1) + mfcr r0 /* Save CR because the hypervisor doesn't */ + stw r0,60(r1) + + lis r9,flush_hash_page_count@ha + lwz r8,flush_hash_page_count@l(r9) + addi r8,r8,1 + stw r8,flush_hash_page_count@l(r9) + + mfspr r7,SPRG1 /* Get address of Paca */ + lbz r8,PACAPROCENABLED(r7) + li r9,0 + stb r9,PACAPROCENABLED(r7) + + stw r8,56(r1) /* Save original enable/disable state */ + +#ifdef CONFIG_SMP + lis r9,hash_table_lock@h + ori r9,r9,hash_table_lock@l + lwz r8,PROCESSOR(r2) + oris r8,r8,8 +10: lwarx r7,0,r9 + cmpi 0,r7,0 + bne- 10b + stwcx. r8,0,r9 + bne- 10b + eieio +#endif /* CONFIG_SMP */ + + /* Don't touch the stack after getting the hash_table_lock */ + + rldicl r11,r4,36,60 /* get esid */ + rldicl r9,r4,52,48 /* get page id */ + cmpldi 0,r11,7 /* Check if user or kernel space */ + bgt 1f /* skip adding context if kernel space */ + rldicl r0,r3,4,28 /* context * 16 */ + or r11,r11,r0 /* compute vsid */ +1: + sldi r4,r11,16 /* vsid in 64-bit r4 */ + or r4,r4,r9 /* vpn = vsid || pageid */ + + lis r3,0x8004 /* HvCallHpt */ + sldi r3,r3,32 /* Put in position */ + ori r3,r3,13 /* findValid */ + li r0,-1 /* Indicate hypervisor call */ + + sc /* HvCallHpt_findValid */ + + andi. r3,r3,1 /* Valid hpte found? */ + beq 20f /* done if no valid hpte */ + + mr r4,r5 /* Move hpte index */ + lis r3,0x8004 /* HvCallHpt */ + sldi r3,r3,32 /* Put in position */ + ori r3,r3,8 /* invalidateNoFlushICache */ + li r0,-1 /* Indicate hypervisor call */ + + sc /* HvCallHpt_invalidateNoFlushICache */ + +20: + +#ifdef CONFIG_SMP + li r0,0 + lis r3,hash_table_lock@ha + stw r0,hash_table_lock@l(r3) +#endif /* CONFIG_SMP */ + + /* Now its okay to touch the stack again */ + + mfspr r7,SPRG1 /* get Paca address */ + lwz r8,56(r1) /* get enabled/disabled */ + stb r8,PACAPROCENABLED(r7) + + lwz r0,60(r1) /* get original CR */ + mtcrf 0xff,r0 + + addi r1,r1,64 /* unstack the frame */ + + blr + + +/* + * Flush the entries for a range of pages from the hash table. + * + * flush_hash_range( u64 lowVa, u64 highVa) + * + * flush_hash_range must not touch any "non-bolted" pages after + * getting the hash_table_lock. + * "bolted" pages are the kernel text (code) and data (static) + * everything else is "non-bolted" in the HPT + * + * It must be disabled when it holds the hash_table_lock + * to prevent an interrupt (external or decrementer) which + * could then take a hpte missing fault which would result + * in a deadlock + * On uniprocessors it still must be disabled to prevent + * an interrupt (external or decrementer) which could + * then take a hpte missing fault (and which would update + * the HPT) + * + */ + + +_GLOBAL(flush_hash_range) + + stwu r1,-64(r1) + mflr r0 + stmw r26,40(r1) + stw r0,68(r1) + mfcr r0 /* Save CR because the hypervisor doesn't */ + stw r0,32(r1) + + mr r26,r7 /* Save # pacas to flag for context overflow */ + + lis r9,flush_hash_range_count@ha + lwz r8,flush_hash_range_count@l(r9) + addi r8,r8,1 + stw r8,flush_hash_range_count@l(r9) + + mfspr r7,SPRG1 /* Get address of Paca */ + lbz r8,PACAPROCENABLED(r7) + li r9,0 + stb r9,PACAPROCENABLED(r7) + + stw r8,36(r1) /* Save original enable/disable state */ + + rldicr r3,r3,32,31 /* Save r3,r4 (first parm) */ + rldicl r4,r4,0,32 + or r27,r3,r4 + + rldicr r5,r5,32,31 /* Save r5,r6 (second parm) */ + rldicl r6,r6,0,32 + or r28,r5,r6 + + lis r29,flush_hash_range_hv_evicts@ha + lis r30,flush_hash_range_hv_finds@ha + + li r31,0 /* r31 is hpte index */ + +#ifdef CONFIG_SMP + lis r9,hash_table_lock@h + ori r9,r9,hash_table_lock@l + lwz r8,PROCESSOR(r2) + oris r8,r8,8 +10: lwarx r7,0,r9 + cmpi 0,r7,0 + bne- 10b + stwcx. r8,0,r9 + bne- 10b + eieio + + lis r8,xPaca@ha + addi r8,r8,xPaca@l /* Address the Paca array */ + + li r9,1 + +1: cmpi 0,r26,0 /* Test if any pacas left to update */ + beq 1f /* If zero, none left */ + + stb r9,PACACONTEXTOVERFLOW(r8) + addi r8,r8,PACA_STRUCT_SIZE + addi r26,r26,-1 + b 1b + +#endif /* CONFIG_SMP */ + + mfmsr r9 + li r4,0 + ori r4,r4,MSR_EE + andc r9,r9,r4 + mtmsr r9 + + /* Don't touch the stack after getting the hash_table_lock */ +1: + lwz r9,flush_hash_range_hv_finds@l(r30) + addi r9,r9,1 + stw r9,flush_hash_range_hv_finds@l(r30) + + mr r4,r31 + li r5,0 + li r6,0 + lis r3,0x8004 /* HvCallHpt */ + sldi r3,r3,32 /* Put into position */ + ori r3,r3,12 /* findNextValid */ + li r0,-1 + + sc + + andi. r0,r3,1 /* Check if valid hpte found */ + beq- 3f /* Branch if no valid hpte */ + mr r31,r5 /* remember hpte index */ + srdi r4,r31,3 /* group = hpteindex >> 3 */ + andi. r0,r3,2 /* Check if secondary hash */ + beq+ 4f /* Branch if primary group */ + li r0,0 + orc r4,r0,r4 /* group = ~group */ +4: srdi r5,r3,12 /* vsid */ + xor r6,r5,r4 /* vsid ^ group */ + andi. r6,r6,0x7ff /* (vsid ^ group) & 0x7ff */ + rldicl r7,r3,57,59 /* api */ + sldi r7,r7,11 /* api << 11 */ + or r6,r6,r7 /* pi = api | (vsid ^ group) & 0x7ff */ + sldi r8,r5,16 /* vsid << 16 */ + add r8,r8,r6 /* vpn */ + sldi r8,r8,12 /* va */ + cmpld 0,r8,r27 /* is va >= lVa */ + blt 2f + cmpld 0,r8,r28 /* is va <= hVa */ + bgt 2f + + lwz r9,flush_hash_range_hv_evicts@l(r29) + addi r9,r9,1 + stw r9,flush_hash_range_hv_evicts@l(r29) + + mr r4,r31 + li r5,0 + li r6,0 + lis r3,0x8004 /* HvCallHpt */ + sldi r3,r3,32 /* Put into position */ + ori r3,r3,18 /* invalidateSetSwBitsGet */ + li r0,-1 + + sc + +2: + addi r31,r31,1 /* ++hpteindex */ + b 1b /* Loop until no valid hpte */ + +3: + mfmsr r9 + ori r9,r9,MSR_EE + mtmsr r9 + +#ifdef CONFIG_SMP + li r0,0 + lis r3,hash_table_lock@ha + stw r0,hash_table_lock@l(r3) +#endif /* CONFIG_SMP */ + + /* Now its okay to touch the stack again */ + + mfspr r7,SPRG1 /* get Paca address */ + lwz r8,36(r1) /* get enabled/disabled */ + stb r8,PACAPROCENABLED(r7) + + lwz r0,32(r1) /* get original CR */ + mtcrf 0xff,r0 + + lmw r26,40(r1) + + addi r1,r1,64 /* unstack the frame */ + + blr + + + +### +### extern void abort(void) +### +### Invoke the hypervisor to kill the partition. +### + +_GLOBAL(abort) + + + __ENDBOLTED + +/* + * We put a few things here that have to be page-aligned. + * This stuff goes at the beginning of the data segment, + * which is page-aligned. + */ + .data + .globl sdata +sdata: + +/* + * Bolted stack required for handling hpte faults + * Free up the extra space later + */ + __BOLTEDDATA + .align 8 + .globl _start_boltedStacks +_start_boltedStacks: + .space 32768 + .globl _end_boltedStacks +_end_boltedStacks: + __ENDBOLTED + + .globl empty_zero_page +empty_zero_page: + .space 4096 + + .globl swapper_pg_dir +swapper_pg_dir: + .space 4096 + +/* + * This space gets a copy of optional info passed to us by the bootstrap + * Used to pass parameters into the kernel like root=/dev/sda1, etc. + */ + .globl cmd_line +cmd_line: + .space 512 diff -Nru a/arch/ppc/kernel/iSeries_setup.c b/arch/ppc/kernel/iSeries_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/iSeries_setup.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,783 @@ +/* + * + * + * Copyright (c) 2000 Mike Corrigan + * Copyright (c) 1999-2000 Grant Erickson + * + * Module name: iSeries_setup.c + * + * Description: + * Architecture- / platform-specific boot-time initialization code for + * the IBM iSeries LPAR. Adapted from original code by Grant Erickson and + * code by Gary Thomas, Cort Dougan , and Dan Malek + * . + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include "iSeries_setup.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pci.h" + +/* Function Prototypes */ + +extern void abort(void); +static void build_iSeries_Memory_Map( void ); +static void setup_iSeries_cache_sizes( void ); +static void init_bolted_stacks( void ); +extern void iSeries_pci_Initialize(void); +extern struct pci_ops iSeries_pci_ops; + +/* Global Variables */ + +unsigned short iSeries_icache_line_size = 0; +unsigned short iSeries_dcache_line_size = 0; +unsigned short iSeries_icache_lines_per_page = 0; +unsigned short iSeries_dcache_lines_per_page = 0; +unsigned short iSeries_log_icache_line_size = 0; +unsigned short iSeries_log_dcache_line_size = 0; + +unsigned long procFreqHz = 0; +unsigned long procFreqMhz = 0; +unsigned long procFreqMhzHundreths = 0; + +unsigned long tbFreqHz = 0; +unsigned long tbFreqMhz = 0; +unsigned long tbFreqMhzHundreths = 0; + +extern char _start_boltedStacks[]; +extern char _end_boltedStacks[]; + +extern unsigned long embedded_sysmap_start; +extern unsigned long embedded_sysmap_end; + +extern unsigned long sysmap; +extern unsigned long sysmap_size; + +/* + * void __init iSeries_init() + * + * Description: + * This routine... + * + * Input(s): + * r3 - Optional pointer to a board information structure. + * r4 - Optional pointer to the physical starting address of the init RAM + * disk. + * r5 - Optional pointer to the physical ending address of the init RAM + * disk. + * r6 - Optional pointer to the physical starting address of any kernel + * command-line parameters. + * r7 - Optional pointer to the physical ending address of any kernel + * command-line parameters. + * + * Output(s): + * N/A + * + * Returns: + * N/A + * + */ + +extern int rd_size; // Defined in drivers/block/rd.c +extern u64 next_jiffy_update_tb[]; +extern u64 get_tb64(void); + +void __init +iSeries_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + +#if defined(CONFIG_BLK_DEV_INITRD) + /* + * If the init RAM disk has been configured and there is + * a non-zero starting address for it, set it up + */ + + if ( xNaca.xRamDisk ) { + initrd_start = xNaca.xRamDisk + KERNELBASE; + initrd_end = initrd_start + xNaca.xRamDiskSize * PAGE_SIZE; + initrd_below_start_ok = 1; // ramdisk in kernel space + ROOT_DEV = MKDEV( RAMDISK_MAJOR, 0 ); + + if ( ((rd_size*1024)/PAGE_SIZE) < xNaca.xRamDiskSize ) + rd_size = (xNaca.xRamDiskSize*PAGE_SIZE)/1024; + } else + +#endif /* CONFIG_BLK_DEV_INITRD */ +#if CONFIG_VIODASD_IDE + { + ROOT_DEV = MKDEV( IDE0_MAJOR, 1 ); + } +#elif defined(CONFIG_VIODASD) + { + ROOT_DEV = MKDEV( VIODASD_MAJOR, 1 ); + } +#endif /* CONFIG_VIODASD_IDE */ + + /* If an embedded System.map has been added to the kernel, + * set it up. + */ + + if ( embedded_sysmap_start ) { + sysmap = embedded_sysmap_start + KERNELBASE; + sysmap_size = embedded_sysmap_end - embedded_sysmap_start; + } + + /* Copy the kernel command line arguments to a safe place. */ + + if (r6) { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } + + /* Initialize the table which translate Linux physical addresses to + * iSeries absolute addresses + */ + + build_iSeries_Memory_Map(); + + init_bolted_stacks(); + + setup_iSeries_cache_sizes(); + + /* Initialize machine-dependency vectors */ + + ppc_md.setup_arch = iSeries_setup_arch; + ppc_md.setup_residual = iSeries_setup_residual; + ppc_md.get_cpuinfo = iSeries_get_cpuinfo; + ppc_md.irq_cannonicalize = NULL; + ppc_md.init_IRQ = iSeries_init_IRQ; + ppc_md.get_irq = iSeries_get_irq; + ppc_md.init = NULL; + + ppc_md.restart = iSeries_restart; + ppc_md.power_off = iSeries_power_off; + ppc_md.halt = iSeries_halt; + + ppc_md.time_init = NULL; + ppc_md.set_rtc_time = iSeries_set_rtc_time; + ppc_md.get_rtc_time = iSeries_get_rtc_time; + ppc_md.calibrate_decr = iSeries_calibrate_decr; + ppc_md.progress = iSeries_progress; + ppc_md.find_end_of_memory = iSeries_find_end_of_memory; + + ppc_md.kbd_setkeycode = NULL; + ppc_md.kbd_getkeycode = NULL; + ppc_md.kbd_translate = NULL; + ppc_md.kbd_unexpected_up = NULL; + ppc_md.kbd_leds = NULL; + ppc_md.kbd_init_hw = NULL; +#ifdef CONFIG_PCI + ppc_md.pcibios_fixup_bus = iSeries_fixup_bus; + ppc_md.pcibios_fixup = iSeries_fixup; +#else + ppc_md.pcibios_fixup_bus = NULL; + ppc_md.pcibios_fixup = NULL; +#endif /* CONFIG_PCI */ + +#if defined(CONFIG_MAGIC_SYSRQ) + ppc_md.ppc_kbd_sysrq_xlate = NULL; +#endif + + + // Associate Lp Event Queue 0 with processor 0 + HvCallEvent_setLpEventQueueInterruptProc( 0, 0 ); + + { + // copy the command line parameter from the primary VSP + char *p, *q; + HvCallEvent_dmaToSp( cmd_line, + 2*64*1024, + 256, + HvLpDma_Direction_RemoteToLocal ); + p = q = cmd_line + 255; + while( p > cmd_line ) { + if ((*p == 0) || (*p == ' ') || (*p == '\n')) + --p; + else + break; + } + if ( p < q ) + *(p+1) = 0; + } + + next_jiffy_update_tb[0] = get_tb64(); + + iSeries_proc_early_init(); + mf_init(); + + iSeries_proc_callback( &pmc_proc_init ); + + viopath_init(); + + return; +} + +/* + * The iSeries may have very large memories ( > 128 GB ) and a partition + * may get memory in "chunks" that may be anywhere in the 2**52 real + * address space. The chunks are 256K in size. To map this to the + * memory model Linux expects, the iSeries specific code builds a + * translation table to translate what Linux thinks are "physical" + * addresses to the actual real addresses. This allows us to make + * it appear to Linux that we have contiguous memory starting at + * physical address zero while in fact this could be far from the truth. + * To avoid confusion, I'll let the words physical and/or real address + * apply to the Linux addresses while I'll use "absolute address" to + * refer to the actual hardware real address. + * + * build_iSeries_Memory_Map gets information from the Hypervisor and + * looks at the Main Store VPD to determine the absolute addresses + * of the memory that has been assigned to our partition and builds + * a table used to translate Linux's physical addresses to these + * absolute addresses. Absolute addresses are needed when + * communicating with the hypervisor (e.g. to build HPT entries) + */ + +static void __init build_iSeries_Memory_Map(void) +{ + u32 loadAreaFirstChunk, loadAreaLastChunk, loadAreaSize; + u32 nextPhysChunk; + u32 hptFirstChunk, hptLastChunk, hptSizeChunks; + u32 holeFirstChunk, holeSizeChunks; + u32 totalChunks,moreChunks; + u32 currChunk, thisChunk, absChunk; + u32 currDword; + u32 chunkBit; + u64 holeStart, holeEnd, holeSize; + u32 absAddrHi, absAddrLo; + u64 map; + struct IoHriMainStoreSegment4 * msVpd; + + // Get absolute address of our load area + // and map it to physical address 0 + // This guarantees that the loadarea ends up at physical 0 + // otherwise, it might not be returned by PLIC as the first + // chunks + + loadAreaFirstChunk = (u32)(itLpNaca.xLoadAreaAddr >> 18); + loadAreaSize = itLpNaca.xLoadAreaChunks; + + // Only add the pages already mapped here. + // Otherwise we might add the hpt pages + // The rest of the pages of the load area + // aren't in the HPT yet and can still + // be assigned an arbitrary physical address + if ( (loadAreaSize * 64) > HvPagesToMap ) + loadAreaSize = HvPagesToMap / 64; + + loadAreaLastChunk = loadAreaFirstChunk + loadAreaSize - 1; + + absAddrLo = loadAreaFirstChunk << 18; + absAddrHi = loadAreaFirstChunk >> 14; + + printk( "Mapping load area - physical addr = 0, absolute addr = %08x%08x\n", + absAddrHi, absAddrLo ); + printk( "Load area size %dK\n", loadAreaSize*256 ); + + for ( nextPhysChunk = 0; + nextPhysChunk < loadAreaSize; + ++nextPhysChunk ) { + msChunks[nextPhysChunk] = loadAreaFirstChunk+nextPhysChunk; + } + + // Get absolute address of our HPT and remember it so + // we won't map it to any physical address + + hptFirstChunk = (u32)(HvCallHpt_getHptAddress() >> 18 ); + hptSizeChunks = (u32)(HvCallHpt_getHptPages() >> 6 ); + hptLastChunk = hptFirstChunk + hptSizeChunks - 1; + absAddrLo = hptFirstChunk << 18; + absAddrHi = hptFirstChunk >> 14; + + printk( "HPT absolute addr = %08x%08x, size = %dK\n", + absAddrHi, absAddrLo, hptSizeChunks*256 ); + + // Determine if absolute memory has any + // holes so that we can interpret the + // access map we get back from the hypervisor + // correctly. + + msVpd = (struct IoHriMainStoreSegment4 *)xMsVpd; + holeStart = msVpd->nonInterleavedBlocksStartAdr; + holeEnd = msVpd->nonInterleavedBlocksEndAdr; + holeSize = holeEnd - holeStart; + + if ( holeSize ) { + holeStart = holeStart & 0x000fffffffffffff; + holeStart = holeStart >> 18; + holeFirstChunk = (u32)holeStart; + holeSize = holeSize >> 18; + holeSizeChunks = (u32)holeSize; + printk( "Main store hole: start chunk = %0x, size = %0x chunks\n", + holeFirstChunk, holeSizeChunks ); + } + else { + holeFirstChunk = 0xffffffff; + holeSizeChunks = 0; + } + + // Process the main store access map from the hypervisor + // to build up our physical -> absolute translation table + + totalChunks = (u32)HvLpConfig_getMsChunks(); + currChunk = 0; + currDword = 0; + moreChunks = totalChunks; + + while ( moreChunks ) { + map = HvCallSm_get64BitsOfAccessMap( itLpNaca.xLpIndex, + currDword ); + thisChunk = currChunk; + while ( map ) { + chunkBit = map >> 63; + map <<= 1; + if ( chunkBit ) { + --moreChunks; + absChunk = thisChunk; + if ( absChunk >= holeFirstChunk ) + absChunk += holeSizeChunks; + if ( ( ( absChunk < hptFirstChunk ) || + ( absChunk > hptLastChunk ) ) && + ( ( absChunk < loadAreaFirstChunk ) || + ( absChunk > loadAreaLastChunk ) ) ) { +// printk( "Mapping physical = %0x to absolute %0x for 256K\n", nextPhysChunk << 18, absChunk << 18 ); + msChunks[nextPhysChunk] = absChunk; + ++nextPhysChunk; + } + } + ++thisChunk; + } + ++currDword; + currChunk += 64; + } + + // main store size (in chunks) is + // totalChunks - hptSizeChunks + // which should be equal to + // nextPhysChunk + + totalLpChunks = nextPhysChunk; + +} + +/* + * Set up the variables that describe the cache line sizes + * for this machine. + */ + +static void __init setup_iSeries_cache_sizes(void) +{ + unsigned i,n; + iSeries_icache_line_size = xIoHriProcessorVpd[0].xInstCacheOperandSize; + iSeries_dcache_line_size = xIoHriProcessorVpd[0].xDataCacheOperandSize; + iSeries_icache_lines_per_page = PAGE_SIZE / iSeries_icache_line_size; + iSeries_dcache_lines_per_page = PAGE_SIZE / iSeries_dcache_line_size; + i = iSeries_icache_line_size; + n = 0; + while ((i=(i/2))) ++n; + iSeries_log_icache_line_size = n; + i = iSeries_dcache_line_size; + n = 0; + while ((i=(i/2))) ++n; + iSeries_log_dcache_line_size = n; + + printk( "D-cache line size = %d (log = %d)\n", + (unsigned)iSeries_dcache_line_size, + (unsigned)iSeries_log_dcache_line_size ); + printk( "I-cache line size = %d (log = %d)\n", + (unsigned)iSeries_icache_line_size, + (unsigned)iSeries_log_icache_line_size ); + +} + +static void __init init_bolted_stacks(void) +{ + struct BoltedStack * bs; + struct BoltedStack * b1, * b2; + unsigned i; + + bs = (struct BoltedStack *)_start_boltedStacks; + + for ( i=0; i= (unsigned long)_end_boltedStacks ) + break; + b1 = bs++; + b2 = bs++; + b1->head.next = b2; + b2->head.next = NULL; + xPaca[i].xBoltedStack = b1; + } +} + +int piranha_simulator = 0; + +/* + * Document me. + */ +void __init +iSeries_setup_arch(void) +{ + void * eventStack; + u32 procFreq; + u32 tbFreq; +// u32 evStackContigReal; +// u64 evStackReal; + + /* Setup the Lp Event Queue */ + + /* Associate Lp Event Queue 0 with processor 0 */ + +// HvCallEvent_setLpEventQueueInterruptProc( 0, 0 ); + + /* Allocate a page for the Event Stack + * The hypervisor wants the absolute real address, so + * we subtract out the KERNELBASE and add in the + * absolute real address of the kernel load area + */ + + eventStack = alloc_bootmem_pages( LpEventStackSize ); + + memset( eventStack, 0, LpEventStackSize ); + + /* Invoke the hypervisor to initialize the event stack */ + + HvCallEvent_setLpEventStack( 0, eventStack, LpEventStackSize ); + + /* Initialize fields in our Lp Event Queue */ + + xItLpQueue.xHSlicEventStackPtr = 0; + xItLpQueue.xSlicEventStackPtr = (char *)eventStack; + xItLpQueue.xHSlicCurEventPtr = 0; + xItLpQueue.xSlicCurEventPtr = (char *)eventStack; + xItLpQueue.xHSlicLastValidEventPtr = 0; + xItLpQueue.xSlicLastValidEventPtr = (char *)eventStack + + (LpEventStackSize - LpEventMaxSize); + xItLpQueue.xIndex = 0; + + if ( itLpNaca.xPirEnvironMode == 0 ) { + printk("Running on Piranha simulator\n"); + piranha_simulator = 1; + } + // Compute processor frequency + procFreq = ( 0x40000000 / (xIoHriProcessorVpd[0].xProcFreq / 1600) ); + procFreqHz = procFreq * 10000; + procFreqMhz = procFreq / 100; + procFreqMhzHundreths = procFreq - (procFreqMhz * 100 ); + + // Compute time base frequency + tbFreq = ( 0x40000000 / (xIoHriProcessorVpd[0].xTimeBaseFreq / 400) ); + tbFreqHz = tbFreq * 10000; + tbFreqMhz = tbFreq / 100; + tbFreqMhzHundreths = tbFreq - (tbFreqMhz * 100 ); + + printk("Max logical processors = %d\n", + itVpdAreas.xSlicMaxLogicalProcs ); + printk("Max physical processors = %d\n", + itVpdAreas.xSlicMaxPhysicalProcs ); + printk("Processor frequency = %lu.%02lu\n", + procFreqMhz, + procFreqMhzHundreths ); + printk("Time base frequency = %lu.%02lu\n", + tbFreqMhz, + tbFreqMhzHundreths ); + printk("Processor version = %x\n", + xIoHriProcessorVpd[0].xPVR ); + +#ifdef CONFIG_PCI + /* Initialize the flight recorder, global bus map and pci memory table */ + iSeries_pci_Initialize(); + + /* Setup the PCI controller list */ + iSeries_build_hose_list(); +#endif /* CONFIG_PCI */ +/* + // copy the command line parameter from the primary VSP + HvCallEvent_dmaToSp( cmd_line, + 2*64*1024, + 256, + HvLpDma_Direction_RemoteToLocal ); + + mf_init(); + viopath_init(); +*/ +} + +/* + * int iSeries_setup_residual() + * + * Description: + * This routine pretty-prints CPU information gathered from the VPD + * for use in /proc/cpuinfo + * + * Input(s): + * *buffer - Buffer into which CPU data is to be printed. + * + * Output(s): + * *buffer - Buffer with CPU data. + * + * Returns: + * The number of bytes copied into 'buffer' if OK, otherwise zero or less + * on error. + */ +int +iSeries_setup_residual(char *buffer) +{ + int len = 0; + + len += sprintf(len+buffer,"clock\t\t: %lu.%02luMhz\n", + procFreqMhz, procFreqMhzHundreths ); +// len += sprintf(len+buffer," processor clock\t\t: %ldMHz\n", +// ((unsigned long)xIoHriProcessorVpd[0].xProcFreq)/1000000); + len += sprintf(len+buffer,"time base\t: %lu.%02luMHz\n", + tbFreqMhz, tbFreqMhzHundreths ); +// len += sprintf(len+buffer," time base freq\t\t: %ldMHz\n", +// ((unsigned long)xIoHriProcessorVpd[0].xTimeBaseFreq)/1000000); + len += sprintf(len+buffer,"i-cache\t\t: %d\n", + iSeries_icache_line_size); + len += sprintf(len+buffer,"d-cache\t\t: %d\n", + iSeries_dcache_line_size); + + + return (len); +} + +int iSeries_get_cpuinfo(char *buffer) +{ + int len = 0; + + len += sprintf(len+buffer,"machine\t\t: iSeries Logical Partition\n"); + + return len; +} + +#ifndef CONFIG_PCI +/* + * Document me. + * and Implement me. + * If no Native I/O, do nothing routine. + */ + void __init +iSeries_init_IRQ(void) +{ + return; +} +#endif + +/* + * Document me. + * and Implement me. + */ +int +iSeries_get_irq(struct pt_regs *regs) +{ +/* + return (ppc4xx_pic_get_irq(regs)); +*/ + /* -2 means ignore this interrupt */ + return -2; +} + +/* + * Document me. + */ +void +iSeries_restart(char *cmd) +{ + mf_reboot(); +} + +/* + * Document me. + */ +void +iSeries_power_off(void) +{ + mf_powerOff(); +} + +/* + * Document me. + */ +void +iSeries_halt(void) +{ + mf_powerOff(); +} + +/* + * Nothing to do here. + */ +void __init +iSeries_time_init(void) +{ + /* Nothing to do */ +} + +/* + * Set the RTC in the virtual service processor + * This requires flowing LpEvents to the primary partition + */ +int __init +iSeries_set_rtc_time(unsigned long time) +{ + mf_setRtcTime(time); + return 0; +} + +/* + * Get the RTC from the virtual service processor + * This requires flowing LpEvents to the primary partition + */ +unsigned long __init +iSeries_get_rtc_time(void) +{ + /* XXX - Implement me */ + unsigned long time; + mf_getRtcTime(&time); + return (time); +} + +/* + * void __init iSeries_calibrate_decr() + * + * Description: + * This routine retrieves the internal processor frequency from the VPD, + * and sets up the kernel timer decrementer based on that value. + * + */ + +unsigned long iSeries_dec_value = 0; + +void __init +iSeries_calibrate_decr(void) +{ + u32 freq; + u32 tbf; + + /* Compute decrementer (and TB) frequency + * in cycles/sec + */ + + tbf = xIoHriProcessorVpd[0].xTimeBaseFreq / 16; + + freq = 0x010000000; + freq = freq / tbf; /* cycles / usec */ + freq = freq * 1000000; /* now in cycles/sec */ + + /* Set the amount to refresh the decrementer by. This + * is the number of decrementer ticks it takes for + * 1/HZ seconds. + */ + + /* decrementer_count = freq / HZ; + * count_period_num = 1; + * count_period_den = freq; */ + + tb_ticks_per_jiffy = freq / HZ; + iSeries_dec_value = tb_ticks_per_jiffy / 8; + tb_to_us = mulhwu_scale_factor(freq, 1000000); +} + +void __init +iSeries_progress( char * st, unsigned short code ) +{ + printk( "Progress: [%04x] - %s\n", (unsigned)code, st ); + if (code != 0xffff) + mf_displayProgress( code ); + else + mf_clearSrc(); +} + +#ifdef CONFIG_PCI +/* + * unsigned int __init iSeries_build_hose_list() + * + * Description: + * This routine builds a list of the PCI host bridges that + * connect PCI buses either partially or fully owned by + * this guest partition + * + */ +unsigned int __init iSeries_build_hose_list ( ) { + struct pci_controller* hose; + struct iSeries_hose_arch_data* hose_data; + u64 hvRc; + u16 hvbusnum; + int LxBusNumber = 0; /* Linux Bus number for grins */ + + /* Check to make sure the device probing will work on this iSeries Release. */ + if(hvReleaseData.xVrmIndex !=3) { + printk("PCI: iSeries Lpar and Linux native PCI I/O code is incompatible.\n"); + printk("PCI: A newer version of the Linux kernel is need for this iSeries release.\n"); + return 0; + } + + + for (hvbusnum = 0; hvbusnum < 256; hvbusnum++) { /* All PCI buses which could be owned by this guest partition will be numbered by the hypervisor between 1 & 255 */ + hvRc = HvCallXm_testBus (hvbusnum); /* Call the system hypervisor to query guest partition ownership status of this bus */ + if (hvRc == 0) { /* This bus is partially/fully owned by this guest partition */ + hose = (struct pci_controller*)pcibios_alloc_controller(); // Create the hose for this PCI bus + hose->first_busno = LxBusNumber; /* This just for debug. pcibios will */ + hose->last_busno = 0xff; /* assign the bus numbers. */ + hose->ops = &iSeries_pci_ops; + /* Create the iSeries_arch_data for the hose and cache the HV bus number in it so that pci bios can build the global bus map */ + hose_data = (struct iSeries_hose_arch_data *) alloc_bootmem(sizeof(struct iSeries_hose_arch_data)); + memset(hose_data, 0, sizeof(*hose_data)); + hose->arch_data = (void *) hose_data; + ((struct iSeries_hose_arch_data *)(hose->arch_data))->hvBusNumber = hvbusnum; + LxBusNumber += 1; /* Keep track for debug */ + } + } + pci_assign_all_busses = 1; /* Let Linux assign the bus numbers in pcibios_init */ + return 0; +} +#endif /* CONFIG_PCI */ + + +unsigned long __init +iSeries_find_end_of_memory(void) +{ + /* totalLpChunks contains the size of memory (in units of 256K) */ + unsigned long memory_end = (totalLpChunks << 18); + + #ifndef CONFIG_HIGHMEM + /* Max memory if highmem is not configured in 768 MB */ + if (memory_end > (768 << 20)) + memory_end = 768 << 20; + #endif /* CONFIG_HIGHMEM */ + + return memory_end; +} + diff -Nru a/arch/ppc/kernel/iSeries_setup.h b/arch/ppc/kernel/iSeries_setup.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/iSeries_setup.h Sat Jun 16 06:00:31 2001 @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2000 Mike Corrigan + * Copyright (c) 1999-2000 Grant Erickson + * + * Module name: iSeries_setup.h + * + * Description: + * Architecture- / platform-specific boot-time initialization code for + * the IBM iSeries LPAR. Adapted from original code by Grant Erickson and + * code by Gary Thomas, Cort Dougan , and Dan Malek + * . + * + * 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 + */ + +#ifndef __ISERIES_SETUP_H__ +#define __ISERIES_SETUP_H__ + + +#ifdef __cplusplus +extern "C" { +#endif + +extern void iSeries_init(unsigned long r3, + unsigned long ird_start, + unsigned long ird_end, + unsigned long cline_start, + unsigned long cline_end); +extern void iSeries_setup_arch(void); +extern int iSeries_setup_residual(char *buffer); +extern int iSeries_get_cpuinfo(char *buffer); +extern void iSeries_init_IRQ(void); +extern int iSeries_get_irq(struct pt_regs *regs); +extern void iSeries_restart(char *cmd); +extern void iSeries_power_off(void); +extern void iSeries_halt(void); +extern void iSeries_time_init(void); +extern int iSeries_set_rtc_time(unsigned long now); +extern unsigned long iSeries_get_rtc_time(void); +extern void iSeries_calibrate_decr(void); +extern void iSeries_progress( char *, unsigned short ); +extern unsigned int iSeries_build_hose_list(void); +extern unsigned long iSeries_find_end_of_memory(void); + + +#ifdef __cplusplus +} +#endif + +#endif /* __ISERIES_SETUP_H__ */ diff -Nru a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c --- a/arch/ppc/kernel/idle.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/kernel/idle.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.idle.c 1.11 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Idle daemon for PowerPC. Idle daemon will handle any action @@ -31,6 +31,7 @@ #include #include #include +#include void zero_paged(void); void power_save(void); @@ -50,16 +51,8 @@ { int do_power_save = 0; - /* only sleep on the 603-family/750 processors */ - switch (_get_PVR() >> 16) { - case 3: /* 603 */ - case 6: /* 603e */ - case 7: /* 603ev */ - case 8: /* 750 */ - case 12: /* 7400 */ - case 0x800c: /* 7410 */ + if (cur_cpu_spec[smp_processor_id()]->cpu_features & CPU_FTR_CAN_DOZE) do_power_save = 1; - } /* endless loop with no priority at all */ current->nice = 20; diff -Nru a/arch/ppc/kernel/indirect_pci.c b/arch/ppc/kernel/indirect_pci.c --- a/arch/ppc/kernel/indirect_pci.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/kernel/indirect_pci.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.indirect_pci.c 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Support for indirect PCI bridges. diff -Nru a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c --- a/arch/ppc/kernel/irq.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/kernel/irq.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.irq.c 1.26 06/06/01 22:33:09 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/irq.c @@ -93,6 +93,10 @@ static struct irqaction malloc_cache[IRQ_KMALLOC_ENTRIES]; extern int mem_init_done; +#if defined(CONFIG_TAU) +extern int tau_interrupts(unsigned long cpu); +#endif + void *irq_kmalloc(size_t size, int pri) { unsigned int i; @@ -531,25 +535,21 @@ { int cpu = smp_processor_id(); int irq; - hardirq_enter( cpu ); + hardirq_enter(cpu); /* every arch is required to have a get_irq -- Cort */ - irq = ppc_md.get_irq( regs ); + irq = ppc_md.get_irq(regs); - if ( irq < 0 ) - { + if (irq >= 0) { + ppc_irq_dispatch_handler( regs, irq ); + } else if (irq != -2) { /* -2 means ignore, already handled */ - if (irq != -2) - { + if (ppc_spurious_interrupts < 10) printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n", irq, regs->nip); - /* That's not SMP safe ... but who cares ? */ - ppc_spurious_interrupts++; - } - goto out; + /* That's not SMP safe ... but who cares ? */ + ppc_spurious_interrupts++; } - ppc_irq_dispatch_handler( regs, irq ); -out: hardirq_exit( cpu ); if (softirq_pending(cpu)) diff -Nru a/arch/ppc/kernel/k2.h b/arch/ppc/kernel/k2.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/k2.h Sat Jun 16 06:00:32 2001 @@ -0,0 +1,89 @@ +/* + * arch/ppc/kernel/k2.h + * + * Definitions for SBS K2 board support + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PPC_KERNEL_K2_H +#define __PPC_KERNEL_K2_H + +#include "m1543c.h" + +/* + * SBS K2 definitions + */ + +#define K2_PCI64_BAR 0xff400000 +#define K2_PCI32_BAR 0xff500000 + +#define K2_PCI64_CONFIG_ADDR (K2_PCI64_BAR + 0x000f8000) +#define K2_PCI64_CONFIG_DATA (K2_PCI64_BAR + 0x000f8010) + +#define K2_PCI32_CONFIG_ADDR (K2_PCI32_BAR + 0x000f8000) +#define K2_PCI32_CONFIG_DATA (K2_PCI32_BAR + 0x000f8010) + +#define K2_PCI64_MEM_BASE 0xc8000000 +#define K2_PCI64_IO_BASE 0x88000000 + +#define K2_PCI32_MEM_BASE 0xc0000000 +#define K2_PCI32_IO_BASE 0x80000000 + +#define K2_PCI32_SYS_MEM_BASE 0x80000000 + +#define K2_PCI32_LOWER_MEM 0x00000000 +#define K2_PCI32_UPPER_MEM 0x07ffffff +#define K2_PCI32_LOWER_IO 0x00000000 +#define K2_PCI32_UPPER_IO 0x07ffffff + +#define K2_PCI64_LOWER_MEM 0x08000000 +#define K2_PCI64_UPPER_MEM 0x0fffffff +#define K2_PCI64_LOWER_IO 0x08000000 +#define K2_PCI64_UPPER_IO 0x0fffffff + +#define K2_ISA_IO_BASE K2_PCI32_IO_BASE +#define K2_ISA_MEM_BASE K2_PCI32_MEM_BASE + +#define K2_ISAPNP_CONFIG (K2_ISA_IO_BASE + M1543C_ISAPNP_CONFIG_OFFSET) +#define K2_ISAPNP_INDEX K2_ISAPNP_CONFIG +#define K2_ISAPNP_DATA (K2_ISA_IO_BASE + M1543C_ISAPNP_DATA_OFFSET) + +#define K2_BOARD_ID_REG (K2_ISA_IO_BASE + 0x800) +#define K2_MISC_REG (K2_ISA_IO_BASE + 0x804) +#define K2_MSIZ_GEO_REG (K2_ISA_IO_BASE + 0x808) +#define K2_HOT_SWAP_REG (K2_ISA_IO_BASE + 0x80c) +#define K2_PLD2_REG (K2_ISA_IO_BASE + 0x80e) +#define K2_PLD3_REG (K2_ISA_IO_BASE + 0x80f) + +#define K2_BUS_SPD(board_id) (board_id >> 2) & 3 + +#define K2_RTC_BASE_OFFSET 0x90000 +#define K2_RTC_BASE_ADDRESS (K2_PCI32_MEM_BASE + K2_RTC_BASE_OFFSET) +#define K2_RTC_SIZE 0x8000 + +#define K2_MEM_SIZE_MASK 0xe0 +#define K2_MEM_SIZE(size_reg) (size_reg & K2_MEM_SIZE_MASK) >> 5 +#define K2_MEM_SIZE_1GB 0x40000000 +#define K2_MEM_SIZE_512MB 0x20000000 +#define K2_MEM_SIZE_256MB 0x10000000 +#define K2_MEM_SIZE_128MB 0x08000000 + +#define K2_L2CACHE_MASK 0x03 /* Mask for 2 L2 Cache bits */ +#define K2_L2CACHE_512KB 0x00 /* 512KB */ +#define K2_L2CACHE_256KB 0x01 /* 256KB */ +#define K2_L2CACHE_1MB 0x02 /* 1MB */ +#define K2_L2CACHE_NONE 0x03 /* None */ + +#define K2_GEO_ADR_MASK 0x1f + +#define K2_SYS_SLOT_MASK 0x08 + +#endif /* __PPC_KERNEL_K2_H */ diff -Nru a/arch/ppc/kernel/k2_pci.c b/arch/ppc/kernel/k2_pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/k2_pci.c Sat Jun 16 06:00:32 2001 @@ -0,0 +1,264 @@ +/* + * arch/ppc/kernel/k2_pci.c + * + * PCI support for SBS K2 + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "pci.h" +#include "pci_auto.h" +#include "cpc710.h" +#include "k2.h" + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +static inline int __init +k2_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {1, 0, 0, 0}, /* IDSEL 3 - Ethernet */ + {5, 5, 5, 5}, /* IDSEL 4 - PMC Site 1 */ + {6, 6, 6, 6}, /* IDSEL 5 - PMC Site 2 */ + {0, 0, 0, 0}, /* IDSEL 6 - unused */ + {0, 0, 0, 0}, /* IDSEL 7 - unused */ + {0, 0, 0, 0}, /* IDSEL 8 - PCI-ISA Bridge */ + {0, 0, 0, 0}, /* IDSEL 9 - unused */ + {0, 0, 0, 0}, /* IDSEL 10 - unused */ + {0, 0, 0, 0}, /* IDSEL 11 - unused */ + {0, 0, 0, 0}, /* IDSEL 12 - unused */ + {0, 0, 0, 0}, /* IDSEL 13 - unused */ + {0, 0, 0, 0}, /* IDSEL 14 - unused */ + {0, 0, 0, 0}, /* IDSEL 15 - unused */ + {0, 0, 0, 0}, /* IDSEL 16 - unused */ + {14, 0, 0, 0}, /* IDSEL 17 - M5229 IDE */ + }; + const long min_idsel = 3, max_idsel = 17, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +/* Interrupt routes from cPCI bus (PCI-64 hose) */ +static unsigned char K2_CPCI_IRQ_routes[4] = {9, 10, 11, 12}; + +void +k2_route_cpci_int(struct pci_dev *dev) +{ + struct pci_bus *pbus; /* Parent bus structure pointer */ + struct pci_dev *tdev = dev; /* Temporary pci_dev pointer */ + unsigned int devnum; /* Accumulated device number */ + unsigned char intpin; /* PCI interrupt pin */ + struct pci_controller *hose; /* PCI controller */ + + /* Check for valid PCI dev pointer */ + if (dev == NULL) return; + + /* Get a pointer to our pci_controller descriptor */ + hose = pci_bus_to_hose(dev->bus->number); + + /* Initialize bridge IDSEL variable */ + devnum = PCI_SLOT(dev->devfn); + + /* Read the interrupt pin of the device */ + pcibios_read_config_byte(dev->bus->number, dev->devfn, + PCI_INTERRUPT_PIN, &intpin); + + /* If device doesn't request an interrupt, return */ + if ( (intpin < 1) || (intpin > 4) ) + return; + + /* Only loop if we are on a subordinate bus */ + if (dev->bus->number != hose->first_busno) + { + /* + * Walk up to the top bus, adjusting the interrupt pin for the + * standard PCI bus swizzle. + */ + do + { + intpin = bridge_swizzle(intpin, devnum); + pbus = tdev->bus; /* up one level */ + tdev = pbus->self; + devnum = PCI_SLOT(tdev->devfn); + } while(tdev->bus->number != hose->first_busno); + } + + /* + * devnum is reduced by 6 because the CPC710 + * addresses IDSELs differently than the PCI + * spec suggests. + */ + intpin = bridge_swizzle(intpin, devnum-6); + + /* + * For the second PCI hose, use the swizzled interrupt pin + * value to map to a CPCI interrupt input on the PIC + */ + dev->irq = K2_CPCI_IRQ_routes[intpin-1]; + + /* Write calculated interrupt value to header and device list */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); +} + +void k2_pcibios_fixup(void) +{ + struct pci_dev *dev; + + pci_for_each_dev(dev) + if (pci_bus_to_hose(dev->bus->number)->first_busno) + k2_route_cpci_int(dev); + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + { + /* + * Enable DMA support on hdc + */ + struct pci_dev *ide_dev; + unsigned long ide_dma_base; + + ide_dev = pci_find_device(PCI_VENDOR_ID_AL, + PCI_DEVICE_ID_AL_M5229, + NULL); + ide_dma_base = pci_resource_start(ide_dev, 4); + outb(0x00, ide_dma_base+0x2); + outb(0x20, ide_dma_base+0xa); + } +#endif + +} + +void k2_pcibios_fixup_resources(struct pci_dev *dev) +{ + int i; + + if ((dev->vendor == PCI_VENDOR_ID_IBM) && + (dev->device == PCI_DEVICE_ID_IBM_CPC710_PCI64)) + { + DBG("Fixup CPC710 resources\n"); + for (i=0; iresource[i].start = 0; + dev->resource[i].end = 0; + } + } +} + +void k2_find_bridges(void) +{ + struct pci_controller *hose_a, *hose_b; + + /* Setup PCI32 hose */ + hose_a = pcibios_alloc_controller(); + if (!hose_a) + return; + + hose_a->first_busno = 0; + hose_a->last_busno = 0xff; + hose_a->pci_mem_offset = K2_PCI32_MEM_BASE; + hose_a->io_space.start = K2_PCI32_LOWER_IO; + hose_a->io_space.end = K2_PCI32_UPPER_IO; + hose_a->mem_space.start = K2_PCI32_LOWER_MEM; + hose_a->mem_space.end = K2_PCI32_UPPER_MEM; + hose_a->io_base_virt = (void *)K2_ISA_IO_BASE; + + setup_indirect_pci(hose_a, K2_PCI32_CONFIG_ADDR, K2_PCI32_CONFIG_DATA); + + /* Initialize PCI32 bus registers */ + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(0, 0), + CPC710_BUS_NUMBER, + hose_a->first_busno); + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(0, 0), + CPC710_SUB_BUS_NUMBER, + hose_a->last_busno); + + hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); + + /* Write out correct max subordinate bus number for hose A */ + early_write_config_byte(hose_a, + hose_a->first_busno, + PCI_DEVFN(0, 0), + CPC710_SUB_BUS_NUMBER, + hose_a->last_busno); + + /* Only setup PCI64 hose if we are in the system slot */ + if (!(readb(K2_MISC_REG) & K2_SYS_SLOT_MASK)) + { + /* Setup PCI64 hose */ + hose_b = pcibios_alloc_controller(); + if (!hose_b) + return; + + hose_b->first_busno = hose_a->last_busno + 1; + hose_b->last_busno = 0xff; + /* Reminder: quit changing the following, it is correct. */ + hose_b->pci_mem_offset = K2_PCI32_MEM_BASE; + hose_b->io_space.start = K2_PCI64_LOWER_IO; + hose_b->io_space.end = K2_PCI64_UPPER_IO; + hose_b->mem_space.start = K2_PCI64_LOWER_MEM; + hose_b->mem_space.end = K2_PCI64_UPPER_MEM; + hose_b->io_base_virt = (void *)K2_ISA_IO_BASE; + + setup_indirect_pci(hose_b, + K2_PCI64_CONFIG_ADDR, + K2_PCI64_CONFIG_DATA); + + /* Initialize PCI64 bus registers */ + early_write_config_byte(hose_b, + 0, + PCI_DEVFN(0, 0), + CPC710_SUB_BUS_NUMBER, + 0xff); + + early_write_config_byte(hose_b, + 0, + PCI_DEVFN(0, 0), + CPC710_BUS_NUMBER, + hose_b->first_busno); + + hose_b->last_busno = pciauto_bus_scan(hose_b, + hose_b->first_busno); + + /* Write out correct max subordinate bus number for hose B */ + early_write_config_byte(hose_b, + hose_b->first_busno, + PCI_DEVFN(0, 0), + CPC710_SUB_BUS_NUMBER, + hose_b->last_busno); + } + + ppc_md.pcibios_fixup = k2_pcibios_fixup; + ppc_md.pcibios_fixup_resources = k2_pcibios_fixup_resources; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = k2_map_irq; +} diff -Nru a/arch/ppc/kernel/k2_pic.c b/arch/ppc/kernel/k2_pic.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/k2_pic.c Sat Jun 16 06:00:32 2001 @@ -0,0 +1,55 @@ +/* + * arch/ppc/kernel/k2_pic.c + * + * Interrupt controller support for SBS K2 + * + * Author: Matt Porter + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include + +#include "local_irq.h" +#include "i8259.h" + +extern int i8259_irq(int); + +__init void +k2_init_IRQ(void) +{ + int i; + + for ( i = 0 ; i < 16 ; i++ ) + irq_desc[i].handler = &i8259_pic; + + i8259_init(); +} + +int +k2_get_irq(struct pt_regs *regs) +{ + int irq; + + if ( (irq = i8259_irq(0)) < 0 ) + { + printk(KERN_DEBUG "Bogus interrupt from PC = %lx\n", + regs->nip); + ppc_spurious_interrupts++; + return -1; + } + + ppc_irq_dispatch_handler( regs, irq ); + + return irq; +} diff -Nru a/arch/ppc/kernel/k2_setup.c b/arch/ppc/kernel/k2_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/k2_setup.c Sat Jun 16 06:00:32 2001 @@ -0,0 +1,453 @@ +/* + * arch/ppc/kernel/k2_setup.c + * + * Board setup routines for SBS K2 + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "todc.h" +#include "k2.h" + +extern void k2_init_IRQ(void); +extern int k2_get_irq(struct pt_regs *); +extern void k2_find_bridges(void); +extern unsigned long loops_per_jiffy; + +static unsigned int k2_l2_cache_size; + +static unsigned int cpu_7xx[16] = { + 0, 15, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 16, 12, 7, 0 +}; +static unsigned int cpu_6xx[16] = { + 0, 0, 14, 0, 0, 13, 5, 9, 6, 11, 8, 10, 0, 12, 7, 0 +}; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +/* IDE functions */ +void +k2_ide_insw(ide_ioreg_t port, void *buf, int ns) +{ + ide_insw(((port)+(_IO_BASE)), buf, ns); +} + +void +k2_ide_outsw(ide_ioreg_t port, void *buf, int ns) +{ + ide_outsw(((port)+_IO_BASE), buf, ns); +} + +int +k2_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +void +k2_ide_request_region(ide_ioreg_t from, + unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +void +k2_ide_release_region(ide_ioreg_t from, + unsigned int extent) +{ + release_region(from, extent); +} + +void __init +k2_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i = 8; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + else + hw->io_ports[IDE_CONTROL_OFFSET] = + hw->io_ports[IDE_DATA_OFFSET] + 0x206; + + if (irq != NULL) + *irq = 0; +} +#endif + +static inline unsigned long _get_HID1(void) +{ + unsigned long val; + + __asm__ __volatile__("mfspr %0,1009" : "=r" (val)); + return val; +} + +int +k2_get_bus_speed(void) +{ + int bus_speed; + unsigned char board_id; + + board_id = *(unsigned char *)K2_BOARD_ID_REG; + + switch( K2_BUS_SPD(board_id) ) { + + case 0: + default: + bus_speed = 100000000; + break; + + case 1: + bus_speed = 83333333; + break; + + case 2: + bus_speed = 75000000; + break; + + case 3: + bus_speed = 66666666; + break; + } + return bus_speed; +} + +int +k2_get_cpu_speed(void) +{ + unsigned long hid1; + int cpu_speed; + + hid1 = _get_HID1() >> 28; + + if ((_get_PVR()>>16) == 8) + hid1 = cpu_7xx[hid1]; + else + hid1 = cpu_6xx[hid1]; + + cpu_speed = k2_get_bus_speed()*hid1/2; + return cpu_speed; +} + +void __init k2_calibrate_decr(void) +{ + int freq, divisor = 4; + + /* determine processor bus speed */ + freq = k2_get_bus_speed(); + tb_ticks_per_jiffy = freq / HZ / divisor; + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +} + +void +k2_setup_l2_cache(void) +{ + switch ((*(unsigned char *)K2_BOARD_ID_REG) & K2_L2CACHE_MASK) + { + case K2_L2CACHE_512KB: + k2_l2_cache_size = L2CR_L2SIZ_512KB; + break; + + case K2_L2CACHE_256KB: + k2_l2_cache_size = L2CR_L2SIZ_256KB; + break; + + case K2_L2CACHE_1MB: + k2_l2_cache_size = L2CR_L2SIZ_1MB; + break; + + case K2_L2CACHE_NONE: + default: + k2_l2_cache_size = 0; + break; + } + + if (k2_l2_cache_size) + { + _set_L2CR(0); + _set_L2CR(L2CR_L2E | L2CR_L2PE | k2_l2_cache_size | + L2CR_L2CLK_DIV2 | L2CR_L2RAM_PIPE_LW | + L2CR_L2DO | L2CR_L2OH_1_0 | L2CR_L2DF); + } +} + +void +k2_get_l2_string(char *buffer) +{ + switch (k2_l2_cache_size) + { + case L2CR_L2SIZ_256KB: + sprintf(buffer, "256KB"); + break; + + case L2CR_L2SIZ_512KB: + sprintf(buffer, "512KB"); + break; + + case L2CR_L2SIZ_1MB: + sprintf(buffer, "1MB"); + break; + + default: + sprintf(buffer, "0KB"); + break; + } +} + +int +k2_get_cpuinfo(char *buffer) +{ + int len; + unsigned char k2_geo_bits, k2_system_slot; + char l2_string[10]; + + len = sprintf( buffer, "vendor\t\t: SBS\n"); + + len += sprintf( buffer+len, "machine\t\t: K2\n"); + + len += sprintf( buffer+len, "cpu speed\t: %dMhz\n", + k2_get_cpu_speed()/1000000); + + len += sprintf( buffer+len, "bus speed\t: %dMhz\n", + k2_get_bus_speed()/1000000); + + k2_get_l2_string(l2_string); + len += sprintf( buffer+len, "L2\t\t: %s\n", l2_string); + + len += sprintf( buffer+len, "memory type\t: SDRAM\n"); + + k2_geo_bits = readb(K2_MSIZ_GEO_REG) & K2_GEO_ADR_MASK; + k2_system_slot = !(readb(K2_MISC_REG) & K2_SYS_SLOT_MASK); + len += sprintf( buffer+len, + "backplane\t: %s slot board with geographical address %x\n", + k2_system_slot ? "System" : "Non system", + k2_geo_bits); + + len += sprintf(buffer+len, "\n"); + + return len; +} + +extern char cmd_line[]; + +void __init +k2_setup_arch(void) +{ + unsigned int cpu; + + /* Setup TODC access */ + todc_info = &m48t37_info; + todc_info->nvram_data = + (u_char *)ioremap(K2_RTC_BASE_ADDRESS, K2_RTC_SIZE); + + /* Configure and enable L2 cache */ + k2_setup_l2_cache(); + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Setup PCI host bridges */ + k2_find_bridges(); + +#ifdef CONFIG_ROOT_NFS + /* bootable from nfsroot */ + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + /* bootable from IDE secondary master */ + ROOT_DEV = to_kdev_t(0x1601); /* /dev/hdc1 */ +#endif + + /* Identify the system */ + printk("System Identification: SBS K2 - PowerPC 750 @ %d Mhz\n", k2_get_cpu_speed()/1000000); + printk("SBS K2 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + + /* Identify the CPU manufacturer */ + cpu = _get_PVR(); + printk("CPU manufacturer: %s [rev=%04x]\n", (cpu & (1<<15)) ? "IBM" : + "Motorola", (cpu & 0xffff)); +} + +void +k2_restart(char *cmd) +{ + __cli(); + /* SRR0 has system reset vector, SRR1 has default MSR value */ + /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ + __asm__ __volatile__ + ("\n\ + lis 3,0xfff0 + ori 3,3,0x0100 + mtspr 26,3 + li 3,0 + mtspr 27,3 + rfi + "); + for(;;); +} + +void +k2_power_off(void) +{ + for(;;); +} + +void +k2_halt(void) +{ + k2_restart(NULL); +} + +/* + * Set BAT 3 to map 0x80000000. + */ +static __inline__ void +k2_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) + { + __asm__ __volatile__( + " lis %0,0x8000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + :: "r" (bat3u), "r" (bat3l)); + + mapping_set = 1; + } + return; +} + +unsigned long __init k2_find_end_of_memory(void) +{ + unsigned long total; + unsigned char msize = 7; /* Default to 128MB */ + + k2_set_bat(); + + msize = K2_MEM_SIZE(readb(K2_MSIZ_GEO_REG)); + + switch (msize) + { + case 2: + total = K2_MEM_SIZE_1GB; + break; + total = K2_MEM_SIZE_1GB; + break; + case 3: + case 4: + total = K2_MEM_SIZE_512MB; + break; + case 5: + case 6: + total = K2_MEM_SIZE_256MB; + break; + case 7: + total = K2_MEM_SIZE_128MB; + break; + default: + printk("K2: Invalid memory size detected, defaulting to + 128MB\n"); + total = K2_MEM_SIZE_128MB; + break; + } + return total; +} + +void __init k2_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + +#ifdef CONFIG_BLK_DEV_INITRD + if ( r4 ) + { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif + + /* Copy cmd_line parameters */ + if ( r6 ) + { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6+KERNELBASE)); + } + + isa_io_base = K2_ISA_IO_BASE; + isa_mem_base = K2_ISA_MEM_BASE; + pci_dram_offset = K2_PCI32_SYS_MEM_BASE; + + ppc_md.setup_arch = k2_setup_arch; + ppc_md.setup_residual = NULL; + ppc_md.get_cpuinfo = k2_get_cpuinfo; + ppc_md.irq_cannonicalize = NULL; + ppc_md.init_IRQ = k2_init_IRQ; + ppc_md.get_irq = k2_get_irq; + ppc_md.init = NULL; + + ppc_md.find_end_of_memory = k2_find_end_of_memory; + + ppc_md.restart = k2_restart; + ppc_md.power_off = k2_power_off; + ppc_md.halt = k2_halt; + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = k2_calibrate_decr; + + ppc_md.nvram_read_val = todc_direct_read_val; + ppc_md.nvram_write_val = todc_direct_write_val; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ppc_ide_md.insw = k2_ide_insw; + ppc_ide_md.outsw = k2_ide_outsw; + ppc_ide_md.ide_check_region = k2_ide_check_region; + ppc_ide_md.ide_request_region = k2_ide_request_region; + ppc_ide_md.ide_release_region = k2_ide_release_region; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; + ppc_ide_md.ide_init_hwif = k2_ide_init_hwif_ports; + ppc_ide_md.io_base = _IO_BASE; +#endif +} diff -Nru a/arch/ppc/kernel/local_irq.h b/arch/ppc/kernel/local_irq.h --- a/arch/ppc/kernel/local_irq.h Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/kernel/local_irq.h Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.local_irq.h 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef _PPC_KERNEL_LOCAL_IRQ_H diff -Nru a/arch/ppc/kernel/m1543c.h b/arch/ppc/kernel/m1543c.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/m1543c.h Sat Jun 16 06:00:31 2001 @@ -0,0 +1,23 @@ +/* + * arch/ppc/kernel/m1543c.h + * + * ALI M1543C PCI-ISA bridge definitions + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PPC_KERNEL_M1543C_H +#define __PPC_KERNEL_M1543C_H + +#define M1543C_ISAPNP_CONFIG_OFFSET 0x370 +#define M1543C_ISAPNP_INDEX_OFFSET M1543C_ISAPNP_CONFIG_OFFSET +#define M1543C_ISAPNP_DATA_OFFSET 0x371 + +#endif /* __PPC_KERNEL_M1543C_H */ diff -Nru a/arch/ppc/kernel/m8260_setup.c b/arch/ppc/kernel/m8260_setup.c --- a/arch/ppc/kernel/m8260_setup.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/kernel/m8260_setup.c Sat Jun 16 06:00:24 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.m8260_setup.c 1.15 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/setup.c @@ -52,17 +52,6 @@ unsigned long m8260_get_rtc_time(void); void m8260_calibrate_decr(void); -#if 0 -extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode); -extern int mackbd_getkeycode(unsigned int scancode); -extern int mackbd_pretranslate(unsigned char scancode, char raw_mode); -extern int mackbd_translate(unsigned char scancode, unsigned char *keycode, - char raw_mode); -extern char mackbd_unexpected_up(unsigned char keycode); -extern void mackbd_leds(unsigned char leds); -extern void mackbd_init_hw(void); -#endif - extern unsigned long loops_per_jiffy; unsigned char __res[sizeof(bd_t)]; @@ -73,10 +62,6 @@ extern unsigned long find_available_memory(void); extern void m8260_cpm_reset(void); -void __init adbdev_init(void) -{ -} - void __init m8260_setup_arch(void) { @@ -112,7 +97,8 @@ /* The 8260 has an internal 1-second timer update register that * we should use for this purpose. */ -static uint rtc_time; +static uint rtc_time; + static int m8260_set_rtc_time(unsigned long time) { @@ -146,7 +132,7 @@ startaddr = simple_strtoul(&cmd[10], NULL, 0); } - m8260_gorom((uint)__pa(__res), startaddr); + m8260_gorom((unsigned int)__pa(__res), startaddr); } void @@ -284,41 +270,6 @@ ppc_ide_md.io_base = _IO_BASE; #endif -} - -/* - * Copied from prom.c so I don't have include all of that crap. - * -- Dan - * - * prom_init() is called very early on, before the kernel text - * and data have been mapped to KERNELBASE. At this point the code - * is running at whatever address it has been loaded at, so - * references to extern and static variables must be relocated - * explicitly. The procedure reloc_offset() returns the address - * we're currently running at minus the address we were linked at. - * (Note that strings count as static variables.) - */ -extern unsigned long reloc_offset(void); -#define PTRRELOC(x) ((typeof(x))((unsigned long)(x) + offset)) - -__init -unsigned long -prom_init(uint r3, uint r4, uint r5, uint r6) -{ - unsigned long offset = reloc_offset(); - unsigned long phys; - extern char __bss_start, _end; - - /* First zero the BSS -- use memset, some arches don't have - * caches on yet */ - memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start); - - /* Default */ - phys = offset + KERNELBASE; - - /* We are done. - */ - return phys; } /* Mainly for ksyms. diff -Nru a/arch/ppc/kernel/m8xx_setup.c b/arch/ppc/kernel/m8xx_setup.c --- a/arch/ppc/kernel/m8xx_setup.c Sat Jun 16 06:00:27 2001 +++ b/arch/ppc/kernel/m8xx_setup.c Sat Jun 16 06:00:27 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.m8xx_setup.c 1.17 05/18/01 07:54:04 patch + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/setup.c @@ -267,7 +267,7 @@ return(0); } -unsigned long __init +unsigned long m8xx_get_rtc_time(void) { /* Get time from the RTC. diff -Nru a/arch/ppc/kernel/mcpn765.h b/arch/ppc/kernel/mcpn765.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/mcpn765.h Sat Jun 16 06:00:30 2001 @@ -0,0 +1,91 @@ +/* + * arch/ppc/kernel/mcpn765.h + * + * Definitions for Motorola MCG MCPN765 cPCI Board. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * From Processor to PCI: + * PCI Mem Space: 0x80000000 - 0xa0000000 -> 0x80000000 - 0xa0000000 (512 MB) + * PCI I/O Space: 0xfc000000 - 0xfc800000 -> 0x00000000 - 0x00800000 (8 MB) + * MPIC in PCI Mem Space: 0xf3f80000 - 0xf3fb0000 (not all used by MPIC) + * + * From PCI to Processor: + * System Memory: 0x00000000 -> 0x00000000 + * + * PCI config addr reg: 0xfe000cf8 + * PCI config data reg: 0xfe000cfc + */ + +#ifndef __PPC_KERNEL_MCPN765_H +#define __PPC_KERNEL_MCPN765_H + +/* Define base addresses for important sets of registers */ +#define MCPN765_HAWK_PPC_REG_BASE 0xfeff0000 +#define MCPN765_HAWK_MPIC_BASE 0xf3f80000 +#define MCPN765_HAWK_SMC_BASE 0xfef80000 + +#define MCPN765_PCI_CONFIG_ADDR 0xfe000cf8 +#define MCPN765_PCI_CONFIG_DATA 0xfe000cfc + + +/* PCI Memory space mapping info */ +#define MCPN765_PCI_MEM_SIZE 0x20000000U +#define MCPN765_PROC_PCI_MEM_START 0x80000000U +#define MCPN765_PROC_PCI_MEM_END (MCPN765_PROC_PCI_MEM_START + \ + MCPN765_PCI_MEM_SIZE - 1) +#define MCPN765_PCI_MEM_START 0x80000000U +#define MCPN765_PCI_MEM_END (MCPN765_PCI_MEM_START + \ + MCPN765_PCI_MEM_SIZE - 1) + +/* PCI I/O space mapping info */ +#define MCPN765_PCI_IO_SIZE 0x00800000U +#define MCPN765_PROC_PCI_IO_START 0xfc000000U +#define MCPN765_PROC_PCI_IO_END (MCPN765_PROC_PCI_IO_START + \ + MCPN765_PCI_IO_SIZE - 1) +#define MCPN765_PCI_IO_START 0x00000000U +#define MCPN765_PCI_IO_END (MCPN765_PCI_IO_START + \ + MCPN765_PCI_IO_SIZE - 1) + +/* System memory mapping info */ +#define MCPN765_PCI_DRAM_OFFSET 0x00000000U +#define MCPN765_PCI_PHY_MEM_OFFSET 0x00000000U + + +#define MCPN765_ISA_MEM_BASE 0x00000000U +#define MCPN765_ISA_IO_BASE MCPN765_PROC_PCI_IO_START + +/* Define MCPN765 board register addresses. */ +#define MCPN765_BOARD_STATUS_REG 0xfef88080 +#define MCPN765_BOARD_MODFAIL_REG 0xfef88090 +#define MCPN765_BOARD_MODRST_REG 0xfef880a0 +#define MCPN765_BOARD_TBEN_REG 0xfef880c0 +#define MCPN765_BOARD_GEOGRAPHICAL_REG 0xfef880e8 +#define MCPN765_BOARD_EXT_FEATURE_REG 0xfef880f0 +#define MCPN765_BOARD_LAST_RESET_REG 0xfef880f8 + +/* UART base addresses are defined in +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pci.h" +#include "pci_auto.h" +#include "pplus.h" +#include "mcpn765.h" + + +/* + * Motorola MCG MCPN765 interrupt routing. + */ +static inline int +mcpn765_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 14, 0, 0, 0 }, /* IDSEL 11 - have to manually set */ + { 0, 0, 0, 0 }, /* IDSEL 12 - unused */ + { 0, 0, 0, 0 }, /* IDSEL 13 - unused */ + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 0 */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 25, 26, 27, 28 }, /* IDSEL 16 - PMC Slot 1 */ + { 28, 25, 26, 27 }, /* IDSEL 17 - PMC Slot 2 */ + { 0, 0, 0, 0 }, /* IDSEL 18 - PMC 2B Connector XXXX */ + { 29, 0, 0, 0 }, /* IDSEL 19 - Enet 1 */ + { 20, 0, 0, 0 }, /* IDSEL 20 - 21554 cPCI bridge */ + }; + + const long min_idsel = 11, max_idsel = 20, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +void __init +mcpn765_find_bridges(void) +{ + struct pci_controller* hose; + int host_bridge; + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + hose->pci_mem_offset = MCPN765_PCI_PHY_MEM_OFFSET; + hose->io_space.start = MCPN765_PCI_IO_START; + hose->io_space.end = MCPN765_PCI_IO_END; + hose->mem_space.start = MCPN765_PCI_MEM_START; + hose->mem_space.end = MCPN765_PCI_MEM_END; + hose->io_base_virt = (void *)MCPN765_ISA_IO_BASE; + + /* Use indirect method of HAWK */ + setup_indirect_pci(hose, + MCPN765_PCI_CONFIG_ADDR, + MCPN765_PCI_CONFIG_DATA); + + /* Get host bridge vendor/dev id */ + early_read_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_VENDOR_ID, + &host_bridge); + + switch (host_bridge) { + case PPLUS_HAWK_VEND_DEV_ID: + if (pplus_init(hose, + MCPN765_HAWK_PPC_REG_BASE, + MCPN765_PROC_PCI_MEM_START, + MCPN765_PROC_PCI_MEM_END, + MCPN765_PROC_PCI_IO_START, + MCPN765_PROC_PCI_IO_END, + MCPN765_HAWK_MPIC_BASE) != 0) { + printk("Could not initialize HAWK bridge\n"); + } + + break; + default: + printk("Host bridge 0x%x not supported\n", host_bridge); + } + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = NULL; + ppc_md.pcibios_fixup_bus = NULL; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = mcpn765_map_irq; + + return; +} diff -Nru a/arch/ppc/kernel/mcpn765_setup.c b/arch/ppc/kernel/mcpn765_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/mcpn765_setup.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,540 @@ +/* + * arch/ppc/kernel/mcpn765_setup.c + * + * Board setup routines for the Motorola MCG MCPN765 cPCI Board. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * This file adds support for the Motorola MCG MCPN765. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pci.h" +#include "local_irq.h" +#include "open_pic.h" +#include "i8259.h" +#include "pplus.h" +#include "todc.h" +#include "mcpn765.h" + +static u_char mcpn765_openpic_initsenses[] __initdata = { + 0, /* 16: i8259 cascade (active high) */ + 1, /* 17: COM1,2,3,4 */ + 1, /* 18: Enet 1 (front panel) */ + 1, /* 19: HAWK WDT XXXX */ + 1, /* 20: 21554 PCI-PCI bridge */ + 1, /* 21: cPCI INTA# */ + 1, /* 22: cPCI INTB# */ + 1, /* 23: cPCI INTC# */ + 1, /* 24: cPCI INTD# */ + 1, /* 25: PMC1 INTA#, PMC2 INTB# */ + 1, /* 26: PMC1 INTB#, PMC2 INTC# */ + 1, /* 27: PMC1 INTC#, PMC2 INTD# */ + 1, /* 28: PMC1 INTD#, PMC2 INTA# */ + 1, /* 29: Enet 2 (connected to J3) */ + 1, /* 30: Abort Switch */ + 1, /* 31: RTC Alarm */ +}; + + +extern u_int openpic_irq(void); +extern char cmd_line[]; + +int use_of_interrupt_tree = 0; + +static void mcpn765_halt(void); + +static void __init +mcpn765_setup_arch(void) +{ + if ( ppc_md.progress ) + ppc_md.progress("mcpn765_setup_arch: enter", 0); + + loops_per_jiffy = 50000000 / HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 SCSI disk */ +#endif + + if ( ppc_md.progress ) + ppc_md.progress("mcpn765_setup_arch: find_bridges", 0); + + /* Lookup PCI host bridges */ + mcpn765_find_bridges(); + + OpenPIC_InitSenses = mcpn765_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(mcpn765_openpic_initsenses); + + printk("Motorola MCG MCPN765 cPCI Non-System Board\n"); + printk("MCPN765 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + + if ( ppc_md.progress ) + ppc_md.progress("mcpn765_setup_arch: exit", 0); + + return; +} + +/* + * Initialize the VIA 82c586b. + */ +static void __init +mcpn765_setup_via_82c586b(void) +{ + struct pci_dev *dev; + u_char c; + + if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C586_1, + NULL)) == NULL) { + printk("No VIA ISA bridge found\n"); + mcpn765_halt(); + /* NOTREACHED */ + } + + /* + * PPCBug doesn't set the enable bits for the IDE device. + * Turn them on now. + */ + pcibios_read_config_byte(dev->bus->number, dev->devfn, 0x40, &c); + c |= 0x03; + pcibios_write_config_byte(dev->bus->number, dev->devfn, 0x40, c); + + return; +} + +static void __init +mcpn765_init2(void) +{ + /* Do MCPN765 board specific initialization. */ + mcpn765_setup_via_82c586b(); + + request_region(0x00,0x20,"dma1"); + request_region(0x20,0x20,"pic1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xa0,0x20,"pic2"); + request_region(0xc0,0x20,"dma2"); + + return; +} + +/* + * Interrupt setup and service. + * Have MPIC on HAWK and cascaded 8259s on VIA 82586 cascaded to MPIC. + */ +static void __init +mcpn765_init_IRQ(void) +{ + int i; + + if ( ppc_md.progress ) + ppc_md.progress("init_irq: enter", 0); + + openpic_init(1, NUM_8259_INTERRUPTS, NULL, -1); + + for(i=0; i < NUM_8259_INTERRUPTS; i++) + irq_desc[i].handler = &i8259_pic; + + i8259_init(); + + if ( ppc_md.progress ) + ppc_md.progress("init_irq: exit", 0); + + return; +} + +static u32 +mcpn765_irq_cannonicalize(u32 irq) +{ + if (irq == 2) + { + return 9; + } + else + { + return irq; + } +} + +unsigned long __init +mcpn765_find_end_of_memory(void) +{ + return pplus_get_mem_size(MCPN765_HAWK_SMC_BASE); +} + +static void +mcpn765_reset_board(void) +{ + __cli(); + + /* Set exception prefix high - to the firmware */ + _nmask_and_or_msr(0, MSR_IP); + + out_8((u_char *)MCPN765_BOARD_MODRST_REG, 0x01); + + return; +} + +static void +mcpn765_restart(char *cmd) +{ + volatile ulong i = 10000000; + + mcpn765_reset_board(); + + while (i-- > 0); + panic("restart failed\n"); +} + +static void +mcpn765_power_off(void) +{ + mcpn765_halt(); + /* NOTREACHED */ +} + +static void +mcpn765_halt(void) +{ + __cli(); + while (1); + /* NOTREACHED */ +} + +static int +mcpn765_get_cpuinfo(char *buffer) +{ + int len; + uint pvid; + + pvid = _get_PVR(); + + len = sprintf( buffer, "vendor\t\t: Motorola MCG\n"); + + len += sprintf( buffer+len, "machine\t\t: MCPN765\n"); + + len += sprintf( buffer+len, "PVID: 0x%x, vendor: %s\n", + pvid, (pvid & (1<<15) ? "IBM" : "Motorola")); + + return len; +} + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +/* + * IDE support. + */ +static int mcpn765_ide_ports_known = 0; +static ide_ioreg_t mcpn765_ide_regbase[MAX_HWIFS]; +static ide_ioreg_t mcpn765_ide_ctl_regbase[MAX_HWIFS]; +static ide_ioreg_t mcpn765_idedma_regbase; + +static void +mcpn765_ide_probe(void) +{ + struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C586_1, + NULL); + + if(pdev) { + mcpn765_ide_regbase[0]=pdev->resource[0].start; + mcpn765_ide_regbase[1]=pdev->resource[2].start; + mcpn765_ide_ctl_regbase[0]=pdev->resource[1].start; + mcpn765_ide_ctl_regbase[1]=pdev->resource[3].start; + mcpn765_idedma_regbase=pdev->resource[4].start; + } + + mcpn765_ide_ports_known = 1; + return; +} + +static void +mcpn765_ide_insw(ide_ioreg_t port, void *buf, int ns) +{ + ide_insw(port+_IO_BASE, buf, ns); + return; +} + +static void +mcpn765_ide_outsw(ide_ioreg_t port, void *buf, int ns) +{ + ide_outsw(port+_IO_BASE, buf, ns); + return; +} + +static int +mcpn765_ide_default_irq(ide_ioreg_t base) +{ + if (mcpn765_ide_ports_known == 0) + mcpn765_ide_probe(); + + if (base == mcpn765_ide_regbase[0]) + return 14; + else if (base == mcpn765_ide_regbase[1]) + return 14; + else + return 0; +} + +static ide_ioreg_t +mcpn765_ide_default_io_base(int index) +{ + if (mcpn765_ide_ports_known == 0) + mcpn765_ide_probe(); + + return mcpn765_ide_regbase[index]; +} + +static int +mcpn765_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void +mcpn765_ide_request_region(ide_ioreg_t from, + unsigned int extent, + const char *name) +{ + request_region(from, extent, name); + return; +} + +static void +mcpn765_ide_release_region(ide_ioreg_t from, + unsigned int extent) +{ + release_region(from, extent); + return; +} + +static void +mcpn765_ide_fix_driveid(struct hd_driveid *id) +{ + ppc_generic_ide_fix_driveid(id); + return; +} + +static void __init +mcpn765_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + uint alt_status_base; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg++; + } + + if (data_port == mcpn765_ide_regbase[0]) { + alt_status_base = mcpn765_ide_ctl_regbase[0] + 2; + hw->irq = 14; + } + else if (data_port == mcpn765_ide_regbase[1]) { + alt_status_base = mcpn765_ide_ctl_regbase[1] + 2; + hw->irq = 14; + } + else { + alt_status_base = 0; + hw->irq = 0; + } + + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = alt_status_base; + } + + if (irq != NULL) { + *irq = hw->irq; + } + + return; +} +#endif + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space. + */ +static __inline__ void +mcpn765_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) { + + __asm__ __volatile__( + " lis %0,0xf000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + :: "r" (bat3u), "r" (bat3l)); + + mapping_set = 1; + } + + return; +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG +#include +#include +#include + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in */ +}; + +void +mcpn765_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned long com_port; + u16 shift; + + com_port = rs_table[0].port; + shift = rs_table[0].iomem_reg_shift; + + while ((c = *s++) != 0) { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = c; + + if (c == '\n') { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + } + } +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +__init void mcpn765_setup_pci_ptrs(void); + +void __init +mcpn765_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ +#ifdef CONFIG_BLK_DEV_INITRD + if ( r4 ) + { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif + + /* Copy cmd_line parameters */ + if ( r6 && (((char *) r6) != '\0')) { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } + + /* Map in board regs, etc. */ + mcpn765_set_bat(); + + todc_info = &m48t37_info; + todc_info->nvram_as0 = (u_char *)MCPN765_NVRAM_AS0; + todc_info->nvram_as1 = (u_char *)MCPN765_NVRAM_AS1; + todc_info->nvram_data = (u_char *)MCPN765_NVRAM_DATA; + + isa_io_base = MCPN765_ISA_IO_BASE; + isa_mem_base = MCPN765_ISA_MEM_BASE; + pci_dram_offset = MCPN765_PCI_DRAM_OFFSET; + ISA_DMA_THRESHOLD = 0x00ffffff; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + + ppc_md.setup_arch = mcpn765_setup_arch; + ppc_md.setup_residual = NULL; + ppc_md.get_cpuinfo = mcpn765_get_cpuinfo; + ppc_md.irq_cannonicalize = mcpn765_irq_cannonicalize; + ppc_md.init_IRQ = mcpn765_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + ppc_md.post_irq = NULL; + ppc_md.init = mcpn765_init2; + + ppc_md.restart = mcpn765_restart; + ppc_md.power_off = mcpn765_power_off; + ppc_md.halt = mcpn765_halt; + + ppc_md.find_end_of_memory = mcpn765_find_end_of_memory; + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + + ppc_md.heartbeat = NULL; + ppc_md.heartbeat_reset = 0; + ppc_md.heartbeat_count = 0; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = mcpn765_progress; +#else /* !CONFIG_SERIAL_TEXT_DEBUG */ + ppc_md.progress = NULL; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + + ppc_md.nvram_read_val = todc_m48txx_read_val; + ppc_md.nvram_write_val = todc_m48txx_write_val; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ppc_ide_md.insw = mcpn765_ide_insw; + ppc_ide_md.outsw = mcpn765_ide_outsw; + ppc_ide_md.default_irq = mcpn765_ide_default_irq; + ppc_ide_md.default_io_base = mcpn765_ide_default_io_base; + ppc_ide_md.ide_check_region = mcpn765_ide_check_region; + ppc_ide_md.ide_request_region = mcpn765_ide_request_region; + ppc_ide_md.ide_release_region = mcpn765_ide_release_region; + ppc_ide_md.fix_driveid = mcpn765_ide_fix_driveid; + ppc_ide_md.ide_init_hwif = mcpn765_ide_init_hwif_ports; +#endif + ppc_ide_md.io_base = _IO_BASE; + + return; +} diff -Nru a/arch/ppc/kernel/menf1.h b/arch/ppc/kernel/menf1.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/menf1.h Sat Jun 16 06:00:31 2001 @@ -0,0 +1,26 @@ +/* + * arch/ppc/kernel/menf1.h + * + * Definitions for MEN F1 board support + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef _PPC_KERNEL_MENF1_H +#define _PPC_KERNEL_MENF1_H + +#define MENF1_NVRAM_AS0 0x70 +#define MENF1_NVRAM_AS1 0x72 +#define MENF1_NVRAM_DATA 0x71 + +#define MENF1_IDE0_BASE_ADDR 0x1f0 +#define MENF1_IDE1_BASE_ADDR 0x170 + +#endif /* _PPC_KERNEL_MENF1_H */ diff -Nru a/arch/ppc/kernel/menf1_pci.c b/arch/ppc/kernel/menf1_pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/menf1_pci.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,88 @@ +/* + * arch/ppc/kernel/menf1_pci.c + * + * PCI support for MEN F1 + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pci.h" +#include "pci_auto.h" +#include "mpc10x.h" +#include "menf1.h" + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +static inline int __init +menf1_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {10, 11, 7, 9}, /* IDSEL 26 - PCMIP 0 */ + {0, 0, 0, 0}, /* IDSEL 27 - M5229 IDE */ + {0, 0, 0, 0}, /* IDSEL 28 - M7101 PMU */ + {9, 10, 11, 7}, /* IDSEL 29 - PCMIP 1 */ + {10, 11, 7, 9}, /* IDSEL 30 - P2P Bridge */ + }; + const long min_idsel = 26, max_idsel = 30, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +void __init +menf1_find_bridges(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + + mpc10x_bridge_init(hose, + MPC10X_MEM_MAP_A, + MPC10X_MEM_MAP_B, + MPC10X_MAPB_EUMB_BASE); + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + +#if 1 + { + /* Add ISA bus wait states */ + unsigned char isa_control; + + early_read_config_byte(hose, 0, 0x90, 0x43, &isa_control); + isa_control |= 0x33; + early_write_config_byte(hose, 0, 0x90, 0x43, isa_control); + } +#endif + + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = menf1_map_irq; +} diff -Nru a/arch/ppc/kernel/menf1_setup.c b/arch/ppc/kernel/menf1_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/menf1_setup.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,291 @@ +/* + * arch/ppc/kernel/menf1_setup.c + * + * Board setup routines for MEN F1 + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "local_irq.h" +#include "i8259.h" +#include "mpc10x.h" +#include "todc.h" +#include "menf1.h" + +extern void menf1_find_bridges(void); +extern unsigned long loops_per_jiffy; + +/* Dummy variable to satisfy mpc10x_common.o */ +void *OpenPIC_Addr; + +int +menf1_get_cpuinfo(char *buffer) +{ + int len; + + len = sprintf(buffer,"machine\t\t: MEN F1\n"); + + return len; +} + +void __init +menf1_setup_arch(void) +{ + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Lookup PCI host bridges */ + menf1_find_bridges(); + +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0302); /* /dev/hda2 */ +#endif + + printk("MEN F1 port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); +} + +void +menf1_restart(char *cmd) +{ + __cli(); + /* SRR0 has system reset vector, SRR1 has default MSR value */ + /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ + __asm__ __volatile__ + ("\n\ + lis 3,0xfff0 + ori 3,3,0x0100 + mtspr 26,3 + li 3,0 + mtspr 27,3 + rfi + "); + while(1); +} + +void +menf1_halt(void) +{ + __cli(); + while (1); +} + +void +menf1_power_off(void) +{ + menf1_halt(); +} + +void __init +menf1_init_IRQ(void) +{ + int i; + + for ( i = 0 ; i < NUM_8259_INTERRUPTS ; i++ ) + irq_desc[i].handler = &i8259_pic; + i8259_init(); +} + +int menf1_get_irq(struct pt_regs *regs) +{ + return i8259_irq(0); +} + +/* + * Set BAT 3 to map 0x80000000. + */ +static __inline__ void +menf1_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) + { + __asm__ __volatile__( + " lis %0,0x8000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + :: "r" (bat3u), "r" (bat3l)); + + mapping_set = 1; + } + return; +} + +unsigned long __init +menf1_find_end_of_memory(void) +{ + /* Cover the I/O with a BAT */ + menf1_set_bat(); + + /* Read the memory size from the MPC107 SMC */ + return mpc10x_get_mem_size(MPC10X_MEM_MAP_A); +} + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +/* IDE functions */ +void +menf1_ide_insw(ide_ioreg_t port, void *buf, int ns) +{ + ide_insw(((port)+(_IO_BASE)), buf, ns); +} + +void +menf1_ide_outsw(ide_ioreg_t port, void *buf, int ns) +{ + ide_outsw(((port)+_IO_BASE), buf, ns); +} + +int +menf1_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +void +menf1_ide_request_region(ide_ioreg_t from, + unsigned int extent, + const char *name) +{ + request_region(from, extent, name); +} + +void +menf1_ide_release_region(ide_ioreg_t from, + unsigned int extent) +{ + release_region(from, extent); +} + +void __init +menf1_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + int i = 8; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg; + reg += 1; + } + if (ctrl_port) + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + else + hw->io_ports[IDE_CONTROL_OFFSET] = + hw->io_ports[IDE_DATA_OFFSET] + 0x206; + + if (irq != NULL) + *irq = 0; +} + +static int +menf1_ide_default_irq(ide_ioreg_t base) +{ + if (base == MENF1_IDE0_BASE_ADDR) + return 14; + else if (base == MENF1_IDE1_BASE_ADDR) + return 15; + else + return 0; +} + +static ide_ioreg_t +menf1_ide_default_io_base(int index) +{ + if (index == 0) + return MENF1_IDE0_BASE_ADDR; + else if (index == 1) + return MENF1_IDE1_BASE_ADDR; + else + return 0; +} +#endif + +void __init +menf1_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + /* Copy cmd_line parameters */ + if (r6 && (((char *) r6) != '\0')) + { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } + + todc_info = &m48t59_info; + todc_info->nvram_as0 = (u_char *)MENF1_NVRAM_AS0; + todc_info->nvram_as1 = (u_char *)MENF1_NVRAM_AS1; + todc_info->nvram_data = (u_char *)MENF1_NVRAM_DATA; + todc_info->as0_bits = 7; + + isa_io_base = MPC10X_MAPB_ISA_IO_BASE; + isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE; + pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET; + + ppc_md.setup_arch = menf1_setup_arch; + ppc_md.get_cpuinfo = menf1_get_cpuinfo; + ppc_md.init_IRQ = menf1_init_IRQ; + ppc_md.get_irq = menf1_get_irq; + + ppc_md.find_end_of_memory = menf1_find_end_of_memory; + + ppc_md.restart = menf1_restart; + ppc_md.power_off = menf1_power_off; + ppc_md.halt = menf1_halt; + + ppc_md.time_init = todc_time_init; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + + ppc_md.nvram_read_val = todc_m48txx_read_val; + ppc_md.nvram_write_val = todc_m48txx_write_val; + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ppc_ide_md.insw = menf1_ide_insw; + ppc_ide_md.outsw = menf1_ide_outsw; + ppc_ide_md.default_io_base = menf1_ide_default_io_base; + ppc_ide_md.default_irq = menf1_ide_default_irq; + ppc_ide_md.ide_check_region = menf1_ide_check_region; + ppc_ide_md.ide_request_region = menf1_ide_request_region; + ppc_ide_md.ide_release_region = menf1_ide_release_region; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; + ppc_ide_md.ide_init_hwif = menf1_ide_init_hwif_ports; +#endif +} diff -Nru a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S --- a/arch/ppc/kernel/misc.S Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/kernel/misc.S Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.misc.S 1.16 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * This file contains miscellaneous low-level functions. @@ -17,11 +17,13 @@ #include #include +#include #include #include #include #include #include +#include #include "ppc_asm.h" .text @@ -216,7 +218,7 @@ tlbia sync #ifdef CONFIG_SMP - tlbsync + TLBSYNC sync li r0,0 stw r0,0(r9) /* clear hash_table_lock */ @@ -249,7 +251,7 @@ tlbie r3 sync #ifdef CONFIG_SMP - tlbsync + TLBSYNC sync li r0,0 stw r0,0(r9) /* clear hash_table_lock */ @@ -263,10 +265,13 @@ * This is a no-op on the 601. */ _GLOBAL(flush_instruction_cache) -#ifdef CONFIG_8xx +#if defined(CONFIG_8xx) isync lis r5, IDC_INVALL@h mtspr IC_CST, r5 +#elif defined(CONFIG_4xx) + lis r3, KERNELBASE@h + iccci 0,r3 #else mfspr r3,PVR rlwinm r3,r3,16,16,31 @@ -338,9 +343,9 @@ * snoop from the data cache. * This is a no-op on the 601 which has a unified cache. * - * void __flush_page_to_ram(void *page) + * void __flush_dcache_icache(void *page) */ -_GLOBAL(__flush_page_to_ram) +_GLOBAL(__flush_dcache_icache) mfspr r5,PVR rlwinm r5,r5,16,16,31 cmpi 0,r5,1 @@ -360,28 +365,6 @@ sync isync blr - -/* - * Flush a particular page from the instruction cache. - * Note: this is necessary because the instruction cache does *not* - * snoop from the data cache. - * This is a no-op on the 601 which has a unified cache. - * - * void __flush_icache_page(void *page) - */ -_GLOBAL(__flush_icache_page) - mfspr r5,PVR - rlwinm r5,r5,16,16,31 - cmpi 0,r5,1 - beqlr /* for 601, do nothing */ - li r4,4096/CACHE_LINE_SIZE /* Number of lines in a page */ - mtctr r4 -1: icbi 0,r3 - addi r3,r3,CACHE_LINE_SIZE - bdnz 1b - sync - isync - blr /* * Clear a page using the dcbz instruction, which doesn't cause any @@ -900,12 +883,10 @@ */ _GLOBAL(_set_L2CR) /* Make sure this is a 750 or 7400 chip */ - mfspr r4,PVR - rlwinm r4,r4,16,16,31 - cmpwi r4,0x0008 - cmpwi cr1,r4,0x000c - cror 2,2,4*cr1+2 - bne 99f +BEGIN_FTR_SECTION + li r3,-1 + blr +END_FTR_SECTION_IFCLR(CPU_FTR_L2CR) /* Turn off interrupts and data relocation. */ mfmsr r7 /* Save MSR in r7 */ @@ -1010,20 +991,12 @@ isync blr -99: li r3,-1 - blr - _GLOBAL(_get_L2CR) - /* Make sure this is a 750 chip */ - mfspr r3,PVR - srwi r3,r3,16 - cmpwi r3,0x0008 - cmpwi cr1,r3,0x000c - li r3,0 - cror 2,2,4*cr1+2 - bnelr /* Return the L2CR contents */ + li r3,0 +BEGIN_FTR_SECTION mfspr r3,L2CR +END_FTR_SECTION_IFSET(CPU_FTR_L2CR) blr /* --- End of PowerLogix code --- @@ -1096,6 +1069,49 @@ li r0,__NR_exit /* exit after child exits */ li r3,0 sc + +#if defined(CONFIG_SPRUCE) +_GLOBAL(spruce_read_keyb_status) + addis r5,0,0xff50 + addi r6,0,0x88 + stw r6,0x8(r5) + eieio + + addis r6,0,0x300 + stw r6,0xc(r5) + eieio + + addis r7,0,0xff88 + ori r7,r7,0x8 + lswi r3,r7,0x8 + srwi r3,r3,0x18 + + addi r6,0,0 + stw r6,0xc(r5) + eieio + + blr + +_GLOBAL(spruce_read_keyb_data) + addis r5,0,0xff50 + addi r6,0,0x88 + stw r6,0x8(r5) + eieio + + addis r6,0,0x300 + stw r6,0xc(r5) + eieio + + addis r7,0,0xff88 + lswi r3,r7,0x8 + srwi r3,r3,0x18 + + addi r6,0,0 + stw r6,0xc(r5) + eieio + + blr +#endif /* * This routine is just here to keep GCC happy - sigh... diff -Nru a/arch/ppc/kernel/mk_defs.c b/arch/ppc/kernel/mk_defs.c --- a/arch/ppc/kernel/mk_defs.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/kernel/mk_defs.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mk_defs.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * This program is used to generate definitions needed by @@ -26,6 +26,7 @@ #include #include #include +#include #define DEFINE(sym, val) \ asm volatile("\n#define\t" #sym "\t%0" : : "i" (val)) @@ -117,5 +118,13 @@ DEFINE(RESULT, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, result)); DEFINE(TRAP, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, trap)); DEFINE(CLONE_VM, CLONE_VM); + DEFINE(MM_PGD, offsetof(struct mm_struct, pgd)); + + /* About the CPU features table */ + DEFINE(CPU_SPEC_ENTRY_SIZE, sizeof(struct cpu_spec)); + DEFINE(CPU_SPEC_PVR_MASK, offsetof(struct cpu_spec, pvr_mask)); + DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value)); + DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features)); + DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup)); return 0; } diff -Nru a/arch/ppc/kernel/mpc10x.h b/arch/ppc/kernel/mpc10x.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/mpc10x.h Sat Jun 16 06:00:31 2001 @@ -0,0 +1,158 @@ +/* + * arch/ppc/kernel/mpc10x.h + * + * Common routines for the Motorola SPS MPC106/8240/107 Host bridge/Mem + * ctlr/EPIC/etc. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __PPC_KERNEL_MPC10X_H +#define __PPC_KERNEL_MPC10X_H + +#include + +#include "pci.h" + +/* + * The values here don't completely map everything but should work in most + * cases. + * + * MAP A (PReP Map) + * Processor: 0x80000000 - 0x807fffff -> PCI I/O: 0x00000000 - 0x007fffff + * Processor: 0xc0000000 - 0xdfffffff -> PCI MEM: 0x00000000 - 0x1fffffff + * PCI MEM: 0x80000000 -> Processor System Memory: 0x00000000 + * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB) + * + * MAP B (CHRP Map) + * Processor: 0xfe000000 - 0xfebfffff -> PCI I/O: 0x00000000 - 0x00bfffff + * Processor: 0x80000000 - 0xbfffffff -> PCI MEM: 0x80000000 - 0xbfffffff + * PCI MEM: 0x00000000 -> Processor System Memory: 0x00000000 + * EUMB mapped to: ioremap_base - 0x00100000 (ioremap_base - 1 MB) + */ + +/* + * Define the vendor/device IDs for the various bridges--should be added to + * + */ +#define MPC10X_BRIDGE_106 ((PCI_DEVICE_ID_MOTOROLA_MPC106 << 16) | \ + PCI_VENDOR_ID_MOTOROLA) +#define MPC10X_BRIDGE_8240 ((0x0003 << 16) | PCI_VENDOR_ID_MOTOROLA) +#define MPC10X_BRIDGE_107 ((0x0004 << 16) | PCI_VENDOR_ID_MOTOROLA) + +/* Define the type of map to use */ +#define MPC10X_MEM_MAP_A 1 +#define MPC10X_MEM_MAP_B 2 + +/* Map A (PReP Map) Defines */ +#define MPC10X_MAPA_CNFG_ADDR 0x80000cf8 +#define MPC10X_MAPA_CNFG_DATA 0x80000cfc + +#define MPC10X_MAPA_ISA_IO_BASE 0x80000000 +#define MPC10X_MAPA_ISA_MEM_BASE 0xc0000000 +#define MPC10X_MAPA_DRAM_OFFSET 0x80000000 + +#define MPC10X_MAPA_PCI_IO_START 0x00000000 +#define MPC10X_MAPA_PCI_IO_END (0x00800000 - 1) +#define MPC10X_MAPA_PCI_MEM_START 0x00000000 +#define MPC10X_MAPA_PCI_MEM_END (0x20000000 - 1) + +#define MPC10X_MAPA_PCI_MEM_OFFSET (MPC10X_MAPA_ISA_MEM_BASE - \ + MPC10X_MAPA_PCI_MEM_START) + +/* Map B (CHRP Map) Defines */ +#define MPC10X_MAPB_CNFG_ADDR 0xfec00000 +#define MPC10X_MAPB_CNFG_DATA 0xfee00000 + +#define MPC10X_MAPB_ISA_IO_BASE 0xfe000000 +#define MPC10X_MAPB_ISA_MEM_BASE 0x80000000 +#define MPC10X_MAPB_DRAM_OFFSET 0x00000000 + +#define MPC10X_MAPB_PCI_IO_START 0x00000000 +#define MPC10X_MAPB_PCI_IO_END (0x00c00000 - 1) +#define MPC10X_MAPB_PCI_MEM_START 0x80000000 +#define MPC10X_MAPB_PCI_MEM_END (0xc0000000 - 1) + +#define MPC10X_MAPB_PCI_MEM_OFFSET (MPC10X_MAPB_ISA_MEM_BASE - \ + MPC10X_MAPB_PCI_MEM_START) + +/* Set hose members to values appropriate for the mem map used */ +#define MPC10X_SETUP_HOSE(hose, map) { \ + (hose)->pci_mem_offset = MPC10X_MAP##map##_PCI_MEM_OFFSET; \ + (hose)->io_space.start = MPC10X_MAP##map##_PCI_IO_START; \ + (hose)->io_space.end = MPC10X_MAP##map##_PCI_IO_END; \ + (hose)->mem_space.start = MPC10X_MAP##map##_PCI_MEM_START; \ + (hose)->mem_space.end = MPC10X_MAP##map##_PCI_MEM_END; \ + (hose)->io_base_virt = (void *)MPC10X_MAP##map##_ISA_IO_BASE; \ +} + + +/* Miscellaneous Configuration register offsets */ +#define MPC10X_CFG_PIR_REG 0x09 +#define MPC10X_CFG_PIR_HOST_BRIDGE 0x00 +#define MPC10X_CFG_PIR_AGENT 0x01 + +#define MPC10X_CFG_EUMBBAR 0x78 + +#define MPC10X_CFG_PICR1_REG 0xa8 +#define MPC10X_CFG_PICR1_ADDR_MAP_MASK 0x00010000 +#define MPC10X_CFG_PICR1_ADDR_MAP_A 0x00010000 +#define MPC10X_CFG_PICR1_ADDR_MAP_B 0x00000000 + +#define MPC10X_CFG_MAPB_OPTIONS_REG 0xe0 +#define MPC10X_CFG_MAPB_OPTIONS_CFAE 0x80 /* CPU_FD_ALIAS_EN */ +#define MPC10X_CFG_MAPB_OPTIONS_PFAE 0x40 /* PCI_FD_ALIAS_EN */ +#define MPC10X_CFG_MAPB_OPTIONS_DR 0x20 /* DLL_RESET */ +#define MPC10X_CFG_MAPB_OPTIONS_PCICH 0x80 /* PCI_COMPATIBILITY_HOLE */ +#define MPC10X_CFG_MAPB_OPTIONS_PROCCH 0x40 /* PROC_COMPATIBILITY_HOLE */ + +/* Define offsets for the memory controller registers in the config space */ +#define MPC10X_MCTLR_MEM_START_1 0x80 /* Banks 0-3 */ +#define MPC10X_MCTLR_MEM_START_2 0x84 /* Banks 4-7 */ +#define MPC10X_MCTLR_EXT_MEM_START_1 0x88 /* Banks 0-3 */ +#define MPC10X_MCTLR_EXT_MEM_START_2 0x8c /* Banks 4-7 */ + +#define MPC10X_MCTLR_MEM_END_1 0x90 /* Banks 0-3 */ +#define MPC10X_MCTLR_MEM_END_2i 0x94 /* Banks 4-7 */ +#define MPC10X_MCTLR_EXT_MEM_END_1 0x98 /* Banks 0-3 */ +#define MPC10X_MCTLR_EXT_MEM_END_2 0x9c /* Banks 4-7 */ + +#define MPC10X_MCTLR_MEM_BANK_ENABLES 0xa0 + +/* Define some offset in the EUMB */ +#define MPC10X_EUMB_SIZE 0x00100000 /* Total EUMB size (1MB) */ + +#define MPC10X_EUMB_MU_OFFSET 0x00000000 /* Msg Unit reg offset */ +#define MPC10X_EUMB_MU_SIZE 0x00001000 /* Msg Unit reg size */ +#define MPC10X_EUMB_DMA_OFFSET 0x00001000 /* DMA Unit reg offset */ +#define MPC10X_EUMB_DMA_SIZE 0x00001000 /* DMA Unit reg size */ +#define MPC10X_EUMB_ATU_OFFSET 0x00002000 /* Addr xlate reg offset */ +#define MPC10X_EUMB_ATU_SIZE 0x00001000 /* Addr xlate reg size */ +#define MPC10X_EUMB_I2C_OFFSET 0x00003000 /* I2C Unit reg offset */ +#define MPC10X_EUMB_I2C_SIZE 0x00001000 /* I2C Unit reg size */ +#define MPC10X_EUMB_EPIC_OFFSET 0x00040000 /* EPIC offset in EUMB */ +#define MPC10X_EUMB_EPIC_SIZE 0x00030000 /* EPIC size */ + +/* + * Define some recommended places to put the EUMB regs. + * For both maps, recommend putting the EUMB from 0xeff00000 to 0xefffffff. + */ +extern unsigned long ioremap_base; +#define MPC10X_MAPA_EUMB_BASE (ioremap_base - MPC10X_EUMB_SIZE) +#define MPC10X_MAPB_EUMB_BASE MPC10X_MAPA_EUMB_BASE + + +int mpc10x_bridge_init(struct pci_controller *hose, + uint current_map, + uint new_map, + uint phys_eumb_base); +unsigned long mpc10x_get_mem_size(uint mem_map); + +#endif /* __PPC_KERNEL_MPC10X_H */ diff -Nru a/arch/ppc/kernel/mpc10x_common.c b/arch/ppc/kernel/mpc10x_common.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/mpc10x_common.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,310 @@ +/* + * arch/ppc/kernel/mpc10x_common.c + * + * Common routines for the Motorola SPS MPC106, MPC107 and MPC8240 Host bridge, + * Mem ctlr, EPIC, etc. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * *** WARNING - A BAT MUST be set to access the PCI config addr/data regs *** + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pci.h" +#include "open_pic.h" +#include "mpc10x.h" + + +/* + * Do some initialization and put the EUMB registers at the specified address + * (also map the EPIC registers into virtual space--OpenPIC_Addr will be set). + * + * The EPIC is not on the 106, only the 8240 and 107. + */ +int __init +mpc10x_bridge_init(struct pci_controller *hose, + uint current_map, + uint new_map, + uint phys_eumb_base) +{ + int host_bridge, picr1, picr1_bit; + ulong pci_config_addr, pci_config_data; + u_char pir, byte; + + if (ppc_md.progress) ppc_md.progress("mpc10x:enter", 0x100); + + /* Set up for current map so we can get at config regs */ + switch (current_map) { + case MPC10X_MEM_MAP_A: + setup_indirect_pci(hose, + MPC10X_MAPA_CNFG_ADDR, + MPC10X_MAPA_CNFG_DATA); + break; + case MPC10X_MEM_MAP_B: + setup_indirect_pci(hose, + MPC10X_MAPB_CNFG_ADDR, + MPC10X_MAPB_CNFG_DATA); + break; + default: + printk("mpc10x_bridge_init: %s\n", + "Invalid current map specified"); + if (ppc_md.progress) + ppc_md.progress("mpc10x:exit1", 0x100); + return -1; + } + + /* Make sure its a supported bridge */ + early_read_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_VENDOR_ID, + &host_bridge); + + switch (host_bridge) { + case MPC10X_BRIDGE_106: + case MPC10X_BRIDGE_8240: + case MPC10X_BRIDGE_107: + break; + default: + if (ppc_md.progress) + ppc_md.progress("mpc10x:exit2", 0x100); + return -1; + } + + switch (new_map) { + case MPC10X_MEM_MAP_A: + MPC10X_SETUP_HOSE(hose, A); + pci_config_addr = MPC10X_MAPA_CNFG_ADDR; + pci_config_data = MPC10X_MAPA_CNFG_DATA; + picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_A; + break; + case MPC10X_MEM_MAP_B: + MPC10X_SETUP_HOSE(hose, B); + pci_config_addr = MPC10X_MAPB_CNFG_ADDR; + pci_config_data = MPC10X_MAPB_CNFG_DATA; + picr1_bit = MPC10X_CFG_PICR1_ADDR_MAP_B; + break; + default: + printk("mpc10x_bridge_init: %s\n", + "Invalid new map specified"); + if (ppc_md.progress) + ppc_md.progress("mpc10x:exit3", 0x100); + return -1; + } + + /* Make bridge use the 'new_map', if not already usng it */ + if (current_map != new_map) { + early_read_config_dword(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_PICR1_REG, + &picr1); + + picr1 = (picr1 & ~MPC10X_CFG_PICR1_ADDR_MAP_MASK) | + picr1_bit; + + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_PICR1_REG, + picr1); + + asm volatile("sync"); + + /* Undo old mappings & map in new cfg data/addr regs */ + iounmap((void *)hose->cfg_addr); + iounmap((void *)hose->cfg_data); + + setup_indirect_pci(hose, + pci_config_addr, + pci_config_data); + } + + /* + * Want processor accesses of 0xFDxxxxxx to be mapped + * to PCI memory space at 0x00000000. Do not want + * host bridge to respond to PCI memory accesses of + * 0xFDxxxxxx. Do not want host bridge to respond + * to PCI memory addresses 0xFD000000-0xFDFFFFFF; + * want processor accesses from 0x000A0000-0x000BFFFF + * to be forwarded to system memory. + * + * Only valid if not in agent mode and using MAP B. + */ + if (new_map == MPC10X_MEM_MAP_B) { + early_read_config_byte(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_MAPB_OPTIONS_REG, + &byte); + + byte &= ~(MPC10X_CFG_MAPB_OPTIONS_PFAE | + MPC10X_CFG_MAPB_OPTIONS_PCICH | + MPC10X_CFG_MAPB_OPTIONS_PROCCH); + + if (host_bridge != MPC10X_BRIDGE_106) { + byte |= MPC10X_CFG_MAPB_OPTIONS_CFAE; + } + + early_write_config_byte(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_MAPB_OPTIONS_REG, + byte); + } + + if (host_bridge != MPC10X_BRIDGE_106) { + early_read_config_byte(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_PIR_REG, + &pir); + + if (pir != MPC10X_CFG_PIR_HOST_BRIDGE) { + printk("Host bridge in Agent mode\n"); + /* Read or Set LMBAR & PCSRBAR? */ + } + + /* Set base addr of the 8240/107 EUMB. */ + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + MPC10X_CFG_EUMBBAR, + phys_eumb_base); + + /* Map EPIC register part of EUMB into vitual memory */ + OpenPIC_Addr = + ioremap(phys_eumb_base + MPC10X_EUMB_EPIC_OFFSET, + MPC10X_EUMB_EPIC_SIZE); + } + + if (ppc_md.progress) ppc_md.progress("mpc10x:exit", 0x100); + return 0; +} + +/* + * Need to make our own PCI config space access macros because + * mpc10x_get_mem_size() is called before the data structures are set up for + * the 'early_xxx' and 'indirect_xxx' routines to work. + * Assumes bus 0. + */ +#define MPC10X_CFG_read(val, addr, type, op) *val = op((type)(addr)) +#define MPC10X_CFG_write(val, addr, type, op) op((type *)(addr), (val)) + +#define MPC10X_PCI_OP(rw, size, type, op, mask) \ +static void \ +mpc10x_##rw##_config_##size(uint *cfg_addr, uint *cfg_data, int devfn, int offset, type val) \ +{ \ + out_be32(cfg_addr, \ + ((offset & 0xfc) << 24) | (devfn << 16) \ + | (0 << 8) | 0x80); \ + MPC10X_CFG_##rw(val, cfg_data + (offset & mask), type, op); \ + return; \ +} + +MPC10X_PCI_OP(read, byte, u8 *, in_8, 3) +MPC10X_PCI_OP(read, dword, u32 *, in_le32, 0) +#if 0 /* Not used */ +MPC10X_PCI_OP(write, byte, u8, out_8, 3) +MPC10X_PCI_OP(read, word, u16 *, in_le16, 2) +MPC10X_PCI_OP(write, word, u16, out_le16, 2) +MPC10X_PCI_OP(write, dword, u32, out_le32, 0) +#endif + +/* + * Read the memory controller registers to determine the amount of memory in + * the system. This assumes that the firmware has correctly set up the memory + * controller registers. + */ +unsigned long __init +mpc10x_get_mem_size(uint mem_map) +{ + uint *config_addr, *config_data, val; + ulong start, end, total, offset; + int i; + u_char bank_enables; + + switch (mem_map) { + case MPC10X_MEM_MAP_A: + config_addr = (uint *)MPC10X_MAPA_CNFG_ADDR; + config_data = (uint *)MPC10X_MAPA_CNFG_DATA; + break; + case MPC10X_MEM_MAP_B: + config_addr = (uint *)MPC10X_MAPB_CNFG_ADDR; + config_data = (uint *)MPC10X_MAPB_CNFG_DATA; + break; + default: + return 0; + } + + mpc10x_read_config_byte(config_addr, + config_data, + PCI_DEVFN(0,0), + MPC10X_MCTLR_MEM_BANK_ENABLES, + &bank_enables); + + total = 0; + + for (i=0; i<8; i++) { + if (bank_enables & (1 << i)) { + offset = MPC10X_MCTLR_MEM_START_1 + ((i > 3) ? 4 : 0); + mpc10x_read_config_dword(config_addr, + config_data, + PCI_DEVFN(0,0), + offset, + &val); + start = (val >> ((i & 3) << 3)) & 0xff; + + offset = MPC10X_MCTLR_EXT_MEM_START_1 + ((i>3) ? 4 : 0); + mpc10x_read_config_dword(config_addr, + config_data, + PCI_DEVFN(0,0), + offset, + &val); + val = (val >> ((i & 3) << 3)) & 0x03; + start = (val << 28) | (start << 20); + + offset = MPC10X_MCTLR_MEM_END_1 + ((i > 3) ? 4 : 0); + mpc10x_read_config_dword(config_addr, + config_data, + PCI_DEVFN(0,0), + offset, + &val); + end = (val >> ((i & 3) << 3)) & 0xff; + + offset = MPC10X_MCTLR_EXT_MEM_END_1 + ((i > 3) ? 4 : 0); + mpc10x_read_config_dword(config_addr, + config_data, + PCI_DEVFN(0,0), + offset, + &val); + val = (val >> ((i & 3) << 3)) & 0x03; + end = (val << 28) | (end << 20) | 0xfffff; + + total += (end - start + 1); + } + } + + return total; +} diff -Nru a/arch/ppc/kernel/mvme5100.h b/arch/ppc/kernel/mvme5100.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/mvme5100.h Sat Jun 16 06:00:31 2001 @@ -0,0 +1,67 @@ +/* + * arch/ppc/kernel/mvme5100.h + * + * Definitions for Motorola MVME5100. + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __PPC_KERNEL_MVME5100_H +#define __PPC_KERNEL_MVME5100_H + +#define MVME5100_HAWK_SMC_BASE 0xfef80000 + +#define MVME5100_PCI_CONFIG_ADDR 0xfe000cf8 +#define MVME5100_PCI_CONFIG_DATA 0xfe000cfc + +#define MVME5100_PCI_IO_BASE 0xfe000000 +#define MVME5100_PCI_MEM_BASE 0x80000000 + +#define MVME5100_PCI_MEM_OFFSET 0x00000000 + +#define MVME5100_PCI_DRAM_OFFSET 0x00000000 +#define MVME5100_ISA_MEM_BASE 0x00000000 +#define MVME5100_ISA_IO_BASE MVME5100_PCI_IO_BASE + +/* MVME5100 board register addresses. */ +#define MVME5100_BOARD_STATUS_REG 0xfef88080 +#define MVME5100_BOARD_MODFAIL_REG 0xfef88090 +#define MVME5100_BOARD_MODRST_REG 0xfef880a0 +#define MVME5100_BOARD_TBEN_REG 0xfef880c0 +#define MVME5100_BOARD_SW_READ_REG 0xfef880e0 +#define MVME5100_BOARD_GEO_ADDR_REG 0xfef880e8 +#define MVME5100_BOARD_EXT_FEATURE1_REG 0xfef880f0 +#define MVME5100_BOARD_EXT_FEATURE2_REG 0xfef88100 + +/* Define the NVRAM/RTC address strobe & data registers */ +#define MVME5100_PHYS_NVRAM_AS0 0xfef880c8 +#define MVME5100_PHYS_NVRAM_AS1 0xfef880d0 +#define MVME5100_PHYS_NVRAM_DATA 0xfef880d8 + +#define MVME5100_NVRAM_AS0 (MVME5100_PHYS_NVRAM_AS0 - MVME5100_ISA_IO_BASE) +#define MVME5100_NVRAM_AS1 (MVME5100_PHYS_NVRAM_AS1 - MVME5100_ISA_IO_BASE) +#define MVME5100_NVRAM_DATA (MVME5100_PHYS_NVRAM_DATA - MVME5100_ISA_IO_BASE) + +/* UART clock, addresses, and irq */ +#define MVME5100_BASE_BAUD 1843200 +#define MVME5100_SERIAL_1 0xfef88000 +#define MVME5100_SERIAL_2 0xfef88200 +#ifdef CONFIG_MVME5100_IPMC761_PRESENT +#define MVME5100_SERIAL_IRQ 17 +#else +#define MVME5100_SERIAL_IRQ 1 +#endif + +#define MVME5100_WINBOND_DEVFN 0x58 +#define MVME5100_WINBOND_VIDDID 0x056510ad + +extern void mvme5100_find_bridges(void); + +#endif /* __PPC_KERNEL_MVME5100_H */ diff -Nru a/arch/ppc/kernel/mvme5100_pci.c b/arch/ppc/kernel/mvme5100_pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/mvme5100_pci.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,107 @@ +/* + * arch/ppc/kernel/mvme5100_pci.c + * + * PCI setup routines for the Motorola MVME5100. + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pci.h" +#include "pplus.h" +#include "mvme5100.h" + +static inline int +mvme5100_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + int irq; + + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 0, 0, 0, 0 }, /* IDSEL 11 - Winbond */ + { 0, 0, 0, 0 }, /* IDSEL 12 - unused */ + { 21, 22, 23, 24 }, /* IDSEL 13 - Universe II */ + { 18, 0, 0, 0 }, /* IDSEL 14 - Enet 1 */ + { 0, 0, 0, 0 }, /* IDSEL 15 - unused */ + { 25, 26, 27, 28 }, /* IDSEL 16 - PMC Slot 1 */ + { 28, 25, 26, 27 }, /* IDSEL 17 - PMC Slot 2 */ + { 0, 0, 0, 0 }, /* IDSEL 18 - unused */ + { 29, 0, 0, 0 }, /* IDSEL 19 - Enet 2 */ + { 0, 0, 0, 0 }, /* IDSEL 20 - PMCSPAN */ + }; + + const long min_idsel = 11, max_idsel = 20, irqs_per_slot = 4; + irq = PCI_IRQ_TABLE_LOOKUP; + /* If lookup is zero, always return 0 */ + if (!irq) + return 0; + else +#ifdef CONFIG_MVME5100_IPMC761_PRESENT + /* If IPMC761 present, return table value */ + return irq; +#else + /* If IPMC761 not present, we don't have an i8259 so adjust */ + return (irq - NUM_8259_INTERRUPTS); +#endif +} + +void mvme5100_pcibios_fixup_resources(struct pci_dev *dev) +{ + int i; + + if ((dev->vendor == PCI_VENDOR_ID_MOTOROLA) && + (dev->device == PCI_DEVICE_ID_MOTOROLA_HAWK)) + for (i=0; iresource[i].start = 0; + dev->resource[i].end = 0; + } +} + +void __init +mvme5100_find_bridges(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + hose->pci_mem_offset = MVME5100_PCI_MEM_OFFSET; + hose->io_base_virt = (void *)MVME5100_ISA_IO_BASE; + + /* Use indirect method of Hawk */ + setup_indirect_pci(hose, + MVME5100_PCI_CONFIG_ADDR, + MVME5100_PCI_CONFIG_DATA); + + ppc_md.pcibios_fixup_resources = mvme5100_pcibios_fixup_resources; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = mvme5100_map_irq; + + return; +} diff -Nru a/arch/ppc/kernel/mvme5100_setup.c b/arch/ppc/kernel/mvme5100_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/mvme5100_setup.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,331 @@ +/* + * arch/ppc/kernel/mvme5100_setup.c + * + * Board setup routines for the Motorola MVME5100. + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pci.h" +#include "local_irq.h" +#include "open_pic.h" +#include "i8259.h" +#include "pplus.h" +#include "todc.h" +#include "mvme5100.h" + +/* + * If you want "progress" messages, define this macro below. + */ +#undef CONFIG_MVME5100_DEBUG + +extern char cmd_line[]; + +static u_char mvme5100_openpic_initsenses[] __initdata = { + 0, /* 16: i8259 cascade (active high) */ + 1, /* 17: TL16C550 UART 1,2 */ + 1, /* 18: Enet 1 (front panel or P2) */ + 1, /* 19: Hawk Watchdog 1,2 */ + 1, /* 20: DS1621 thermal alarm */ + 1, /* 21: Universe II LINT0# */ + 1, /* 22: Universe II LINT1# */ + 1, /* 23: Universe II LINT2# */ + 1, /* 24: Universe II LINT3# */ + 1, /* 25: PMC1 INTA#, PMC2 INTB# */ + 1, /* 26: PMC1 INTB#, PMC2 INTC# */ + 1, /* 27: PMC1 INTC#, PMC2 INTD# */ + 1, /* 28: PMC1 INTD#, PMC2 INTA# */ + 1, /* 29: Enet 2 (front panel) */ + 1, /* 30: Abort Switch */ + 1, /* 31: RTC Alarm */ +}; + +static void __init +mvme5100_setup_arch(void) +{ + extern char cmd_line[]; + + if ( ppc_md.progress ) + ppc_md.progress("mvme5100_setup_arch: enter", 0); + + loops_per_jiffy = 50000000 / HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 SCSI disk */ +#endif + + if ( ppc_md.progress ) + ppc_md.progress("mvme5100_setup_arch: find_bridges", 0); + + /* Lookup PCI host bridges */ + mvme5100_find_bridges(); + + /* Find and map our OpenPIC */ + pplus_mpic_init(MVME5100_PCI_MEM_OFFSET); + OpenPIC_InitSenses = mvme5100_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(mvme5100_openpic_initsenses); + + printk("MVME5100 port (C) 2001 MontaVista Software, Inc. \n"); + + if ( ppc_md.progress ) + ppc_md.progress("mvme5100_setup_arch: exit", 0); + + return; +} + +static void __init +mvme5100_init2(void) +{ +#ifdef CONFIG_MVME5100_IPMC761_PRESENT + request_region(0x00,0x20,"dma1"); + request_region(0x20,0x20,"pic1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xa0,0x20,"pic2"); + request_region(0xc0,0x20,"dma2"); +#endif + return; +} + +/* + * Interrupt setup and service. + * Have MPIC on HAWK and cascaded 8259s on Winbond cascaded to MPIC. + */ +static void __init +mvme5100_init_IRQ(void) +{ +#ifdef CONFIG_MVME5100_IPMC761_PRESENT + int i; +#endif + + if ( ppc_md.progress ) + ppc_md.progress("init_irq: enter", 0); + +#ifdef CONFIG_MVME5100_IPMC761_PRESENT + openpic_init(1, NUM_8259_INTERRUPTS, NULL, -1); + + for(i=0; i < NUM_8259_INTERRUPTS; i++) + irq_desc[i].handler = &i8259_pic; + + i8259_init(); +#else + openpic_init(1, 0, NULL, -1); +#endif + + if ( ppc_md.progress ) + ppc_md.progress("init_irq: exit", 0); + + return; +} + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space. + */ +static __inline__ void +mvme5100_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) { + + __asm__ __volatile__( + " lis %0,0xf000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + :: "r" (bat3u), "r" (bat3l)); + + mapping_set = 1; + } + + return; +} + +unsigned long __init +mvme5100_find_end_of_memory(void) +{ + mvme5100_set_bat(); + return pplus_get_mem_size(MVME5100_HAWK_SMC_BASE); +} + +static void +mvme5100_reset_board(void) +{ + __cli(); + + /* Set exception prefix high - to the firmware */ + _nmask_and_or_msr(0, MSR_IP); + + out_8((u_char *)MVME5100_BOARD_MODRST_REG, 0x01); + + return; +} + +static void +mvme5100_restart(char *cmd) +{ + volatile ulong i = 10000000; + + mvme5100_reset_board(); + + while (i-- > 0); + panic("restart failed\n"); +} + +static void +mvme5100_halt(void) +{ + __cli(); + while (1); +} + +static void +mvme5100_power_off(void) +{ + mvme5100_halt(); +} + +static int +mvme5100_get_cpuinfo(char *buffer) +{ + int len; + uint pvid; + + pvid = _get_PVR(); + + len = sprintf( buffer, "vendor\t\t: Motorola\n"); + + len += sprintf( buffer+len, "machine\t\t: MVME5100\n"); + + return len; +} + +#ifdef CONFIG_MVME5100_DEBUG +#include "../boot/include/ns16550.h" +void +mvme5100_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile struct NS16550 *com_port; + + mvme5100_set_bat(); + + com_port = (volatile struct NS16550 *)(COM1); + while ((c = *s++) != 0) { + while ((com_port->lsr & LSR_THRE) == 0) ; + com_port->thr = c; + if (c == '\n') { + while ((com_port->lsr & LSR_THRE) == 0) ; + com_port->thr = '\r'; + } + } + + while ((com_port->lsr & LSR_THRE) == 0) ; + com_port->thr = '\n'; + while ((com_port->lsr & LSR_THRE) == 0) ; + com_port->thr = '\r'; + + return; +} +#endif /* CONFIG_MVME5100_DEBUG */ + +void __init +mvme5100_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ +#ifdef CONFIG_BLK_DEV_INITRD + if ( r4 ) + { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif + + /* Copy cmd_line parameters */ + if ( r6 && (((char *) r6) != '\0')) { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } + + todc_info = &m48t37_info; + todc_info->nvram_as0 = (u_char *)MVME5100_NVRAM_AS0; + todc_info->nvram_as1 = (u_char *)MVME5100_NVRAM_AS1; + todc_info->nvram_data = (u_char *)MVME5100_NVRAM_DATA; + + isa_io_base = MVME5100_ISA_IO_BASE; + isa_mem_base = MVME5100_ISA_MEM_BASE; + pci_dram_offset = MVME5100_PCI_DRAM_OFFSET; + + ppc_md.setup_arch = mvme5100_setup_arch; + ppc_md.setup_residual = NULL; + ppc_md.get_cpuinfo = mvme5100_get_cpuinfo; + ppc_md.init_IRQ = mvme5100_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + ppc_md.post_irq = NULL; + ppc_md.init = mvme5100_init2; + + ppc_md.restart = mvme5100_restart; + ppc_md.power_off = mvme5100_power_off; + ppc_md.halt = mvme5100_halt; + + ppc_md.find_end_of_memory = mvme5100_find_end_of_memory; + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + +#ifdef CONFIG_MVME5100_DEBUG + ppc_md.progress = mvme5100_progress; +#else /* CONFIG_MVME5100_DEBUG */ + ppc_md.progress = NULL; +#endif /* CONFIG_MVME5100_DEBUG */ + + ppc_md.nvram_read_val = todc_m48txx_read_val; + ppc_md.nvram_write_val = todc_m48txx_write_val; + + return; +} diff -Nru a/arch/ppc/kernel/oak_setup.c b/arch/ppc/kernel/oak_setup.c --- a/arch/ppc/kernel/oak_setup.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/kernel/oak_setup.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.oak_setup.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * diff -Nru a/arch/ppc/kernel/oak_setup.h b/arch/ppc/kernel/oak_setup.h --- a/arch/ppc/kernel/oak_setup.h Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/kernel/oak_setup.h Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.oak_setup.h 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * diff -Nru a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c --- a/arch/ppc/kernel/open_pic.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/kernel/open_pic.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.open_pic.c 1.20 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling @@ -47,8 +47,8 @@ /* Global Operations */ static void openpic_disable_8259_pass_through(void); -static u_int openpic_irq(void); -static void openpic_eoi(void); +u_int openpic_irq(void); +void openpic_eoi(void); static void openpic_set_priority(u_int pri); static void openpic_set_spurious(u_int vector); @@ -435,7 +435,7 @@ /* * Find out the current interrupt */ -static u_int openpic_irq(void) +u_int openpic_irq(void) { u_int vec; DECL_THIS_CPU; @@ -446,7 +446,7 @@ return vec; } -static void openpic_eoi(void) +void openpic_eoi(void) { DECL_THIS_CPU; diff -Nru a/arch/ppc/kernel/open_pic.h b/arch/ppc/kernel/open_pic.h --- a/arch/ppc/kernel/open_pic.h Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/kernel/open_pic.h Sat Jun 16 06:00:18 2001 @@ -19,6 +19,14 @@ #define OPENPIC_SIZE 0x40000 +/* + * Non-offset'ed vector numbers + */ + +#define OPENPIC_VEC_TIMER 64 /* and up */ +#define OPENPIC_VEC_IPI 72 /* and up */ +#define OPENPIC_VEC_SPURIOUS 127 + /* OpenPIC IRQ controller structure */ extern struct hw_interrupt_type open_pic; @@ -42,7 +50,15 @@ extern inline int openpic_to_irq(int irq) { - return irq += NUM_8259_INTERRUPTS; + /* IRQ 0 usually means 'disabled'.. don't mess with it + * exceptions to this (sandpoint maybe?) + * shouldn't use openpic_to_irq + */ + if (irq != 0){ + return irq += NUM_8259_INTERRUPTS; + } else { + return 0; + } } /*extern int open_pic_irq_offset;*/ #endif /* _PPC_KERNEL_OPEN_PIC_H */ diff -Nru a/arch/ppc/kernel/open_pic_defs.h b/arch/ppc/kernel/open_pic_defs.h --- a/arch/ppc/kernel/open_pic_defs.h Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/kernel/open_pic_defs.h Sat Jun 16 06:00:32 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.open_pic_defs.h 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/openpic.h -- OpenPIC definitions @@ -44,14 +44,6 @@ #define OPENPIC_NUM_PRI 16 #define OPENPIC_NUM_VECTORS 256 - - /* - * Non-offset'ed vector numbers - */ - -#define OPENPIC_VEC_TIMER 64 /* and up */ -#define OPENPIC_VEC_IPI 72 /* and up */ -#define OPENPIC_VEC_SPURIOUS 127 /* diff -Nru a/arch/ppc/kernel/pci-dma.c b/arch/ppc/kernel/pci-dma.c --- a/arch/ppc/kernel/pci-dma.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/kernel/pci-dma.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pci-dma.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) 2000 Ani Joshi diff -Nru a/arch/ppc/kernel/pci.c b/arch/ppc/kernel/pci.c --- a/arch/ppc/kernel/pci.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/kernel/pci.c Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pci.c 1.21 05/21/01 01:31:30 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Common pmac/prep/chrp pci routines. -- Cort @@ -28,7 +28,7 @@ #include "pci.h" -#define DEBUG +#undef DEBUG #ifdef DEBUG #define DBG(x...) printk(x) @@ -40,11 +40,10 @@ unsigned long isa_mem_base = 0; unsigned long pci_dram_offset = 0; -static u8* pci_to_OF_bus_map; - static void pcibios_fixup_resources(struct pci_dev* dev); #ifdef CONFIG_ALL_PPC static void pcibios_fixup_cardbus(struct pci_dev* dev); +static u8* pci_to_OF_bus_map; #endif /* By default, we don't re-assign bus numbers. We do this only on @@ -133,6 +132,10 @@ res->start - offs, res->start); } } + + /* Call machine specific resource fixup */ + if (ppc_md.pcibios_fixup_resources) + ppc_md.pcibios_fixup_resources(dev); } #ifdef CONFIG_ALL_PPC @@ -228,22 +231,27 @@ { struct list_head *ln; struct pci_bus *bus; - struct pci_dev *dev; - int idx; - struct resource *r, *pr; + int i; + struct resource *res, *pr; /* Depth-First Search on bus tree */ - for (ln=bus_list->next; ln != bus_list; ln=ln->next) { + for (ln = bus_list->next; ln != bus_list; ln=ln->next) { bus = pci_bus_b(ln); - 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: Cannot allocate resource region %d of bridge %s\n", idx, dev->slot_name); - } + for (i = 0; i < 4; ++i) { + if ((res = bus->resource[i]) == NULL || !res->flags) + continue; + if (bus->parent == NULL) + pr = (res->flags & IORESOURCE_IO)? + &ioport_resource: &iomem_resource; + else + pr = pci_find_parent_resource(bus->self, res); + + if (pr && request_resource(pr, res) == 0) + continue; + printk(KERN_ERR "PCI: Cannot allocate resource region " + "%d of PCI bridge %d\n", i, bus->number); + DBG("PCI: resource is %lx..%lx (%lx), parent %p\n", + res->start, res->end, res->flags, pr); } pcibios_allocate_bus_resources(&bus->children); } @@ -327,19 +335,12 @@ for(idx=0; idx<6; idx++) { r = &dev->resource[idx]; -#if 0 /* we don't need this PC-ism */ - /* - * 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; -#endif /* - * We shall assign a new address to this resource, either because - * the BIOS (sic) forgot to do so or because we have decided the old - * address was unusable for some reason. + * We shall assign a new address to this resource, + * either because the BIOS (sic) forgot to do so + * or because we have decided the old address was + * unusable for some reason. */ if (!r->start && r->end && (!ppc_md.pcibios_enable_device_hook || @@ -496,10 +497,15 @@ && ((reg[0] >> 16) & 0xff) == bus) return node; - /* For PCI<->PCI bridges or CardBus bridges, we go down */ + /* For PCI<->PCI bridges or CardBus bridges, we go down + * Note: some OFs create a parent node "multifunc-device" as + * a fake root for all functions of a multi-function device, + * we go down them as well. + */ class_code = (unsigned int *) get_property(node, "class-code", 0); - if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && - (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) + if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI && + (*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) && + strcmp(node->name, "multifunc-device")) continue; sub_node = scan_OF_childs_for_device(node->child, bus, dev_fn); if (sub_node) @@ -682,9 +688,9 @@ { struct pci_controller *hose; struct pci_bus *bus; - int next_busno, i; + int next_busno; - printk("PCI: Probing PCI hardware\n"); + printk(KERN_INFO "PCI: Probing PCI hardware\n"); /* Scan all of the recorded PCI controllers. */ for (next_busno = 0, hose = hose_head; hose; hose = hose->next) { @@ -692,18 +698,6 @@ hose->first_busno = next_busno; hose->last_busno = 0xff; bus = pci_scan_bus(hose->first_busno, hose->ops, hose); - if (hose->io_resource.flags) { - unsigned long offs; - - offs = (unsigned long)hose->io_base_virt - isa_io_base; - hose->io_resource.start += offs; - hose->io_resource.end += offs; - bus->resource[0] = &hose->io_resource; - } - for (i = 0; i < 3; ++i) - if (hose->mem_resources[i].flags) - bus->resource[i+1] = &hose->mem_resources[i]; - hose->bus = bus; hose->last_busno = bus->subordinate; if (pci_assign_all_busses || next_busno <= hose->last_busno) next_busno = hose->last_busno+1; @@ -716,7 +710,11 @@ */ if (pci_assign_all_busses && have_of) pcibios_make_OF_bus_map(); - + + /* Do machine dependent PCI interrupt routing */ + if (ppc_md.pci_swizzle && ppc_md.pci_map_irq) + pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq); + /* Call machine dependant fixup */ if (ppc_md.pcibios_fixup) ppc_md.pcibios_fixup(); @@ -758,6 +756,25 @@ return pci_assign_all_busses; } +unsigned char __init +common_swizzle(struct pci_dev *dev, unsigned char *pinp) +{ + struct pci_controller *hose = dev->sysdata; + + if (dev->bus->number != hose->first_busno) { + u8 pin = *pinp; + do { + pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn)); + /* Move up the chain of bridges. */ + dev = dev->bus->self; + } while (dev->bus->self); + *pinp = pin; + + /* The slot is the idsel of the last bridge. */ + } + return PCI_SLOT(dev->devfn); +} + void __init pcibios_fixup_pbus_ranges(struct pci_bus * bus, struct pbus_set_ranges_data * ranges) { @@ -775,21 +792,60 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) { - struct pci_controller *hose; + struct pci_controller *hose = (struct pci_controller *) bus->sysdata; + unsigned long io_offset; + struct resource *res; + int i; - pci_read_bridge_bases(bus); + io_offset = (unsigned long)hose->io_base_virt - isa_io_base; + if (bus->parent == NULL) { + /* This is a host bridge - fill in its resources */ + hose->bus = bus; - hose = pci_bus_to_hose(bus->number); + bus->resource[0] = res = &hose->io_resource; + if (!res->flags) { + if (io_offset) + printk(KERN_ERR "I/O resource not set for host" + " bridge %d\n", hose->index); + res->start = 0; + res->end = IO_SPACE_LIMIT; + res->flags = IORESOURCE_IO; + } + + for (i = 0; i < 3; ++i) { + res = &hose->mem_resources[i]; + if (!res->flags) { + if (i > 0) + continue; + printk(KERN_ERR "Memory resource not set for " + "host bridge %d\n", hose->index); + res->start = 0; + res->end = ~0U - hose->pci_mem_offset; + res->flags = IORESOURCE_MEM; + } + bus->resource[i+1] = res; + } + } else { + /* This is a subordinate bridge */ + pci_read_bridge_bases(bus); + } - /* Apply pci_mem_offset to bridge mem resource */ - if (hose->first_busno != bus->number) - if (bus->resource[1]->start && (bus->resource[1]->end != -1)) - { - bus->resource[1]->start += hose->pci_mem_offset; - bus->resource[1]->end += hose->pci_mem_offset; + for (i = 0; i < 4; ++i) { + if ((res = bus->resource[i]) == NULL) + continue; + if (!res->flags) + continue; + if (io_offset && (res->flags & IORESOURCE_IO)) { + res->start += io_offset; + res->end += io_offset; + } else if (hose->pci_mem_offset + && (res->flags & IORESOURCE_MEM)) { + res->start += hose->pci_mem_offset; + res->end += hose->pci_mem_offset; } + } - if ( ppc_md.pcibios_fixup_bus ) + if (ppc_md.pcibios_fixup_bus) ppc_md.pcibios_fixup_bus(bus); } @@ -893,7 +949,7 @@ #ifdef CONFIG_POWER4 unsigned long offset = pci_address_offset(pdev->bus->number, res->flags); return res->start - offset; -#else /* CONFIG_POWER4 */ +#else /* !CONFIG_POWER4 */ struct pci_controller* hose = (struct pci_controller *)pdev->sysdata; if (hose && res->flags & IORESOURCE_MEM) @@ -1074,12 +1130,12 @@ { #ifdef CONFIG_POWER4 return pa - pci_address_offset(busnr, IORESOURCE_MEM); -#else /* CONFIG_POWER4 */ +#else /* !CONFIG_POWER4 */ struct pci_controller* hose = pci_bus_to_hose(busnr); if (!hose) return pa; return pa - hose->pci_mem_offset; -#endif +#endif /* CONFIG_POWER4 */ } unsigned long @@ -1087,12 +1143,12 @@ { #ifdef CONFIG_POWER4 return ba + pci_address_offset(dev->bus->number, IORESOURCE_MEM); -#else /* CONFIG_POWER4 */ +#else /* !CONFIG_POWER4 */ struct pci_controller* hose = pci_bus_to_hose(busnr); if (!hose) return ba; return ba + hose->pci_mem_offset; -#endif +#endif /* CONFIG_POWER4 */ } /* Provide information on locations of various I/O regions in physical diff -Nru a/arch/ppc/kernel/pci.h b/arch/ppc/kernel/pci.h --- a/arch/ppc/kernel/pci.h Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/kernel/pci.h Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pci.h 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef __PPC_KERNEL_PCI_H__ @@ -23,5 +23,31 @@ extern void setup_indirect_pci(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data); extern void setup_grackle(struct pci_controller *hose, unsigned io_space_size); + +extern unsigned char common_swizzle(struct pci_dev *, unsigned char *); + +/* + * The following code swizzles for exactly one bridge. The routine + * common_swizzle below handles multiple bridges. But there are a + * some boards that don't follow the PCI spec's suggestion so we + * break this piece out separately. + */ +static inline unsigned char bridge_swizzle(unsigned char pin, + unsigned char idsel) +{ + return (((pin-1) + idsel) % 4) + 1; +} + +/* + * The following macro is used to lookup irqs in a standard table + * format for those PPC systems that do not already have PCI + * interrupts properly routed. + */ +/* FIXME - double check this */ +#define PCI_IRQ_TABLE_LOOKUP \ +({ long _ctl_ = -1; \ + if (idsel >= min_idsel && idsel <= max_idsel && pin <= irqs_per_slot) \ + _ctl_ = pci_irq_table[idsel - min_idsel][pin-1]; \ + _ctl_; }) #endif /* __PPC_KERNEL_PCI_H__ */ diff -Nru a/arch/ppc/kernel/pci_auto.c b/arch/ppc/kernel/pci_auto.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/pci_auto.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,339 @@ +/* + * arch/ppc/kernel/pci_auto.c + * + * PCI autoconfiguration library + * + * Author: Matt Porter + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include + +#include + +#include "pci.h" +#include "pci_auto.h" + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +static int pciauto_upper_iospc; +static int pciauto_upper_memspc; + +void pciauto_setup_bars(struct pci_controller *hose, + int current_bus, + int pci_devfn) +{ + int bar_response, bar_size, bar_value; + int bar, addr_mask, bar_nr = 0; + int * upper_limit; + int found_mem64 = 0; + + DBG("PCI Autoconfig: Found Bus %d, Device %d, Function %d\n", + current_bus, PCI_SLOT(pci_devfn), PCI_FUNC(pci_devfn) ); + + for (bar = PCI_BASE_ADDRESS_0; bar <= PCI_BASE_ADDRESS_5; bar+=4) + { + /* Tickle the BAR and get the response */ + early_write_config_dword(hose, + current_bus, + pci_devfn, + bar, + 0xffffffff); + early_read_config_dword(hose, + current_bus, + pci_devfn, + bar, + &bar_response); + + /* If BAR is not implemented go to the next BAR */ + if (!bar_response) + continue; + + /* Check the BAR type and set our address mask */ + if (bar_response & PCI_BASE_ADDRESS_SPACE) + { + addr_mask = PCI_BASE_ADDRESS_IO_MASK; + upper_limit = &pciauto_upper_iospc; + DBG("PCI Autoconfig: BAR %d, I/O, ", bar_nr); + } + else + { + if ( (bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == + PCI_BASE_ADDRESS_MEM_TYPE_64) + found_mem64 = 1; + + addr_mask = PCI_BASE_ADDRESS_MEM_MASK; + upper_limit = &pciauto_upper_memspc; + DBG("PCI Autoconfig: BAR %d, Mem, ", bar_nr); + } + + /* Calculate requested size */ + bar_size = ~(bar_response & addr_mask) + 1; + + /* Allocate a base address */ + bar_value = (*upper_limit - bar_size) & ~(bar_size - 1); + + /* Write it out and update our limit */ + early_write_config_dword(hose, + current_bus, + pci_devfn, + bar, + bar_value); + + *upper_limit = bar_value; + + /* + * If we are a 64-bit decoder then increment to the + * upper 32 bits of the bar and force it to locate + * in the lower 4GB of memory. + */ + if (found_mem64) + { + bar += 4; + early_write_config_dword(hose, + current_bus, + pci_devfn, + bar, + 0x00000000); + } + + bar_nr++; + + DBG("size=0x%x, address=0x%x\n", + bar_size, bar_value); + } + +} + +void pciauto_prescan_setup_bridge(struct pci_controller *hose, + int current_bus, + int pci_devfn, + int sub_bus) +{ + int cmdstat; + + /* Configure bus number registers */ + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_PRIMARY_BUS, + current_bus); + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_SECONDARY_BUS, + sub_bus + 1); + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_SUBORDINATE_BUS, + 0xff); + + /* Round memory allocator to 1MB boundary */ + pciauto_upper_memspc &= ~(0x100000 - 1); + + /* Round I/O allocator to 4KB boundary */ + pciauto_upper_iospc &= ~(0x1000 - 1); + + /* Set up memory and I/O filter limits, assume 32-bit I/O space */ + early_write_config_word(hose, + current_bus, + pci_devfn, + PCI_MEMORY_LIMIT, + ((pciauto_upper_memspc - 1) & 0xfff00000) >> 16); + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_IO_LIMIT, + ((pciauto_upper_iospc - 1) & 0x0000f000) >> 8); + early_write_config_word(hose, + current_bus, + pci_devfn, + PCI_IO_LIMIT_UPPER16, + ((pciauto_upper_iospc - 1) & 0xffff0000) >> 16); + + /* We don't support prefetchable memory for now, so disable */ + early_write_config_word(hose, + current_bus, + pci_devfn, + PCI_PREF_MEMORY_BASE, + 0x1000); + early_write_config_word(hose, + current_bus, + pci_devfn, + PCI_PREF_MEMORY_LIMIT, + 0x1000); + + /* Enable memory and I/O accesses, enable bus master */ + early_read_config_dword(hose, + current_bus, + pci_devfn, + PCI_COMMAND, + &cmdstat); + early_write_config_dword(hose, + current_bus, + pci_devfn, + PCI_COMMAND, + cmdstat | + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); +} + +void pciauto_postscan_setup_bridge(struct pci_controller *hose, + int current_bus, + int pci_devfn, + int sub_bus) +{ + /* Configure bus number registers */ + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_SUBORDINATE_BUS, + sub_bus); + + /* Round memory allocator to 1MB boundary */ + pciauto_upper_memspc &= ~(0x100000 - 1); + early_write_config_word(hose, + current_bus, + pci_devfn, + PCI_MEMORY_BASE, + pciauto_upper_memspc >> 16); + + /* Round I/O allocator to 4KB boundary */ + pciauto_upper_iospc &= ~(0x1000 - 1); + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_IO_BASE, + (pciauto_upper_iospc & 0x0000f000) >> 8); + early_write_config_word(hose, + current_bus, + pci_devfn, + PCI_IO_BASE_UPPER16, + pciauto_upper_iospc >> 16); +} + +int pciauto_bus_scan(struct pci_controller *hose, int current_bus) +{ + int sub_bus, pci_devfn, pci_class, cmdstat, found_multi=0; + unsigned short vid; + unsigned char header_type; + + /* + * Fetch our I/O and memory space upper boundaries used + * to allocated base addresses on this hose. + */ + if (current_bus == hose->first_busno) + { + pciauto_upper_iospc = hose->io_space.end + 1; + pciauto_upper_memspc = hose->mem_space.end + 1; + } + + sub_bus = current_bus; + + for (pci_devfn=0; pci_devfn<0xff; pci_devfn++) + { + /* Skip our host bridge */ + if ( (current_bus == hose->first_busno) && (pci_devfn == 0) ) + continue; + + if (PCI_FUNC(pci_devfn) && !found_multi) + continue; + + early_read_config_byte(hose, + current_bus, + pci_devfn, + PCI_HEADER_TYPE, + &header_type); + + if (!PCI_FUNC(pci_devfn)) + found_multi = header_type & 0x80; + + early_read_config_word(hose, + current_bus, + pci_devfn, + PCI_VENDOR_ID, + &vid); + + if (vid != 0xffff) + { + early_read_config_dword(hose, + current_bus, + pci_devfn, + PCI_CLASS_REVISION, &pci_class); + if ( (pci_class >> 16) == PCI_CLASS_BRIDGE_PCI ) + { + DBG("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_SLOT(pci_devfn)); + pciauto_prescan_setup_bridge(hose, + current_bus, + pci_devfn, + sub_bus); + sub_bus = pciauto_bus_scan(hose, sub_bus+1); + pciauto_postscan_setup_bridge(hose, + current_bus, + pci_devfn, + sub_bus); + } + else + { + if ((pci_class >> 16) == PCI_CLASS_STORAGE_IDE) + { + unsigned char prg_iface; + + early_read_config_byte(hose, + current_bus, + pci_devfn, + PCI_CLASS_PROG, + &prg_iface); + if (!(prg_iface & PCIAUTO_IDE_MODE_MASK)) + { + DBG("PCI Autoconfig: Skipping legacy mode IDE controller\n"); + continue; + } + } + /* + * Found a peripheral, enable some standard + * settings + */ + early_read_config_dword(hose, + current_bus, + pci_devfn, + PCI_COMMAND, + &cmdstat); + early_write_config_dword(hose, + current_bus, + pci_devfn, + PCI_COMMAND, + cmdstat | + PCI_COMMAND_IO | + PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER); + early_write_config_byte(hose, + current_bus, + pci_devfn, + PCI_LATENCY_TIMER, + 0x80); + + /* Allocate PCI I/O and/or memory space */ + pciauto_setup_bars(hose, + current_bus, + pci_devfn); + } + } + } + return sub_bus; +} diff -Nru a/arch/ppc/kernel/pci_auto.h b/arch/ppc/kernel/pci_auto.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/pci_auto.h Sat Jun 16 06:00:32 2001 @@ -0,0 +1,25 @@ +/* + * arch/ppc/kernel/pci_auto.h + * + * PCI autoconfiguration library definitions + * + * Author: Matt Porter + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef _PPC_KERNEL_PCI_AUTO_H +#define _PPC_KERNEL_PCI_AUTO_H + +#include + +extern int pciauto_bus_scan(struct pci_controller *, int); + +#define PCIAUTO_IDE_MODE_MASK 0x05 + +#endif /* _PPC_KERNEL_PCI_AUTO_H */ diff -Nru a/arch/ppc/kernel/pcore.h b/arch/ppc/kernel/pcore.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/pcore.h Sat Jun 16 06:00:32 2001 @@ -0,0 +1,41 @@ +/* + * arch/ppc/kernel/pcore.h + * + * Definitions for Force PowerCore board support + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef _PPC_KERNEL_PCORE_H +#define _PPC_KERNEL_PCORE_H + +#include "mpc10x.h" + +#define PCORE_TYPE_6750 1 +#define PCORE_TYPE_680 2 + +#define PCORE_NVRAM_AS0 0x73 +#define PCORE_NVRAM_AS1 0x75 +#define PCORE_NVRAM_DATA 0x77 + +#define PCORE_DCCR_REG (MPC10X_MAPB_ISA_IO_BASE + 0x308) +#define PCORE_DCCR_L2_MASK 0xc0 +#define PCORE_DCCR_L2_0KB 0x00 +#define PCORE_DCCR_L2_256KB 0x40 +#define PCORE_DCCR_L2_512KB 0xc0 +#define PCORE_DCCR_L2_1MB 0x80 +#define PCORE_DCCR_L2_2MB 0x00 + +#define PCORE_WINBOND_IDE_INT 0x43 +#define PCORE_WINBOND_PCI_INT 0x44 +#define PCORE_WINBOND_PRI_EDG_LVL 0x4d0 +#define PCORE_WINBOND_SEC_EDG_LVL 0x4d1 + +#endif /* _PPC_KERNEL_PCORE_H */ diff -Nru a/arch/ppc/kernel/pcore_pci.c b/arch/ppc/kernel/pcore_pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/pcore_pci.c Sat Jun 16 06:00:32 2001 @@ -0,0 +1,143 @@ +/* + * arch/ppc/kernel/pcore_pci.c + * + * PCI support for Force PCORE boards + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pci.h" +#include "pci_auto.h" +#include "mpc10x.h" +#include "pcore.h" + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +static inline int __init +pcore_6750_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {9, 10, 11, 12}, /* IDSEL 24 - DEC 21554 */ + {10, 0, 0, 0}, /* IDSEL 25 - DEC 21143 */ + {11, 12, 9, 10}, /* IDSEL 26 - PMC I */ + {12, 9, 10, 11}, /* IDSEL 27 - PMC II */ + {0, 0, 0, 0}, /* IDSEL 28 - unused */ + {0, 0, 9, 0}, /* IDSEL 29 - unused */ + {0, 0, 0, 0}, /* IDSEL 30 - Winbond */ + }; + const long min_idsel = 24, max_idsel = 30, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +static inline int __init +pcore_680_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {9, 10, 11, 12}, /* IDSEL 24 - Sentinel */ + {10, 0, 0, 0}, /* IDSEL 25 - i82559 #1 */ + {11, 12, 9, 10}, /* IDSEL 26 - PMC I */ + {12, 9, 10, 11}, /* IDSEL 27 - PMC II */ + {9, 0, 0, 0}, /* IDSEL 28 - i82559 #2 */ + {0, 0, 0, 0}, /* IDSEL 29 - unused */ + {0, 0, 0, 0}, /* IDSEL 30 - Winbond */ + }; + const long min_idsel = 24, max_idsel = 30, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +void __init +pcore_pcibios_fixup(void) +{ + struct pci_dev *dev; + + if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, + PCI_DEVICE_ID_WINBOND_83C553, + 0))) + { + /* Reroute interrupts both IDE channels to 15 */ + pci_write_config_byte(dev, + PCORE_WINBOND_IDE_INT, + 0xff); + + /* Route INTA-D to IRQ9-12, respectively */ + pci_write_config_word(dev, + PCORE_WINBOND_PCI_INT, + 0x9abc); + + /* + * Set up 8259 edge/level triggering + */ + outb(0x00, PCORE_WINBOND_PRI_EDG_LVL); + outb(0x1e, PCORE_WINBOND_SEC_EDG_LVL); + } +} + +int __init +pcore_find_bridges(void) +{ + struct pci_controller* hose; + int host_bridge, board_type; + + hose = pcibios_alloc_controller(); + if (!hose) + return 0; + + mpc10x_bridge_init(hose, MPC10X_MEM_MAP_B, MPC10X_MEM_MAP_B, 0); + + /* Determine board type */ + early_read_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_VENDOR_ID, + &host_bridge); + if (host_bridge == MPC10X_BRIDGE_106) + board_type = PCORE_TYPE_6750; + else /* MPC10X_BRIDGE_107 */ + board_type = PCORE_TYPE_680; + + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = pcore_pcibios_fixup; + ppc_md.pci_swizzle = common_swizzle; + + if (board_type == PCORE_TYPE_6750) + ppc_md.pci_map_irq = pcore_6750_map_irq; + else /* PCORE_TYPE_680 */ + ppc_md.pci_map_irq = pcore_680_map_irq; + + return board_type; +} diff -Nru a/arch/ppc/kernel/pcore_setup.c b/arch/ppc/kernel/pcore_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/pcore_setup.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,256 @@ +/* + * arch/ppc/kernel/pcore_setup.c + * + * Setup routines for Force PCORE boards + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "local_irq.h" +#include "i8259.h" +#include "mpc10x.h" +#include "todc.h" +#include "pcore.h" + +extern int pcore_find_bridges(void); +extern unsigned long loops_per_jiffy; + +static int board_type; + +/* Dummy variable to satisfy mpc10x_common.o */ +void *OpenPIC_Addr; + +int +pcore_get_cpuinfo(char *buffer) +{ + int len; + + len = sprintf(buffer, "vendor\t\t: Force Computers\n"); + + if (board_type == PCORE_TYPE_6750) + len += sprintf(buffer+len, "machine\t\t: PowerCore 6750\n"); + else /* PCORE_TYPE_680 */ + len += sprintf(buffer+len, "machine\t\t: PowerCore 680\n"); + + len += sprintf(buffer+len, "L2\t\t: " ); + if (board_type == PCORE_TYPE_6750) + switch (readb(PCORE_DCCR_REG) & PCORE_DCCR_L2_MASK) + { + case PCORE_DCCR_L2_0KB: + len += sprintf(buffer+len, "nocache"); + break; + case PCORE_DCCR_L2_256KB: + len += sprintf(buffer+len, "256KB"); + break; + case PCORE_DCCR_L2_1MB: + len += sprintf(buffer+len, "1MB"); + break; + case PCORE_DCCR_L2_512KB: + len += sprintf(buffer+len, "512KB"); + break; + default: + len += sprintf(buffer+len, "error"); + break; + } + else /* PCORE_TYPE_680 */ + switch (readb(PCORE_DCCR_REG) & PCORE_DCCR_L2_MASK) + { + case PCORE_DCCR_L2_2MB: + len += sprintf(buffer+len, "2MB"); + break; + case PCORE_DCCR_L2_256KB: + len += sprintf(buffer+len, "reserved"); + break; + case PCORE_DCCR_L2_1MB: + len += sprintf(buffer+len, "1MB"); + break; + case PCORE_DCCR_L2_512KB: + len += sprintf(buffer+len, "512KB"); + break; + default: + len += sprintf(buffer+len, "error"); + break; + } + + len += sprintf(buffer+len, "\n"); + + return len; +} + +void __init +pcore_setup_arch(void) +{ + extern char cmd_line[]; + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000/HZ; + + /* Lookup PCI host bridges */ + board_type = pcore_find_bridges(); + +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */ +#endif + + printk("Boot arguments: %s\n", cmd_line); +} + +void +pcore_restart(char *cmd) +{ + __cli(); + /* Hard reset */ + writeb(0x11, 0xfe000332); + while(1); +} + +void +pcore_halt(void) +{ + __cli(); + /* Turn off user LEDs */ + writeb(0x00, 0xfe000300); + while (1); +} + +void +pcore_power_off(void) +{ + pcore_halt(); +} + + +void __init +pcore_init_IRQ(void) +{ + int i; + + for ( i = 0 ; i < 16 ; i++ ) + irq_desc[i].handler = &i8259_pic; + + i8259_init(); +} + +int +pcore_get_irq(struct pt_regs *regs) +{ + int irq; + + if ( (irq = i8259_irq(0)) < 0 ) + { + printk(KERN_DEBUG "Bogus interrupt from PC = %lx\n", + regs->nip); + ppc_spurious_interrupts++; + return -1; + } + + ppc_irq_dispatch_handler( regs, irq ); + + return irq; +} + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space. + */ +static __inline__ void +pcore_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) + { + __asm__ __volatile__( + " lis %0,0xf000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + :: "r" (bat3u), "r" (bat3l)); + + mapping_set = 1; + } + return; +} + +unsigned long __init +pcore_find_end_of_memory(void) +{ + /* Cover I/O space with a BAT */ + pcore_set_bat(); + + return mpc10x_get_mem_size(MPC10X_MEM_MAP_B); +} + +void __init +pcore_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + /* Copy cmd_line parameters */ + if ( r6) + { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } + + todc_info = &m48t59_info; + todc_info->nvram_as0 = (u_char *)PCORE_NVRAM_AS0; + todc_info->nvram_as1 = (u_char *)PCORE_NVRAM_AS1; + todc_info->nvram_data = (u_char *)PCORE_NVRAM_DATA; + + isa_io_base = MPC10X_MAPB_ISA_IO_BASE; + isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE; + pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET; + + ppc_md.setup_arch = pcore_setup_arch; + ppc_md.get_cpuinfo = pcore_get_cpuinfo; + ppc_md.init_IRQ = pcore_init_IRQ; + ppc_md.get_irq = pcore_get_irq; + + ppc_md.find_end_of_memory = pcore_find_end_of_memory; + + ppc_md.restart = pcore_restart; + ppc_md.power_off = pcore_power_off; + ppc_md.halt = pcore_halt; + + ppc_md.time_init = todc_time_init; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + + ppc_md.nvram_read_val = todc_m48txx_read_val; + ppc_md.nvram_write_val = todc_m48txx_write_val; +} diff -Nru a/arch/ppc/kernel/pmac_backlight.c b/arch/ppc/kernel/pmac_backlight.c --- a/arch/ppc/kernel/pmac_backlight.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/kernel/pmac_backlight.c Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pmac_backlight.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Miscellaneous procedures for dealing with the PowerMac hardware. diff -Nru a/arch/ppc/kernel/pmac_nvram.c b/arch/ppc/kernel/pmac_nvram.c --- a/arch/ppc/kernel/pmac_nvram.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/kernel/pmac_nvram.c Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pmac_nvram.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Miscellaneous procedures for dealing with the PowerMac hardware. diff -Nru a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c --- a/arch/ppc/kernel/pmac_pci.c Sat Jun 16 06:00:27 2001 +++ b/arch/ppc/kernel/pmac_pci.c Sat Jun 16 06:00:27 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pmac_pci.c 1.14 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Support for PCI bridges found on Power Macintoshes. diff -Nru a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c --- a/arch/ppc/kernel/pmac_pic.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/kernel/pmac_pic.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pmac_pic.c 1.14 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/kernel/pmac_pic.h b/arch/ppc/kernel/pmac_pic.h --- a/arch/ppc/kernel/pmac_pic.h Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/kernel/pmac_pic.h Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pmac_pic.h 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef _PPC_KERNEL_PMAC_PIC_H #define _PPC_KERNEL_PMAC_PIC_H diff -Nru a/arch/ppc/kernel/pmac_setup.c b/arch/ppc/kernel/pmac_setup.c --- a/arch/ppc/kernel/pmac_setup.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/kernel/pmac_setup.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pmac_setup.c 1.21 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/setup.c @@ -65,6 +65,7 @@ #include #include #include +#include #include #include "local_irq.h" @@ -138,7 +139,7 @@ { int cpu = smp_processor_id(); - if ( (_get_PVR() >> 16) != 8 && (_get_PVR() >> 16) != 12 ) + if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)) return; if (cpu == 0){ @@ -279,6 +280,7 @@ { struct device_node *cpu; int *fp; + unsigned long pvr = (_get_PVR() >> 16) & 0xffff; /* Set loops_per_jiffy to a half-way reasonable value, for use until calibrate_delay gets called. */ @@ -286,18 +288,12 @@ if (cpu != 0) { fp = (int *) get_property(cpu, "clock-frequency", NULL); if (fp != 0) { - switch (_get_PVR() >> 16) { - case 4: /* 604 */ - case 8: /* G3 */ - case 9: /* 604e */ - case 10: /* mach V (604ev5) */ - case 12: /* G4 */ - case 20: /* 620 */ + if (pvr == 4 || pvr >= 8) + /* 604, G3, G4 etc. */ loops_per_jiffy = *fp / HZ; - break; - default: /* 601, 603, etc. */ + else + /* 601, 603, etc. */ loops_per_jiffy = *fp / (2*HZ); - } } else loops_per_jiffy = 50000000 / HZ; } @@ -305,14 +301,13 @@ /* this area has the CPU identification register and some registers used by smp boards */ sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000); - __ioremap(0xffc00000, 0x400000, pgprot_val(PAGE_READONLY)); ohare_init(); /* Lookup PCI hosts */ pmac_find_bridges(); /* Checks "l2cr-value" property in the registry */ - if ( (_get_PVR() >> 16) == 8 || (_get_PVR() >> 16) == 12 ) { + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) { struct device_node *np = find_devices("cpus"); if (np == 0) np = find_type_devices("cpu"); diff -Nru a/arch/ppc/kernel/pmac_time.c b/arch/ppc/kernel/pmac_time.c --- a/arch/ppc/kernel/pmac_time.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/kernel/pmac_time.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.pmac_time.c 1.8 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Support for periodic interrupts (100 per second) and for getting diff -Nru a/arch/ppc/kernel/ppc-stub.c b/arch/ppc/kernel/ppc-stub.c --- a/arch/ppc/kernel/ppc-stub.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/kernel/ppc-stub.c Sat Jun 16 06:00:24 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc-stub.c 1.6 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * ppc-stub.c: KGDB support for the Linux kernel. diff -Nru a/arch/ppc/kernel/ppc4xx_pic.c b/arch/ppc/kernel/ppc4xx_pic.c --- a/arch/ppc/kernel/ppc4xx_pic.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/kernel/ppc4xx_pic.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc4xx_pic.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * diff -Nru a/arch/ppc/kernel/ppc4xx_pic.h b/arch/ppc/kernel/ppc4xx_pic.h --- a/arch/ppc/kernel/ppc4xx_pic.h Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/kernel/ppc4xx_pic.h Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc4xx_pic.h 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * @@ -14,12 +14,8 @@ #ifndef __PPC4XX_PIC_H__ #define __PPC4XX_PIC_H__ -#include - - -#ifdef __cplusplus -extern "C" { -#endif +#include +#include "local_irq.h" /* External Global Variables */ @@ -30,10 +26,5 @@ extern void ppc4xx_pic_init(void); extern int ppc4xx_pic_get_irq(struct pt_regs *regs); - - -#ifdef __cplusplus -} -#endif #endif /* __PPC4XX_PIC_H__ */ diff -Nru a/arch/ppc/kernel/ppc8260_pic.c b/arch/ppc/kernel/ppc8260_pic.c --- a/arch/ppc/kernel/ppc8260_pic.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/kernel/ppc8260_pic.c Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc8260_pic.c 1.5 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #include diff -Nru a/arch/ppc/kernel/ppc8260_pic.h b/arch/ppc/kernel/ppc8260_pic.h --- a/arch/ppc/kernel/ppc8260_pic.h Sat Jun 16 06:00:26 2001 +++ b/arch/ppc/kernel/ppc8260_pic.h Sat Jun 16 06:00:26 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc8260_pic.h 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef _PPC_KERNEL_PPC8260_H diff -Nru a/arch/ppc/kernel/ppc8xx_pic.c b/arch/ppc/kernel/ppc8xx_pic.c --- a/arch/ppc/kernel/ppc8xx_pic.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/kernel/ppc8xx_pic.c Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc8xx_pic.c 1.10 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/kernel/ppc8xx_pic.h b/arch/ppc/kernel/ppc8xx_pic.h --- a/arch/ppc/kernel/ppc8xx_pic.h Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/kernel/ppc8xx_pic.h Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc8xx_pic.h 1.7 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef _PPC_KERNEL_PPC8xx_H #define _PPC_KERNEL_PPC8xx_H diff -Nru a/arch/ppc/kernel/ppc_asm.h b/arch/ppc/kernel/ppc_asm.h --- a/arch/ppc/kernel/ppc_asm.h Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/kernel/ppc_asm.h Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc_asm.h 1.10 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/ppc_asm.h @@ -70,12 +70,20 @@ #define REST_32VR(n,b,base) REST_16VR(n,b,base); REST_16VR(n+16,b,base) #ifdef CONFIG_PPC601_SYNC_FIX -#define SYNC \ - sync; \ - isync +#define SYNC \ +BEGIN_FTR_SECTION \ + sync; \ + isync; \ +END_FTR_SECTION_IFSET(CPU_FTR_601) #else #define SYNC #endif + +/* tlbsync is not implemented on 601 */ +#define TLBSYNC \ +BEGIN_FTR_SECTION \ + tlbsync; \ +END_FTR_SECTION_IFCLR(CPU_FTR_601) /* * This instruction is not implemented on the PPC 603 or 601; however, on diff -Nru a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c --- a/arch/ppc/kernel/ppc_htab.c Sat Jun 16 06:00:26 2001 +++ b/arch/ppc/kernel/ppc_htab.c Sat Jun 16 06:00:26 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc_htab.c 1.8 05/17/01 18:14:21 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * PowerPC hash table management proc entry. Will show information @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include static ssize_t ppc_htab_read(struct file * file, char * buf, size_t count, loff_t *ppos); @@ -41,9 +43,12 @@ extern unsigned long Hash_size, Hash_mask; extern unsigned long _SDR1; extern unsigned long htab_reloads; +extern unsigned long htab_preloads; extern unsigned long htab_evicts; extern unsigned long pte_misses; extern unsigned long pte_errors; +extern unsigned int primary_pteg_full; +extern unsigned int htab_hash_searches; /* these will go into processor.h when I'm done debugging -- Cort */ #define MMCR0 952 @@ -110,7 +115,7 @@ { unsigned long mmcr0 = 0, pmc1 = 0, pmc2 = 0; int n = 0, valid; - unsigned int kptes = 0, overflow = 0, uptes = 0, zombie_ptes = 0; + unsigned int kptes = 0, uptes = 0, zombie_ptes = 0; PTE *ptr; struct task_struct *p; char buffer[512]; @@ -118,11 +123,7 @@ if (count < 0) return -EINVAL; - switch ( _get_PVR()>>16 ) - { - case 4: /* 604 */ - case 9: /* 604e */ - case 10: /* 604ev5 */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { asm volatile ("mfspr %0,952 \n\t" "mfspr %1,953 \n\t" "mfspr %2,954 \n\t" @@ -138,9 +139,6 @@ "PMC2\t\t: %08lx (%s)\n", pmc1, pmc1_lookup(mmcr0), pmc2, pmc2_lookup(mmcr0)); - break; - default: - break; } @@ -150,41 +148,34 @@ n += sprintf( buffer + n, "No Hash Table used\n"); goto return_string; } - - /* - * compute user/kernel pte's table this info can be - * misleading since there can be valid (v bit set) entries - * in the table but their vsid is used by no process (mm->context) - * due to the way tlb invalidation is handled on the ppc - * -- Cort - */ + +#if !defined(CONFIG_8xx) && !defined(CONFIG_4xx) for ( ptr = Hash ; ptr < Hash_end ; ptr++) { - if (ptr->v) - { - /* make sure someone is using this context/vsid */ - valid = 0; - for_each_task(p) - { - if (p->mm && (ptr->vsid >> 4) == p->mm->context) - { - valid = 1; - break; - } - } - if ( !valid ) - { - zombie_ptes++; - continue; - } - /* user not allowed read or write */ - if (ptr->pp == PP_RWXX) - kptes++; - else + unsigned int ctx, mctx, vsid; + + if (!ptr->v) + continue; + /* make sure someone is using this context/vsid */ + /* first undo the esid skew */ + vsid = ptr->vsid; + mctx = ((vsid - (vsid & 0xf) * 0x111) >> 4) & 0xfffff; + if (mctx == 0) { + kptes++; + continue; + } + /* now undo the context skew; 801921 * 897 == 1 mod 2^20 */ + ctx = (mctx * 801921) & 0xfffff; + valid = 0; + for_each_task(p) { + if (p->mm != NULL && ctx == p->mm->context) { + valid = 1; uptes++; - if (ptr->h == 1) - overflow++; + break; + } } + if (!valid) + zombie_ptes++; } n += sprintf( buffer + n, @@ -195,29 +186,32 @@ "Entries\t\t: %lu\n" "User ptes\t: %u\n" "Kernel ptes\t: %u\n" - "Overflows\t: %u\n" "Zombies\t\t: %u\n" - "Percent full\t: %%%lu\n", + "Percent full\t: %lu%%\n", (unsigned long)(Hash_size>>10), (Hash_size/(sizeof(PTE)*8)), (unsigned long)Hash, Hash_size/sizeof(PTE), uptes, kptes, - overflow, zombie_ptes, ((kptes+uptes)*100) / (Hash_size/sizeof(PTE)) ); n += sprintf( buffer + n, - "Reloads\t\t: %08lx\n" - "Evicts\t\t: %08lx\n", - htab_reloads, htab_evicts); + "Reloads\t\t: %lu\n" + "Preloads\t: %lu\n" + "Searches\t: %u\n" + "Overflows\t: %u\n" + "Evicts\t\t: %lu\n", + htab_reloads, htab_preloads, htab_hash_searches, + primary_pteg_full, htab_evicts); +#endif /* !8xx && !4xx */ return_string: n += sprintf( buffer + n, - "Non-error misses: %08lx\n" - "Error misses\t: %08lx\n", + "Non-error misses: %lu\n" + "Error misses\t: %lu\n", pte_misses, pte_errors); if (*ppos >= strlen(buffer)) return 0; @@ -247,37 +241,22 @@ /* turn off performance monitoring */ if ( !strncmp( buffer, "off", 3) ) { - switch ( _get_PVR()>>16 ) - { - case 4: /* 604 */ - case 9: /* 604e */ - case 10: /* 604ev5 */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { asm volatile ("mtspr %0, %3 \n\t" "mtspr %1, %3 \n\t" "mtspr %2, %3 \n\t" :: "i" (MMCR0), "i" (PMC1), "i" (PMC2), "r" (0)); - break; - default: - break; } - } if ( !strncmp( buffer, "reset", 5) ) { - switch ( _get_PVR()>>16 ) - { - case 4: /* 604 */ - case 9: /* 604e */ - case 10: /* 604ev5 */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { /* reset PMC1 and PMC2 */ asm volatile ( "mtspr 953, %0 \n\t" "mtspr 954, %0 \n\t" :: "r" (0)); - break; - default: - break; } htab_reloads = 0; htab_evicts = 0; @@ -287,11 +266,7 @@ if ( !strncmp( buffer, "user", 4) ) { - switch ( _get_PVR()>>16 ) - { - case 4: /* 604 */ - case 9: /* 604e */ - case 10: /* 604ev5 */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { /* setup mmcr0 and clear the correct pmc */ asm("mfspr %0,%1\n\t" : "=r" (tmp) : "i" (MMCR0)); tmp &= ~(0x60000000); @@ -302,19 +277,12 @@ "mtspr %5,%4 \n\t" /* reset the pmc2 */ :: "r" (tmp), "i" (MMCR0), "i" (0), "i" (PMC1), "r" (0), "i"(PMC2) ); - break; - default: - break; } } if ( !strncmp( buffer, "kernel", 6) ) { - switch ( _get_PVR()>>16 ) - { - case 4: /* 604 */ - case 9: /* 604e */ - case 10: /* 604ev5 */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { /* setup mmcr0 and clear the correct pmc */ asm("mfspr %0,%1\n\t" : "=r" (tmp) : "i" (MMCR0)); tmp &= ~(0x60000000); @@ -325,20 +293,13 @@ "mtspr %5,%4 \n\t" /* reset the pmc2 */ :: "r" (tmp), "i" (MMCR0), "i" (0), "i" (PMC1), "r" (0), "i"(PMC2) ); - break; - default: - break; } } /* PMC1 values */ if ( !strncmp( buffer, "dtlb", 4) ) { - switch ( _get_PVR()>>16 ) - { - case 4: /* 604 */ - case 9: /* 604e */ - case 10: /* 604ev5 */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { /* setup mmcr0 and clear the correct pmc */ asm("mfspr %0,%1\n\t" : "=r" (tmp) : "i" (MMCR0)); tmp &= ~(0x7f<<7); @@ -353,11 +314,7 @@ if ( !strncmp( buffer, "ic miss", 7) ) { - switch ( _get_PVR()>>16 ) - { - case 4: /* 604 */ - case 9: /* 604e */ - case 10: /* 604ev5 */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { /* setup mmcr0 and clear the correct pmc */ asm("mfspr %0,%1\n\t" : "=r" (tmp) : "i" (MMCR0)); tmp &= ~(0x7f<<7); @@ -373,11 +330,7 @@ /* PMC2 values */ if ( !strncmp( buffer, "load miss time", 14) ) { - switch ( _get_PVR()>>16 ) - { - case 4: /* 604 */ - case 9: /* 604e */ - case 10: /* 604ev5 */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { /* setup mmcr0 and clear the correct pmc */ asm volatile( "mfspr %0,%1\n\t" /* get current mccr0 */ @@ -393,11 +346,7 @@ if ( !strncmp( buffer, "itlb", 4) ) { - switch ( _get_PVR()>>16 ) - { - case 4: /* 604 */ - case 9: /* 604e */ - case 10: /* 604ev5 */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { /* setup mmcr0 and clear the correct pmc */ asm volatile( "mfspr %0,%1\n\t" /* get current mccr0 */ @@ -413,11 +362,7 @@ if ( !strncmp( buffer, "dc miss", 7) ) { - switch ( _get_PVR()>>16 ) - { - case 4: /* 604 */ - case 9: /* 604e */ - case 10: /* 604ev5 */ + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_604_PERF_MON) { /* setup mmcr0 and clear the correct pmc */ asm volatile( "mfspr %0,%1\n\t" /* get current mccr0 */ @@ -517,7 +462,7 @@ "0.5", "1.0", "(reserved2)", "(reserved3)" }; - if ( ((_get_PVR() >> 16) != 8) && ((_get_PVR() >> 16) != 12)) + if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR)) return -EFAULT; if ( /*!table->maxlen ||*/ (filp->f_pos && !write)) { diff -Nru a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c --- a/arch/ppc/kernel/ppc_ksyms.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/kernel/ppc_ksyms.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc_ksyms.c 1.34 06/09/01 22:38:13 paulus + * BK Id: %F% %I% %G% %U% %#% */ #include #include @@ -48,6 +48,7 @@ #include #endif /* CONFIG_SMP */ #include +#include #ifdef CONFIG_8xx #include "../8xx_io/commproc.h" @@ -200,9 +201,11 @@ EXPORT_SYMBOL(__global_sti); EXPORT_SYMBOL(__global_save_flags); EXPORT_SYMBOL(__global_restore_flags); +#ifdef SPINLOCK_DEBUG EXPORT_SYMBOL(_spin_lock); EXPORT_SYMBOL(_spin_unlock); EXPORT_SYMBOL(spin_trylock); +#endif EXPORT_SYMBOL(_read_lock); EXPORT_SYMBOL(_read_unlock); EXPORT_SYMBOL(_write_lock); @@ -245,7 +248,6 @@ #endif /* CONFIG_PMAC_BACKLIGHT */ #if defined(CONFIG_ALL_PPC) EXPORT_SYMBOL(_machine); -EXPORT_SYMBOL_NOVERS(have_of); EXPORT_SYMBOL_NOVERS(sys_ctrler); EXPORT_SYMBOL(find_devices); EXPORT_SYMBOL(find_type_devices); @@ -359,13 +361,13 @@ EXPORT_SYMBOL(ret_to_user_hook); EXPORT_SYMBOL(next_mmu_context); EXPORT_SYMBOL(set_context); -EXPORT_SYMBOL(mmu_context_overflow); -EXPORT_SYMBOL(flush_hash_page); /* For MOL */ EXPORT_SYMBOL(handle_mm_fault); /* For MOL */ EXPORT_SYMBOL_NOVERS(disarm_decr); #if !defined(CONFIG_8xx) && !defined(CONFIG_4xx) +EXPORT_SYMBOL(flush_hash_page); /* For MOL */ extern long *intercept_table; EXPORT_SYMBOL(intercept_table); #endif extern long *ret_from_intercept; EXPORT_SYMBOL(ret_from_intercept); +EXPORT_SYMBOL(cur_cpu_spec); diff -Nru a/arch/ppc/kernel/ppc_stubs.c b/arch/ppc/kernel/ppc_stubs.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/ppc_stubs.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,40 @@ +/* + * arch/ppc/kernel/ppc_stubs.c + * + * Call stubs to allow linking without pulling in CHRP/PMAC/PREP objects + * on 6xx/7xx/74xx systems + * + * Author: Matt Porter + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +EXPORT_SYMBOL(get_property); + +__openfirmware +struct device_node * +find_path_device(const char *path) +{ + return NULL; +} + +__openfirmware +unsigned char * +get_property(struct device_node *np, const char *name, int *lenp) +{ + return NULL; +} diff -Nru a/arch/ppc/kernel/pplus.h b/arch/ppc/kernel/pplus.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/pplus.h Sat Jun 16 06:00:32 2001 @@ -0,0 +1,91 @@ +/* + * arch/ppc/kernel/pplus.h + * + * Definitions for Motorola MCG Falcon/Raven & HAWK North Bridge & Memory ctlr. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASMPPC_PPLUS_H +#define __ASMPPC_PPLUS_H + +#include + +/* + * The Falcon/Raven and HAWK have 4 sets of registers: + * 1) PPC Registers which define the mappings from PPC bus to PCI bus, + * etc. + * 2) PCI Registers which define the mappings from PCI bus to PPC bus and the + * MPIC base address. + * 3) MPIC registers + * 4) System Memory Controller (SMC) registers. + */ + +#define PPLUS_RAVEN_VEND_DEV_ID 0x48011057 +#define PPLUS_HAWK_VEND_DEV_ID 0x48031057 + +#define PPLUS_MPIC_SIZE 0x00030000U +#define PPLUS_SMC_SIZE 0x00001000U + +/* + * Define PPC register offsets. + */ +#define PPLUS_PPC_XSADD0_OFF 0x40 +#define PPLUS_PPC_XSOFF0_OFF 0x44 +#define PPLUS_PPC_XSADD1_OFF 0x48 +#define PPLUS_PPC_XSOFF1_OFF 0x4c +#define PPLUS_PPC_XSADD2_OFF 0x50 +#define PPLUS_PPC_XSOFF2_OFF 0x54 +#define PPLUS_PPC_XSADD3_OFF 0x58 +#define PPLUS_PPC_XSOFF3_OFF 0x5c + +/* + * Define PCI register offsets. + */ +#define PPLUS_PCI_PSADD0_OFF 0x80 +#define PPLUS_PCI_PSOFF0_OFF 0x84 +#define PPLUS_PCI_PSADD1_OFF 0x88 +#define PPLUS_PCI_PSOFF1_OFF 0x8c +#define PPLUS_PCI_PSADD2_OFF 0x90 +#define PPLUS_PCI_PSOFF2_OFF 0x94 +#define PPLUS_PCI_PSADD3_OFF 0x98 +#define PPLUS_PCI_PSOFF3_OFF 0x9c + +/* + * Define the System Memory Controller (SMC) register offsets. + */ +#define PPLUS_SMC_RAM_A_SIZE_REG_OFF 0x10 +#define PPLUS_SMC_RAM_B_SIZE_REG_OFF 0x11 +#define PPLUS_SMC_RAM_C_SIZE_REG_OFF 0x12 +#define PPLUS_SMC_RAM_D_SIZE_REG_OFF 0x13 +#define PPLUS_SMC_RAM_E_SIZE_REG_OFF 0xc0 /* HAWK Only */ +#define PPLUS_SMC_RAM_F_SIZE_REG_OFF 0xc1 /* HAWK Only */ +#define PPLUS_SMC_RAM_G_SIZE_REG_OFF 0xc2 /* HAWK Only */ +#define PPLUS_SMC_RAM_H_SIZE_REG_OFF 0xc3 /* HAWK Only */ + +#define PPLUS_FALCON_SMC_REG_COUNT 4 +#define PPLUS_HAWK_SMC_REG_COUNT 8 + + + +int pplus_init(struct pci_controller *hose, + uint ppc_reg_base, + ulong processor_pci_mem_start, + ulong processor_pci_mem_end, + ulong processor_pci_io_start, + ulong processor_pci_io_end, + ulong processor_mpic_base); + +unsigned long pplus_get_mem_size(uint smc_base); + +int pplus_mpic_init(unsigned int pci_mem_offset); + +#endif /* __ASMPPC_PPLUS_H */ diff -Nru a/arch/ppc/kernel/pplus_common.c b/arch/ppc/kernel/pplus_common.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/pplus_common.c Sat Jun 16 06:00:32 2001 @@ -0,0 +1,297 @@ +/* + * arch/ppc/kernel/pplus_common.c + * + * Common Motorola PowerPlus Platform--really Falcon/Raven or HAWK. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "pci.h" +#include "open_pic.h" +#include "pplus.h" + +/* + * The Falcon/Raven and HAWK has 4 sets of registers: + * 1) PPC Registers which define the mappings from PPC bus to PCI bus, + * etc. + * 2) PCI Registers which define the mappings from PCI bus to PPC bus and the + * MPIC base address. + * 3) MPIC registers. + * 4) System Memory Controller (SMC) registers. + */ + +/* + * Initialize the Motorola MCG Raven or HAWK host bridge. + * + * This means setting up the PPC bus to PCI memory and I/O space mappings, + * setting the PCI memory space address of the MPIC (mapped straight + * through), and ioremap'ing the mpic registers. + * 'OpenPIC_Addr' will be set correctly by this routine. + * This routine will not change the PCI_CONFIG_ADDR or PCI_CONFIG_DATA + * addresses and assumes that the mapping of PCI memory space back to system + * memory is set up correctly by PPCBug. + */ +int __init +pplus_init(struct pci_controller *hose, + uint ppc_reg_base, + ulong processor_pci_mem_start, + ulong processor_pci_mem_end, + ulong processor_pci_io_start, + ulong processor_pci_io_end, + ulong processor_mpic_base) +{ + uint addr, offset; + + /* + * Some sanity checks... + */ + if (((processor_pci_mem_start&0xffff0000) != processor_pci_mem_start) || + ((processor_pci_io_start &0xffff0000) != processor_pci_io_start)) { + printk("pplus_init: %s\n", + "PPC to PCI mappings must start on 64 MB boundaries"); + return -1; + } + + if (((processor_pci_mem_end &0x0000ffff) != 0x0000ffff) || + ((processor_pci_io_end &0x0000ffff) != 0x0000ffff)) { + printk("pplus_init: PPC to PCI mappings %s\n", + "must end just before a 64 MB boundaries"); + return -1; + } + + if (((processor_pci_mem_end - processor_pci_mem_start) != + (hose->mem_space.end - hose->mem_space.start)) || + ((processor_pci_io_end - processor_pci_io_start) != + (hose->io_space.end - hose->io_space.start))) { + printk("pplus_init: %s\n", + "PPC and PCI memory or I/O space sizes don't match"); + return -1; + } + + if ((processor_mpic_base & 0xfffc0000) != processor_mpic_base) { + printk("pplus_init: %s\n", + "MPIC address must start on 256 MB boundary"); + return -1; + } + + if ((pci_dram_offset & 0xffff0000) != pci_dram_offset) { + printk("pplus_init: %s\n", + "pci_dram_offset must be multiple of 64 MB"); + return -1; + } + + /* + * Program the XSADD/XSOFF registers to set up the PCI Mem & I/O + * space mappings. These are the mappings going from the processor to + * the PCI bus. + * + * Note: Don't need to 'AND' start/end addresses with 0xffff0000 + * because sanity check above ensures that they are properly + * aligned. + */ + + /* Set up PPC->PCI Mem mapping */ + addr = processor_pci_mem_start | (processor_pci_mem_end >> 16); + offset = (hose->mem_space.start - processor_pci_mem_start) | 0xd2; + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSADD0_OFF), addr); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF0_OFF), offset); + + /* Set up PPC->PCI I/O mapping -- Contiguous I/O space */ + addr = processor_pci_io_start | (processor_pci_io_end >> 16); + offset = (hose->io_space.start - processor_pci_io_start) | 0xc0; + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSADD1_OFF), addr); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF1_OFF), offset); + + /* Set up PPC->MPIC mapping on the bridge--mapped straight through */ + addr = processor_mpic_base | + (((processor_mpic_base + PPLUS_MPIC_SIZE) >> 16) - 1); + offset = 0xc2; /* No write posting for this PCI Mem space */ + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSADD2_OFF), addr); + out_be32((uint *)(ppc_reg_base + PPLUS_PPC_XSOFF2_OFF), offset); + + /* + * Disable MPIC response to PCI I/O space (BAR 0). + * Make MPIC respond to PCI Mem space at specified address. + * (BAR 1). + */ + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_BASE_ADDRESS_0, + 0x00000000 | 0x1); + + early_write_config_dword(hose, + 0, + PCI_DEVFN(0,0), + PCI_BASE_ADDRESS_1, + processor_mpic_base | 0x0); + + /* Map MPIC into vitual memory */ + OpenPIC_Addr = ioremap(processor_mpic_base, PPLUS_MPIC_SIZE); + + return 0; +} + +/* + * Find the amount of RAM present. + * This assumes that PPCBug has initialized the memory controller (SMC) + * on the Falcon/HAWK correctly (i.e., it does no sanity checking). + * It also assumes that the memory base registers are set to configure the + * memory as contigous starting with "RAM A BASE", "RAM B BASE", etc. + * however, RAM base registers can be skipped (e.g. A, B, C are set, + * D is skipped but E is set is okay). + */ +#define MB (1024*1024) + +static uint __init reg_offset_table[] = { + PPLUS_SMC_RAM_A_SIZE_REG_OFF, + PPLUS_SMC_RAM_B_SIZE_REG_OFF, + PPLUS_SMC_RAM_C_SIZE_REG_OFF, + PPLUS_SMC_RAM_D_SIZE_REG_OFF, + PPLUS_SMC_RAM_E_SIZE_REG_OFF, + PPLUS_SMC_RAM_F_SIZE_REG_OFF, + PPLUS_SMC_RAM_G_SIZE_REG_OFF, + PPLUS_SMC_RAM_H_SIZE_REG_OFF +}; + +static uint __init falcon_size_table[] = { + 0 * MB, /* 0 ==> 0 MB */ + 16 * MB, /* 1 ==> 16 MB */ + 32 * MB, /* 2 ==> 32 MB */ + 64 * MB, /* 3 ==> 64 MB */ + 128 * MB, /* 4 ==> 128 MB */ + 256 * MB, /* 5 ==> 256 MB */ + 1024 * MB, /* 6 ==> 1024 MB (1 GB) */ +}; + +static uint __init hawk_size_table[] = { + 0 * MB, /* 0 ==> 0 MB */ + 32 * MB, /* 1 ==> 32 MB */ + 64 * MB, /* 2 ==> 64 MB */ + 64 * MB, /* 3 ==> 64 MB */ + 128 * MB, /* 4 ==> 128 MB */ + 128 * MB, /* 5 ==> 128 MB */ + 128 * MB, /* 6 ==> 128 MB */ + 256 * MB, /* 7 ==> 256 MB */ + 256 * MB, /* 8 ==> 256 MB */ + 512 * MB, /* 9 ==> 512 MB */ +}; + +/* + * *** WARNING: You MUST have a BAT set up to map in the SMC regs *** + * + * Read the memory controller's registers to determine the amount of system + * memory. Assumes that the memory controller registers are already mapped + * into virtual memory--too early to use ioremap(). + */ +unsigned long __init +pplus_get_mem_size(uint smc_base) +{ + unsigned long total; + int i, size_table_entries, reg_limit; + uint vend_dev_id; + uint *size_table; + u_char val; + + + vend_dev_id = in_be32((uint *)smc_base + PCI_VENDOR_ID); + + if (((vend_dev_id & 0xffff0000) >> 16) != PCI_VENDOR_ID_MOTOROLA) { + printk("pplus_get_mem_size: %s (0x%x)\n", + "Not a Motorola Memory Controller", vend_dev_id); + return 0; + } + + vend_dev_id &= 0x0000ffff; + + if (vend_dev_id == PCI_DEVICE_ID_MOTOROLA_FALCON) { + size_table = falcon_size_table; + size_table_entries = sizeof(falcon_size_table) / + sizeof(falcon_size_table[0]); + + reg_limit = PPLUS_FALCON_SMC_REG_COUNT; + } + else if (vend_dev_id == PCI_DEVICE_ID_MOTOROLA_HAWK) { + size_table = hawk_size_table; + size_table_entries = sizeof(hawk_size_table) / + sizeof(hawk_size_table[0]); + reg_limit = PPLUS_HAWK_SMC_REG_COUNT; + } + else { + printk("pplus_get_mem_size: %s (0x%x)\n", + "Not a Falcon or HAWK", vend_dev_id); + return 0; + } + + total = 0; + + /* Check every reg because PPCBug may skip some */ + for (i=0; i 4) + return; + intpin = (PCI_SLOT(dev->devfn) + intpin - 1) & 3; + dev->irq = bridge_intrs[intpin]; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); +} + +void __init prep_route_pci_interrupts(void) { unsigned char *ibc_pirq = (unsigned char *)0x80800860; unsigned char *ibc_pcicon = (unsigned char *)0x80800840; @@ -856,7 +939,13 @@ Motherboard_map_name = "IBM 6015"; Motherboard_map = ibm6015_pci_IRQ_map; Motherboard_routes = ibm6015_pci_IRQ_routes; - break; + break; + case 0xd5: + Motherboard_map_name = "IBM 43p/140"; + Motherboard_map = ibm43p_pci_IRQ_map; + Motherboard_routes = ibm43p_pci_IRQ_routes; + Motherboard_non0 = ibm43p_pci_map_non0; + break; default: Motherboard_map_name = "IBM 8xx (Carolina)"; Motherboard_map = ibm8xx_pci_IRQ_map; @@ -878,7 +967,7 @@ else { printk("No known machine pci routing!\n"); - return -1; + return; } /* Set up mapping from slots */ @@ -888,16 +977,15 @@ } /* Enable PCI interrupts */ *ibc_pcicon |= 0x20; - return 0; } void __init prep_pib_init(void) { -unsigned char reg; -unsigned short short_reg; + unsigned char reg; + unsigned short short_reg; -struct pci_dev *dev = NULL; + struct pci_dev *dev = NULL; if (( _prep_type == _PREP_Motorola) && (OpenPIC_Addr)) { /* @@ -910,54 +998,47 @@ * PPCBUG does not set the enable bits * for the IDE device. Force them on here. */ - pcibios_read_config_byte(dev->bus->number, - dev->devfn, 0x40, ®); + pci_read_config_byte(dev, 0x40, ®); reg |= 0x03; /* IDE: Chip Enable Bits */ - pcibios_write_config_byte(dev->bus->number, - dev->devfn, 0x40, reg); - - /* Force correct IDE function interrupt */ - dev->irq = 14; - pcibios_write_config_byte(dev->bus->number, - dev->devfn, + pci_write_config_byte(dev, 0x40, reg); + } + if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, + PCI_DEVICE_ID_VIA_82C586_2, + dev)) && (dev->devfn = 0x5a)) { + /* Force correct USB interrupt */ + dev->irq = 11; + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); - - } else if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, + } + if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, dev))) { - /* - * Clear the PCI Interrupt Routing Control Register. - */ + /* Clear PCI Interrupt Routing Control Register. */ short_reg = 0x0000; pci_write_config_word(dev, 0x44, short_reg); if (OpenPIC_Addr){ - /* - * Route both IDE interrupts to IRQ 14 - */ + /* Route IDE interrupts to IRQ 14 */ reg = 0xEE; - pci_write_config_byte(dev, 0x44, reg); + pci_write_config_byte(dev, 0x43, reg); } } - if ((dev = pci_find_device(PCI_VENDOR_ID_VIA, - PCI_DEVICE_ID_VIA_82C586_2, - dev))) - { - /* Force correct USB function interrupt */ - dev->irq = 11; - pcibios_write_config_byte(dev->bus->number, - dev->devfn, - PCI_INTERRUPT_LINE, - dev->irq); - } } + if ((dev = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, dev))){ if (OpenPIC_Addr){ - /* Disable LEGIRQ mode so PCI INTs are routed to - the 8259 */ - printk("Set winbond IDE to native mode\n"); - pci_write_config_dword(dev, 0x40, 0x10ff00a1); + /* + * Disable LEGIRQ mode so PCI INTS are routed + * directly to the 8259 and enable both channels + */ + pci_write_config_dword(dev, 0x40, 0x10ff0033); + + /* Force correct IDE interrupt */ + dev->irq = 14; + pci_write_config_byte(dev, + PCI_INTERRUPT_LINE, + dev->irq); }else{ /* Enable LEGIRQ for PCI INT -> 8259 IRQ routing */ pci_write_config_dword(dev, 0x40, 0x10ff08a1); @@ -1117,6 +1198,19 @@ } } +static void __init +prep_init_resource(struct resource *res, unsigned long start, + unsigned long end, int flags) +{ + res->flags = flags; + res->start = start; + res->end = end; + res->name = "PCI host bridge"; + res->parent = NULL; + res->sibling = NULL; + res->child = NULL; +} + void __init prep_find_bridges(void) { @@ -1130,6 +1224,9 @@ hose->last_busno = 0xff; hose->pci_mem_offset = PREP_ISA_MEM_BASE; hose->io_base_virt = (void *)PREP_ISA_IO_BASE; + prep_init_resource(&hose->io_resource, 0, 0x0fffffff, IORESOURCE_IO); + prep_init_resource(&hose->mem_resources[0], 0xc0000000, 0xfeffffff, + IORESOURCE_MEM); printk("PReP architecture\n"); { diff -Nru a/arch/ppc/kernel/prep_setup.c b/arch/ppc/kernel/prep_setup.c --- a/arch/ppc/kernel/prep_setup.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/kernel/prep_setup.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.prep_setup.c 1.20 05/21/01 09:19:50 trini + * BK Id: SCCS/s.prep_setup.c 1.20 05/21/01 09:19:50 %#% */ /* * linux/arch/ppc/kernel/setup.c @@ -77,6 +77,7 @@ extern unsigned char rs_nvram_read_val(int addr); extern void rs_nvram_write_val(int addr, unsigned char val); +extern void ibm_prep_init(void); extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode); extern int pckbd_getkeycode(unsigned int scancode); @@ -329,13 +330,20 @@ /*print_residual_device_info();*/ - raven_init(); + switch (_prep_type) { + case _PREP_Motorola: + raven_init(); + break; + case _PREP_IBM: + ibm_prep_init(); + break; + } #ifdef CONFIG_VGA_CONSOLE /* remap the VGA memory */ vgacon_remap_base = 0xf0000000; /*vgacon_remap_base = ioremap(0xc0000000, 0xba000);*/ - conswitchp = &vga_con; + conswitchp = &vga_con; #elif defined(CONFIG_DUMMY_CONSOLE) conswitchp = &dummy_con; #endif @@ -640,13 +648,13 @@ void __prep prep_ide_insw(ide_ioreg_t port, void *buf, int ns) { - _insw((unsigned short *)((port)+_IO_BASE), buf, ns); + _insw_ns((unsigned short *)((port)+_IO_BASE), buf, ns); } void __prep prep_ide_outsw(ide_ioreg_t port, void *buf, int ns) { - _outsw((unsigned short *)((port)+_IO_BASE), buf, ns); + _outsw_ns((unsigned short *)((port)+_IO_BASE), buf, ns); } int __prep @@ -657,8 +665,9 @@ case 0x170: return 13; case 0x1e8: return 11; case 0x168: return 10; - default: - return 0; + case 0xfff0: /* MCP(N)750 ide0 */ + case 0xffe0: /* MCP(N)750 ide1 */ + default: return 0; } } @@ -852,12 +861,12 @@ #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) ppc_ide_md.insw = prep_ide_insw; ppc_ide_md.outsw = prep_ide_outsw; + ppc_ide_md.fix_driveid = ppc_generic_ide_fix_driveid; ppc_ide_md.default_irq = prep_ide_default_irq; ppc_ide_md.default_io_base = prep_ide_default_io_base; ppc_ide_md.ide_check_region = prep_ide_check_region; ppc_ide_md.ide_request_region = prep_ide_request_region; ppc_ide_md.ide_release_region = prep_ide_release_region; - ppc_ide_md.fix_driveid = NULL; ppc_ide_md.ide_init_hwif = prep_ide_init_hwif_ports; #endif ppc_ide_md.io_base = _IO_BASE; diff -Nru a/arch/ppc/kernel/prep_time.c b/arch/ppc/kernel/prep_time.c --- a/arch/ppc/kernel/prep_time.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/kernel/prep_time.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.prep_time.c 1.7 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/i386/kernel/time.c diff -Nru a/arch/ppc/kernel/proc_rtas.c b/arch/ppc/kernel/proc_rtas.c --- a/arch/ppc/kernel/proc_rtas.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/kernel/proc_rtas.c Sat Jun 16 06:00:32 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.proc_rtas.c 1.5 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/proc_rtas.c diff -Nru a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c --- a/arch/ppc/kernel/process.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/kernel/process.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.process.c 1.15 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/process.c @@ -152,6 +152,19 @@ return 1; } +void +msr_vec_debug(struct task_struct *tsk) +{ + printk("giveup_altivec called on non-altivec process (cpu %d)\n", + smp_processor_id()); + printk("task = %p, current = %p, task->thead.regs %p\n", + tsk, current, tsk->thread.regs); + printk("task->pid %d, task->thread.regs->msr 0x%lx\n", + tsk->pid, tsk->thread.regs->msr); + + print_backtrace(_get_SP()); +} + void enable_kernel_altivec(void) { @@ -267,6 +280,15 @@ printk("Last syscall: %ld ", current->thread.last_syscall); printk("\nlast math %p last altivec %p", last_task_used_math, last_task_used_altivec); + +#ifdef CONFIG_4xx + printk("\nPLB0: bear= 0x%8.8x acr= 0x%8.8x besr= 0x%8.8x\n", + mfdcr(DCRN_POB0_BEAR), mfdcr(DCRN_PLB0_ACR), + mfdcr(DCRN_PLB0_BESR)); + printk("PLB0 to OPB: bear= 0x%8.8x besr0= 0x%8.8x besr1= 0x%8.8x\n", + mfdcr(DCRN_PLB0_BEAR), mfdcr(DCRN_POB0_BESR0), + mfdcr(DCRN_POB0_BESR1)); +#endif #ifdef CONFIG_SMP printk(" CPU: %d", current->processor); @@ -289,7 +311,8 @@ printk("\n"); } } -out: ; +out: + print_backtrace((unsigned long *)regs->gpr[1]); } void exit_thread(void) @@ -343,9 +366,14 @@ kregs->gpr[1] = (unsigned long)childregs - STACK_FRAME_OVERHEAD; kregs->gpr[2] = (unsigned long)p; - if (usp >= (unsigned long) regs) { + if ((usp >= (unsigned long) regs) || (usp == 0 && p->pid == 0)) { + /* usp == 0 && p->pid == 0 is special case for the + * do_fork in smp.c. This is the wrong way to fix this, + * but I'm not completely sure why this adjustment is + * necessary... --Troy */ /* Stack is in kernel space - must adjust */ childregs->gpr[1] = (unsigned long)(childregs + 1); + p->thread.regs = NULL; } else { /* Provided stack is in user space */ childregs->gpr[1] = usp; @@ -384,6 +412,8 @@ void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp) { set_fs(USER_DS); + memset(regs->gpr, 0, sizeof(regs->gpr)); + memset(®s->ctr, 0, 5 * sizeof(regs->ctr)); regs->nip = nip; regs->gpr[1] = sp; regs->msr = MSR_USER; diff -Nru a/arch/ppc/kernel/prom.c b/arch/ppc/kernel/prom.c --- a/arch/ppc/kernel/prom.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/kernel/prom.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.prom.c 1.23 06/06/01 22:49:01 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Procedures for interfacing to the Open Firmware PROM on @@ -116,8 +116,11 @@ unsigned int rtas_size; unsigned int old_rtas; -/* Set for a newworld machine */ +/* Set for a newworld or CHRP machine */ int use_of_interrupt_tree; +struct device_node *dflt_interrupt_controller; +int num_interrupt_controllers; + int pmac_newworld; static struct device_node *allnodes; @@ -174,7 +177,6 @@ #endif extern void enter_rtas(void *); -extern unsigned long reloc_offset(void); void phys_call_rtas(int, int, int, ...); extern char cmd_line[512]; /* XXX */ @@ -192,6 +194,14 @@ #define BOOT_INFO_IS_V2_COMPATIBLE(bi) ((bi)->version >= 2) #define BOOT_INFO_IS_V4_COMPATIBLE(bi) ((bi)->version >= 4) +/* + * Note that prom_init() and anything called from prom_init() must + * use the RELOC/PTRRELOC macros to access any static data in + * memory, since the kernel may be running at an address that is + * different from the address that it was linked at. + * (Note that strings count as static variables.) + */ + __init static void prom_exit() @@ -480,13 +490,14 @@ unsigned int va, unsigned int pa, int mode) { unsigned int *pteg; - unsigned int hash, i; + unsigned int hash, i, vsid; - hash = ((va >> 5) ^ (va >> 21)) & 0x7fff80; + vsid = ((va >> 28) * 0x111) << 12; + hash = ((va ^ vsid) >> 5) & 0x7fff80; pteg = (unsigned int *)(htab + (hash & (hsize - 1))); for (i = 0; i < 8; ++i, pteg += 4) { if ((pteg[1] & 1) == 0) { - pteg[1] = ((va >> 16) & 0xff80) | 1; + pteg[1] = vsid | ((va >> 16) & 0xf80) | 1; pteg[3] = pa | mode; break; } @@ -1145,7 +1156,19 @@ *prev_propp = PTRUNRELOC(pp); prev_propp = &pp->next; } - *prev_propp = 0; + if (np->node != NULL) { + /* Add a "linux,phandle" property" */ + pp = (struct property *) mem_start; + *prev_propp = PTRUNRELOC(pp); + prev_propp = &pp->next; + namep = (char *) (pp + 1); + pp->name = PTRUNRELOC(namep); + strcpy(namep, RELOC("linux,phandle")); + mem_start = ALIGN((unsigned long)namep + strlen(namep) + 1); + pp->value = (unsigned char *) PTRUNRELOC(&np->node); + pp->length = sizeof(np->node); + } + *prev_propp = NULL; /* get the node's full name */ l = (int) call_prom(RELOC("package-to-path"), 3, 1, node, @@ -1178,19 +1201,36 @@ finish_device_tree(void) { unsigned long mem = (unsigned long) klimit; + struct device_node *np; - /* All newworld machines now use the interrupt tree */ - struct device_node *np = allnodes; - - while(np && (_machine == _MACH_Pmac)) { + /* All newworld pmac machines and CHRPs now use the interrupt tree */ + for (np = allnodes; np != NULL; np = np->allnext) { if (get_property(np, "interrupt-parent", 0)) { - pmac_newworld = 1; + use_of_interrupt_tree = 1; break; } - np = np->allnext; } - if ((_machine == _MACH_chrp) || (boot_infos == 0 && pmac_newworld)) - use_of_interrupt_tree = 1; + if (use_of_interrupt_tree) { + /* + * We want to find out here how many interrupt-controller + * nodes there are, and if we are booted from BootX, + * we need a pointer to the first (and hopefully only) + * such node. But we can't use find_devices here since + * np->name has not been set yet. -- paulus + */ + int n = 0; + char *name; + + for (np = allnodes; np != NULL; np = np->allnext) { + if ((name = get_property(np, "name", NULL)) == NULL + || strcmp(name, "interrupt-controller") != 0) + continue; + if (n == 0) + dflt_interrupt_controller = np; + ++n; + } + num_interrupt_controllers = n; + } mem = finish_node(allnodes, mem, NULL, 1, 1); dev_tree_size = mem - (unsigned long) allnodes; @@ -1232,9 +1272,8 @@ if (ifunc != NULL) { mem_start = ifunc(np, mem_start, naddrc, nsizec); } - if (use_of_interrupt_tree) { + if (use_of_interrupt_tree) mem_start = finish_node_interrupts(np, mem_start); - } /* Look for #address-cells and #size-cells properties. */ ip = (int *) get_property(np, "#address-cells", 0); @@ -1290,141 +1329,210 @@ return mem_start; } -/* This routine walks the interrupt tree for a given device node and gather - * all necessary informations according to the draft interrupt mapping - * for CHRP. The current version was only tested on Apple "Core99" machines - * and may not handle cascaded controllers correctly. +/* + * Find the interrupt parent of a node. */ -__init -static unsigned long -finish_node_interrupts(struct device_node *np, unsigned long mem_start) +static struct device_node *intr_parent(struct device_node *p) { - /* Finish this node */ - unsigned int *isizep, *asizep, *interrupts, *map, *map_mask, *reg; - phandle *parent; - struct device_node *node, *parent_node; - int l, isize, ipsize, asize, map_size, regpsize; - - /* Currently, we don't look at all nodes with no "interrupts" property */ - interrupts = (unsigned int *)get_property(np, "interrupts", &l); - if (interrupts == NULL) - return mem_start; - ipsize = l>>2; + phandle *parp; - reg = (unsigned int *)get_property(np, "reg", &l); - regpsize = l>>2; + parp = (phandle *) get_property(p, "interrupt-parent", NULL); + if (parp == NULL) + return p->parent; + p = find_phandle(*parp); + if (p != NULL) + return p; + /* + * On a powermac booted with BootX, we don't get to know the + * phandles for any nodes, so find_phandle will return NULL. + * Fortunately these machines only have one interrupt controller + * so there isn't in fact any ambiguity. -- paulus + */ + if (num_interrupt_controllers == 1) + p = dflt_interrupt_controller; + return p; +} - /* We assume default interrupt cell size is 1 (bugus ?) */ - isize = 1; - node = np; - - do { - /* We adjust the cell size if the current parent contains an #interrupt-cells - * property */ - isizep = (unsigned int *)get_property(node, "#interrupt-cells", &l); - if (isizep) - isize = *isizep; - - /* We don't do interrupt cascade (ISA) for now, we stop on the first - * controller found - */ - 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 = 1; - if (isize > 1) - np->intrs[i].sense = *interrupts++; - for (j=2; jfull_name); + return 1; + } + } + printk("prom_n_intr_cells failed for %s\n", np->full_name); + return 1; +} + +/* + * Map an interrupt from a device up to the platform interrupt + * descriptor. + */ +static int +map_interrupt(unsigned int **irq, struct device_node **ictrler, + struct device_node *np, unsigned int *ints, int nintrc) +{ + struct device_node *p, *ipar; + unsigned int *imap, *imask, *ip; + int i, imaplen, match; + int newintrc, newaddrc; + unsigned int *reg; + int naddrc; + + reg = (unsigned int *) get_property(np, "reg", NULL); + naddrc = prom_n_addr_cells(np); + p = intr_parent(np); + while (p != NULL) { + if (get_property(p, "interrupt-controller", NULL) != NULL) + /* this node is an interrupt controller, stop here */ + break; + imap = (unsigned int *) + get_property(p, "interrupt-map", &imaplen); + if (imap == NULL) { + p = intr_parent(p); + continue; + } + imask = (unsigned int *) + get_property(p, "interrupt-map-mask", NULL); + if (imask == NULL) { + printk("oops, %s has interrupt-map but no mask\n", + p->full_name); + return 0; } + imaplen /= sizeof(unsigned int); + match = 0; + ipar = NULL; + while (imaplen > 0 && !match) { + /* check the child-interrupt field */ + match = 1; + for (i = 0; i < naddrc && match; ++i) + match = ((reg[i] ^ imap[i]) & imask[i]) == 0; + for (; i < naddrc + nintrc && match; ++i) + match = ((ints[i-naddrc] ^ imap[i]) & imask[i]) == 0; + imap += naddrc + nintrc; + imaplen -= naddrc + nintrc; + /* grab the interrupt parent */ + ipar = find_phandle((phandle) *imap++); + --imaplen; + if (ipar == NULL && num_interrupt_controllers == 1) + /* cope with BootX not giving us phandles */ + ipar = dflt_interrupt_controller; + if (ipar == NULL) { + printk("oops, no int parent %x in map of %s\n", + imap[-1], p->full_name); + return 0; + } + /* find the parent's # addr and intr cells */ + ip = (unsigned int *) + get_property(ipar, "#interrupt-cells", NULL); + if (ip == NULL) { + printk("oops, no #interrupt-cells on %s\n", + ipar->full_name); + return 0; + } + newintrc = *ip; + ip = (unsigned int *) + get_property(ipar, "#address-cells", NULL); + newaddrc = (ip == NULL)? 0: *ip; + imap += newaddrc + newintrc; + imaplen -= newaddrc + newintrc; + } + if (imaplen < 0) { + printk("oops, error decoding int-map on %s, len=%d\n", + p->full_name, imaplen); + return 0; + } + if (!match) { + printk("oops, no match in %s int-map for %s\n", + p->full_name, np->full_name); + return 0; + } + p = ipar; + naddrc = newaddrc; + nintrc = newintrc; + ints = imap - nintrc; + reg = ints - naddrc; + } + if (p == NULL) + printk("hmmm, int tree for %s doesn't have ctrler\n", + np->full_name); + *irq = ints; + *ictrler = p; + return nintrc; +} + +/* + * New version of finish_node_interrupts. + */ +static unsigned long +finish_node_interrupts(struct device_node *np, unsigned long mem_start) +{ + unsigned int *ints; + int intlen, intrcells; + int i, j, n, offset; + unsigned int *irq; + struct device_node *ic; + + ints = (unsigned int *) get_property(np, "interrupts", &intlen); + if (ints == NULL) return mem_start; - } - /* We lookup for an interrupt-map. This code can only handle one interrupt - * per device in the map. We also don't handle #address-cells in the parent - * I skip the pci node itself here, may not be necessary but I don't like it's - * reg property. - */ - if (np != node) - map = (unsigned int *)get_property(node, "interrupt-map", &l); - else - map = NULL; - if (map && l) { - int i, found, temp_isize; - map_size = l>>2; - map_mask = (unsigned int *)get_property(node, "interrupt-map-mask", &l); - asizep = (unsigned int *)get_property(node, "#address-cells", &l); - if (asizep && l == sizeof(unsigned int)) - asize = *asizep; - else - asize = 0; - found = 0; - while(map_size>0 && !found) { - found = 1; - for (i=0; i=regpsize) || ((mask & *map) != (mask & reg[i]))) - found = 0; - map++; - map_size--; - } - for (i=0; iparent; - } while(node); + intrcells = prom_n_intr_cells(np); + intlen /= intrcells * sizeof(unsigned int); + np->n_intrs = intlen; + np->intrs = (struct interrupt_info *) mem_start; + mem_start += intlen * sizeof(struct interrupt_info); + + for (i = 0; i < intlen; ++i) { + np->intrs[i].line = 0; + np->intrs[i].sense = 1; + n = map_interrupt(&irq, &ic, np, ints, intrcells); + if (n <= 0) + continue; + offset = 0; + /* + * On a CHRP we have an 8259 which is subordinate to + * the openpic in the interrupt tree, but we want the + * openpic's interrupt numbers offsetted, not the 8259's. + * So we apply the offset if the controller is at the + * root of the interrupt tree, i.e. has no interrupt-parent. + * This doesn't cope with the general case of multiple + * cascaded interrupt controllers, but then neither will + * irq.c at the moment either. -- paulus + */ + if (num_interrupt_controllers > 1 && ic != NULL + && get_property(ic, "interrupt-parent", NULL) == NULL) + offset = 16; + np->intrs[i].line = irq[0] + offset; + if (n > 1) + np->intrs[i].sense = irq[1]; + if (n > 2) { + printk("hmmm, got %d intr cells for %s:", n, + np->full_name); + for (j = 0; j < n; ++j) + printk(" %d", irq[j]); + printk("\n"); + } + ints += intrcells; + } return mem_start; } - /* * When BootX makes a copy of the device tree from the MacOS * Name Registry, it is in the format we use but all of the pointers @@ -1467,7 +1575,7 @@ ip = (int *) get_property(np, "#address-cells", 0); if (ip != NULL) return *ip; - } while(np->parent); + } while (np->parent); /* No #address-cells property for the root node, default to 1 */ return 1; } @@ -1482,7 +1590,7 @@ ip = (int *) get_property(np, "#size-cells", 0); if (ip != NULL) return *ip; - } while(np->parent); + } while (np->parent); /* No #size-cells property for the root node, default to 1 */ return 1; } @@ -1494,8 +1602,7 @@ { struct address_range *adr; struct pci_reg_property *pci_addrs; - int i, l, *ip, ml; - struct pci_intr_map *imp; + int i, l, *ip; pci_addrs = (struct pci_reg_property *) get_property(np, "assigned-addresses", &l); @@ -1517,44 +1624,6 @@ if (use_of_interrupt_tree) return mem_start; - /* - * If the pci host bridge has an interrupt-map property, - * look for our node in it. - */ - if (np->parent != 0 && pci_addrs != 0 - && (imp = (struct pci_intr_map *) - get_property(np->parent, "interrupt-map", &ml)) != 0 - && (ip = (int *) get_property(np, "interrupts", &l)) != 0) { - unsigned int devfn = pci_addrs[0].addr.a_hi & 0xff00; - unsigned int cell_size; - struct device_node* np2; - /* This is hackish, but is only used for BootX booting */ - cell_size = sizeof(struct pci_intr_map); - np2 = np->parent; - while(np2) { - if (device_is_compatible(np2, "uni-north")) { - cell_size += 4; - break; - } - np2 = np2->parent; - } - np->n_intrs = 0; - np->intrs = (struct interrupt_info *) mem_start; - for (i = 0; (ml -= cell_size) >= 0; ++i) { - if (imp->addr.a_hi == devfn) { - np->intrs[np->n_intrs].line = imp->intr; - np->intrs[np->n_intrs].sense = 1; /* FIXME */ - ++np->n_intrs; - } - imp = (struct pci_intr_map *)(((unsigned int)imp) - + cell_size); - } - if (np->n_intrs == 0) - np->intrs = 0; - mem_start += np->n_intrs * sizeof(struct interrupt_info); - return mem_start; - } - ip = (int *) get_property(np, "AAPL,interrupts", &l); if (ip == 0 && np->parent) ip = (int *) get_property(np->parent, "AAPL,interrupts", &l); @@ -1669,26 +1738,10 @@ ip = (int *) get_property(np, "AAPL,interrupts", &l); if (ip != 0) { np->intrs = (struct interrupt_info *) mem_start; - if (_machine == _MACH_Pmac) { - /* for the iMac */ - np->n_intrs = l / sizeof(int); - /* Hack for BootX on Core99 */ - if (keylargo) - np->n_intrs = np->n_intrs/2; - for (i = 0; i < np->n_intrs; ++i) { - np->intrs[i].line = *ip++; - if (keylargo) - np->intrs[i].sense = *ip++; - else - np->intrs[i].sense = 1; - } - } else { - /* CHRP machines */ - np->n_intrs = l / (2 * sizeof(int)); - for (i = 0; i < np->n_intrs; ++i) { - np->intrs[i].line = openpic_to_irq(*ip++); - np->intrs[i].sense = *ip++; - } + np->n_intrs = l / sizeof(int); + for (i = 0; i < np->n_intrs; ++i) { + np->intrs[i].line = *ip++; + np->intrs[i].sense = 1; } mem_start += np->n_intrs * sizeof(struct interrupt_info); } @@ -1970,13 +2023,12 @@ { struct property *pp; - for (pp = np->properties; pp != 0; pp = pp->next) { + for (pp = np->properties; pp != 0; pp = pp->next) if (pp->name != NULL && strcmp(pp->name, name) == 0) { if (lenp != 0) *lenp = pp->length; return pp->value; } - } return 0; } diff -Nru a/arch/ppc/kernel/prpmc750.h b/arch/ppc/kernel/prpmc750.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/prpmc750.h Sat Jun 16 06:00:31 2001 @@ -0,0 +1,56 @@ +/* + * include/asm-ppc/prpmc750.h + * + * Definitions for Motorola PrPMC750 board support + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#ifndef __ASMPPC_PRPMC750_H +#define __ASMPPC_PRPMC750_H + +#include + +#define PRPMC750_PCI_CONFIG_ADDR 0x80000cf8 +#define PRPMC750_PCI_CONFIG_DATA 0x80000cfc + +#define PRPMC750_PCI_PHY_MEM_BASE 0xc0000000 +#define PRPMC750_PCI_MEM_BASE 0xf0000000 +#define PRPMC750_PCI_IO_BASE 0x80000000 + +#define PRPMC750_ISA_IO_BASE PRPMC750_PCI_IO_BASE +#define PRPMC750_ISA_MEM_BASE PRPMC750_PCI_MEM_BASE +#define PRPMC750_PCI_MEM_OFFSET PRPMC750_PCI_PHY_MEM_BASE + +#define PRPMC750_SYS_MEM_BASE 0x80000000 + +#define PRPMC750_HAWK_SMC_BASE 0xfef80000 + +#define PRPMC750_BASE_BAUD 1843200 +#define PRPMC750_SERIAL_0 0xfef88000 +#define PRPMC750_SERIAL_0_DLL (PRPMC750_SERIAL_0 + (UART_DLL << 4)) +#define PRPMC750_SERIAL_0_DLM (PRPMC750_SERIAL_0 + (UART_DLM << 4)) +#define PRPMC750_SERIAL_0_LCR (PRPMC750_SERIAL_0 + (UART_LCR << 4)) + +#define PRPMC750_STATUS_REG 0xfef88080 +#define PRPMC750_BAUDOUT_MASK 0x02 +#define PRPMC750_MONARCH_MASK 0x01 + +#define PRPMC750_MODRST_REG 0xfef880a0 +#define PRPMC750_MODRST_MASK 0x01 + +#define PRPMC750_PIRQ_REG 0xfef880b0 +#define PRPMC750_SEL1_MASK 0x02 +#define PRPMC750_SEL0_MASK 0x01 + +#define PRPMC750_TBEN_REG 0xfef880c0 +#define PRPMC750_TBEN_MASK 0x01 + +#endif /* __ASMPPC_PRPMC750_H */ diff -Nru a/arch/ppc/kernel/prpmc750_pci.c b/arch/ppc/kernel/prpmc750_pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/prpmc750_pci.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,138 @@ +/* + * arch/ppc/kernel/prpmc750_pci.c + * + * PCI support for Motorola PrPMC750 + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pci.h" +#include "prpmc750.h" + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif /* DEBUG */ + +/* Motorola PrPMC750 in a PrPMCBASE */ +static inline int __init +prpmc_base_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {12, 0, 0, 0}, /* IDSEL 14 - Ethernet */ + {0, 0, 0, 0}, /* IDSEL 15 - unused */ + {10, 0, 0, 0}, /* IDSEL 16 - PMC1INTA */ + {0, 0, 0, 0}, /* IDSEL 17 - unused */ + {0, 0, 0, 0}, /* IDSEL 18 - unused */ + {0, 0, 0, 0}, /* IDSEL 19 - unused */ + {9, 0, 0, 0}, /* IDSEL 20 - DEC21554 */ + }; + const long min_idsel = 14, max_idsel = 20, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +/* Motorola PrPMC750 in a PrPMC-Carrier */ +static inline int __init +prpmc_carrier_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {10, 11, 12, 9}, /* IDSEL 16 - PMC A1 */ + {0, 0, 0, 0}, /* IDSEL 17 - unused */ + {0, 0, 0, 0}, /* IDSEL 18 - unused */ + {0, 0, 0, 0}, /* IDSEL 19 - unused */ + {9, 10, 11, 12}, /* IDSEL 20 - P2P Bridge */ + {11, 12, 9, 10}, /* IDSEL 21 - PMC A2 */ + }; + const long min_idsel = 16, max_idsel = 21, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +}; + +void __init +prpmc750_pcibios_fixup(void) +{ + struct pci_dev *dev; + unsigned short wtmp; + + /* + * Kludge to clean up after PPC6BUG which doesn't + * configure the CL5446 VGA card. Also the + * resource subsystem doesn't fixup the + * PCI mem resources on the CL5446. + */ + if ((dev = pci_find_device(PCI_VENDOR_ID_CIRRUS, + PCI_DEVICE_ID_CIRRUS_5446, 0))) + { + dev->resource[0].start += PRPMC750_PCI_PHY_MEM_BASE; + dev->resource[0].end += PRPMC750_PCI_PHY_MEM_BASE; + pci_read_config_word(dev, + PCI_COMMAND, + &wtmp); + pci_write_config_word(dev, + PCI_COMMAND, + wtmp|3); + /* Enable Color mode in MISC reg */ + outb(0x03, 0x3c2); + /* Select DRAM config reg */ + outb(0x0f, 0x3c4); + /* Set proper DRAM config */ + outb(0xdf, 0x3c5); + } +} + +void __init +prpmc750_find_bridges(void) +{ + struct pci_controller* hose; + + hose = pcibios_alloc_controller(); + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + hose->pci_mem_offset = PRPMC750_PCI_PHY_MEM_BASE; + hose->io_base_virt = (void *)PRPMC750_ISA_IO_BASE; + + setup_indirect_pci(hose, + PRPMC750_PCI_CONFIG_ADDR, + PRPMC750_PCI_CONFIG_DATA); + + ppc_md.pcibios_fixup = prpmc750_pcibios_fixup; + ppc_md.pci_swizzle = common_swizzle; +#ifdef CONFIG_PRPMC_BASE + ppc_md.pci_map_irq = prpmc_base_map_irq; +#elif CONFIG_PRPMC_CARRIER + ppc_md.pci_map_irq = prpmc_carrier_map_irq; +#endif /* Carrier specific interrupt routing */ +} diff -Nru a/arch/ppc/kernel/prpmc750_setup.c b/arch/ppc/kernel/prpmc750_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/prpmc750_setup.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,279 @@ +/* + * arch/ppc/kernel/prpmc750_setup.c + * + * Board setup routines for Motorola PrPMC750 + * + * Author: Matt Porter + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "local_irq.h" +#include "open_pic.h" +#include "pplus.h" +#include "prpmc750.h" + +extern void prpmc750_find_bridges(void); +extern int mpic_init(void); +extern unsigned long loops_per_jiffy; + +static u_char prpmc750_openpic_initsenses[] __initdata = +{ + 1, /* PRPMC750_INT_HOSTINT0 */ + 1, /* PRPMC750_INT_UART */ + 1, /* PRPMC750_INT_DEBUGINT */ + 1, /* PRPMC750_INT_HAWK_WDT */ + 1, /* PRPMC750_INT_UNUSED */ + 1, /* PRPMC750_INT_ABORT */ + 1, /* PRPMC750_INT_HOSTINT1 */ + 1, /* PRPMC750_INT_HOSTINT2 */ + 1, /* PRPMC750_INT_HOSTINT3 */ + 1, /* PRPMC750_INT_PMC_INTA */ + 1, /* PRPMC750_INT_PMC_INTB */ + 1, /* PRPMC750_INT_PMC_INTC */ + 1, /* PRPMC750_INT_PMC_INTD */ + 1, /* PRPMC750_INT_UNUSED */ + 1, /* PRPMC750_INT_UNUSED */ + 1, /* PRPMC750_INT_UNUSED */ +}; + +int +prpmc750_get_cpuinfo(char *buffer) +{ + int len; + + len = sprintf(buffer,"machine\t\t: PrPMC750\n"); + + return len; +} + +void __init +prpmc750_setup_arch(void) +{ + extern char cmd_line[]; + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 100000000/HZ; + + /* Lookup PCI host bridges */ + prpmc750_find_bridges(); + +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */ +#endif + + /* Find and map our OpenPIC */ + pplus_mpic_init(PRPMC750_PCI_MEM_OFFSET); + OpenPIC_InitSenses = prpmc750_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(prpmc750_openpic_initsenses); + + printk("PrPMC750 port (C) 2001 MontaVista Software, Inc. \n"); + + return; +} + +/* + * Compute the PrPMC750's bus speed using the baud clock as a + * reference. + */ +unsigned long __init prpmc750_get_bus_speed(void) +{ + unsigned long tbl_start, tbl_end; + unsigned long current_state, old_state, bus_speed; + unsigned char lcr, dll, dlm; + int baud_divisor, count; + + /* Read the UART's baud clock divisor */ + lcr = readb(PRPMC750_SERIAL_0_LCR); + writeb(lcr | UART_LCR_DLAB, PRPMC750_SERIAL_0_LCR); + dll = readb(PRPMC750_SERIAL_0_DLL); + dlm = readb(PRPMC750_SERIAL_0_DLM); + writeb(lcr & ~UART_LCR_DLAB, PRPMC750_SERIAL_0_LCR); + baud_divisor = (dlm << 8) | dll; + + /* + * Use the baud clock divisor and base baud clock + * to determine the baud rate and use that as + * the number of baud clock edges we use for + * the time base sample. Make it half the baud + * rate. + */ + count = PRPMC750_BASE_BAUD / (baud_divisor * 16); + + /* Find the first edge of the baud clock */ + old_state = readb(PRPMC750_STATUS_REG) & PRPMC750_BAUDOUT_MASK; + do { + current_state = readb(PRPMC750_STATUS_REG) & + PRPMC750_BAUDOUT_MASK; + } while(old_state == current_state); + + old_state = current_state; + + /* Get the starting time base value */ + tbl_start = get_tbl(); + + /* + * Loop until we have found a number of edges equal + * to half the count (half the baud rate) + */ + do { + do { + current_state = readb(PRPMC750_STATUS_REG) & + PRPMC750_BAUDOUT_MASK; + } while(old_state == current_state); + old_state = current_state; + } while (--count); + + /* Get the ending time base value */ + tbl_end = get_tbl(); + + /* Compute bus speed */ + bus_speed = (tbl_end-tbl_start)*128; + + return bus_speed; +} + +void __init prpmc750_calibrate_decr(void) +{ + unsigned long freq; + int divisor = 4; + + freq = prpmc750_get_bus_speed(); + + tb_ticks_per_jiffy = freq / (HZ * divisor); + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +} + +void +prpmc750_restart(char *cmd) +{ + __cli(); + writeb(PRPMC750_MODRST_MASK, PRPMC750_MODRST_REG); + while(1); +} + +void +prpmc750_halt(void) +{ + __cli(); + while (1); +} + +void +prpmc750_power_off(void) +{ + prpmc750_halt(); +} + +/* Resolves the open_pic.c build without including i8259.c */ +int i8259_irq(int cpu) +{ + return 0; +} + +void __init +prpmc750_init_IRQ(void) +{ + openpic_init(1, 0, 0, -1); +} + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space. + */ +static __inline__ void +prpmc750_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) + { + __asm__ __volatile__( + " lis %0,0xf000\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x1ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + :: "r" (bat3u), "r" (bat3l)); + + mapping_set = 1; + } + return; +} + +/* + * We need to read the Falcon/Hawk memory controller + * to properly determine this value + */ +unsigned long __init +prpmc750_find_end_of_memory(void) +{ + /* Cover the Hawk registers with a BAT */ + prpmc750_set_bat(); + + /* Read the memory size from the Hawk SMC */ + return pplus_get_mem_size(PRPMC750_HAWK_SMC_BASE); +} + +void __init +prpmc750_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ + /* Copy cmd_line parameters */ + if ( r6) + { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } + + isa_io_base = PRPMC750_ISA_IO_BASE; + isa_mem_base = PRPMC750_ISA_MEM_BASE; + pci_dram_offset = PRPMC750_SYS_MEM_BASE; + + ppc_md.setup_arch = prpmc750_setup_arch; + ppc_md.get_cpuinfo = prpmc750_get_cpuinfo; + ppc_md.init_IRQ = prpmc750_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + + ppc_md.find_end_of_memory = prpmc750_find_end_of_memory; + + ppc_md.restart = prpmc750_restart; + ppc_md.power_off = prpmc750_power_off; + ppc_md.halt = prpmc750_halt; + + /* PrPMC750 has no timekeeper part */ + ppc_md.time_init = NULL; + ppc_md.get_rtc_time = NULL; + ppc_md.set_rtc_time = NULL; + ppc_md.calibrate_decr = prpmc750_calibrate_decr; diff -Nru a/arch/ppc/kernel/ptrace.c b/arch/ppc/kernel/ptrace.c --- a/arch/ppc/kernel/ptrace.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/kernel/ptrace.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ptrace.c 1.5 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/ptrace.c @@ -28,12 +28,16 @@ #include #include #include +#include #include #include #include #include +int ppc_access_process_vm(struct task_struct *tsk, unsigned long addr, + void *buf, int len, int write); + /* * Set of msr bits that gdb can change on behalf of a process. */ @@ -159,7 +163,7 @@ unsigned long tmp; int copied; - copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); + copied = ppc_access_process_vm(child, addr, &tmp, sizeof(tmp), 0); ret = -EIO; if (copied != sizeof(tmp)) break; @@ -193,7 +197,7 @@ case PTRACE_POKETEXT: /* write the word at location addr. */ case PTRACE_POKEDATA: ret = 0; - if (access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) + if (ppc_access_process_vm(child, addr, &data, sizeof(data), 1) == sizeof(data)) break; ret = -EIO; break; @@ -315,4 +319,153 @@ send_sig(current->exit_code, current, 1); current->exit_code = 0; } +} + + +/* + * These functions are stolen from kernel/ptrace.c. The reason that + * we can't use the version that is there is that it uses + * flush_icache_page after a write. Now flush_icache_page has become + * a no-op - it's called in do_no_page after getting a page from the + * page cache, and we now defer the flush until it's needed, and only + * do it once. + * + * The version below uses flush_icache_range instead of flush_icache_page + * in access_one_page. That's the only difference. + */ +/* + * Access another process' address space, one page at a time. + */ +static int access_one_page(struct mm_struct * mm, struct vm_area_struct * vma, unsigned long addr, void *buf, int len, int write) +{ + pgd_t * pgdir; + pmd_t * pgmiddle; + pte_t * pgtable; + char *maddr; + struct page *page; + +repeat: + spin_lock(&mm->page_table_lock); + pgdir = pgd_offset(vma->vm_mm, addr); + if (pgd_none(*pgdir)) + goto fault_in_page; + if (pgd_bad(*pgdir)) + goto bad_pgd; + pgmiddle = pmd_offset(pgdir, addr); + if (pmd_none(*pgmiddle)) + goto fault_in_page; + if (pmd_bad(*pgmiddle)) + goto bad_pmd; + pgtable = pte_offset(pgmiddle, addr); + if (!pte_present(*pgtable)) + goto fault_in_page; + if (write && (!pte_write(*pgtable) || !pte_dirty(*pgtable))) + goto fault_in_page; + page = pte_page(*pgtable); + + /* ZERO_PAGE is special: reads from it are ok even though it's marked reserved */ + if (page != ZERO_PAGE(addr) || write) { + if ((!VALID_PAGE(page)) || PageReserved(page)) { + spin_unlock(&mm->page_table_lock); + return 0; + } + } + get_page(page); + spin_unlock(&mm->page_table_lock); + flush_cache_page(vma, addr); + + if (write) { + maddr = kmap(page) + (addr & ~PAGE_MASK); + memcpy(maddr, buf, len); + flush_page_to_ram(page); + flush_icache_range((unsigned long) maddr, + (unsigned long) maddr + len); + kunmap(page); + } else { + maddr = kmap(page); + memcpy(buf, maddr + (addr & ~PAGE_MASK), len); + flush_page_to_ram(page); + kunmap(page); + } + put_page(page); + return len; + +fault_in_page: + spin_unlock(&mm->page_table_lock); + /* -1: out of memory. 0 - unmapped page */ + if (handle_mm_fault(mm, vma, addr, write) > 0) + goto repeat; + return 0; + +bad_pgd: + spin_unlock(&mm->page_table_lock); + pgd_ERROR(*pgdir); + return 0; + +bad_pmd: + spin_unlock(&mm->page_table_lock); + pmd_ERROR(*pgmiddle); + return 0; +} + +static int access_mm(struct mm_struct *mm, struct vm_area_struct * vma, unsigned long addr, void *buf, int len, int write) +{ + int copied = 0; + + for (;;) { + unsigned long offset = addr & ~PAGE_MASK; + int this_len = PAGE_SIZE - offset; + int retval; + + if (this_len > len) + this_len = len; + retval = access_one_page(mm, vma, addr, buf, this_len, write); + copied += retval; + if (retval != this_len) + break; + + len -= retval; + if (!len) + break; + + addr += retval; + buf += retval; + + if (addr < vma->vm_end) + continue; + if (!vma->vm_next) + break; + if (vma->vm_next->vm_start != vma->vm_end) + break; + + vma = vma->vm_next; + } + return copied; +} + +int ppc_access_process_vm(struct task_struct *tsk, unsigned long addr, + void *buf, int len, int write) +{ + int copied; + struct mm_struct *mm; + struct vm_area_struct * vma; + + /* Worry about races with exit() */ + task_lock(tsk); + mm = tsk->mm; + if (mm) + atomic_inc(&mm->mm_users); + task_unlock(tsk); + if (!mm) + return 0; + + down_read(&mm->mmap_sem); + vma = find_extend_vma(mm, addr); + copied = 0; + if (vma) + copied = access_mm(mm, vma, addr, buf, len, write); + + up_read(&mm->mmap_sem); + mmput(mm); + return copied; } diff -Nru a/arch/ppc/kernel/qspan_pci.c b/arch/ppc/kernel/qspan_pci.c --- a/arch/ppc/kernel/qspan_pci.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/kernel/qspan_pci.c Sat Jun 16 06:00:24 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.qspan_pci.c 1.5 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * QSpan pci routines. diff -Nru a/arch/ppc/kernel/residual.c b/arch/ppc/kernel/residual.c --- a/arch/ppc/kernel/residual.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/kernel/residual.c Sat Jun 16 06:00:24 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.residual.c 1.7 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Code to deal with the PReP residual data. diff -Nru a/arch/ppc/kernel/sandpoint.h b/arch/ppc/kernel/sandpoint.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/sandpoint.h Sat Jun 16 06:00:31 2001 @@ -0,0 +1,33 @@ +/* + * arch/ppc/kernel/sandpoint.h + * + * Definitions for Motorola SPS Sandpoint Test Platform + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * Sandpoint uses the CHRP map (Map B). + */ + +#ifndef __PPC_KERNEL_SANDPOINT_H +#define __PPC_KERNEL_SANDPOINT_H + +/* + * Define the PCI slot that the 8259 is sharing interrupts with. + * Valid values are 1 (PCI slot 2) and 2 (PCI slot 3). + */ +#define SANDPOINT_SIO_SLOT 1 +#define SANDPOINT_SIO_IRQ (SANDPOINT_SIO_SLOT + NUM_8259_INTERRUPTS) + +void sandpoint_find_bridges(void); + +#endif /* __PPC_KERNEL_SANDPOINT_H */ diff -Nru a/arch/ppc/kernel/sandpoint_pci.c b/arch/ppc/kernel/sandpoint_pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/sandpoint_pci.c Sat Jun 16 06:00:32 2001 @@ -0,0 +1,159 @@ +/* + * arch/ppc/kernel/sandpoint_pci.c + * + * PCI setup routines for the Motorola SPS Sandpoint Test Platform + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "pci.h" +#include "pci_auto.h" +#include "mpc10x.h" +#include "sandpoint.h" + +/* + * Motorola SPS Sandpoint interrupt routing. + */ +static inline int +sandpoint_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { SANDPOINT_SIO_IRQ, + 0, 0, 0 }, /* IDSEL 11 - i8259 on Winbond */ + { 0, 0, 0, 0 }, /* IDSEL 12 - unused */ + { 16, 19, 18, 17 }, /* IDSEL 13 - PCI slot 1 */ + { 17, 16, 19, 18 }, /* IDSEL 14 - PCI slot 2 */ + { 18, 17, 16, 19 }, /* IDSEL 15 - PCI slot 3 */ + { 19, 18, 17, 16 }, /* IDSEL 16 - PCI slot 4 */ + }; + + const long min_idsel = 11, max_idsel = 16, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +static void __init +sandpoint_setup_winbond_83553(struct pci_controller *hose) +{ + int devfn; + + /* + * Route IDE interrupts directly to the 8259's IRQ 14 & 15. + * We can't route the IDE interrupt to PCI INTC# or INTD# because those + * woule interfere with the PMC's INTC# and INTD# lines. + */ + /* + * Winbond Fcn 0 + */ + devfn = PCI_DEVFN(11,0); + + early_write_config_byte(hose, + 0, + devfn, + 0x43, /* IDE Interrupt Routing Control */ + 0xef); + early_write_config_word(hose, + 0, + devfn, + 0x44, /* PCI Interrupt Routing Control */ + 0x0000); + + /* Want ISA memory cycles to be forwarded to PCI bus */ + early_write_config_byte(hose, + 0, + devfn, + 0x48, /* ISA-to-PCI Addr Decoder Control */ + 0xf0); + + /* Enable RTC and Keyboard address locations. */ + early_write_config_byte(hose, + 0, + devfn, + 0x4d, /* Chip Select Control Register */ + 0x00); + + /* Enable Port 92. */ + early_write_config_byte(hose, + 0, + devfn, + 0x4e, /* AT System Control Register */ + 0x06); + /* + * Winbond Fcn 1 + */ + devfn = PCI_DEVFN(11,1); + + /* Put IDE controller into native mode. */ + early_write_config_byte(hose, + 0, + devfn, + 0x09, /* Programming interface Register */ + 0x8f); + + /* Init IRQ routing, enable both ports, disable fast 16 */ + early_write_config_dword(hose, + 0, + devfn, + 0x40, /* IDE Control/Status Register */ + 0x00ff0011); + return; +} + +void __init +sandpoint_find_bridges(void) +{ + struct pci_controller *hose; + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + if (mpc10x_bridge_init(hose, + MPC10X_MEM_MAP_B, + MPC10X_MEM_MAP_B, + MPC10X_MAPB_EUMB_BASE) == 0) { + + /* Do early winbond init, then scan PCI bus */ + sandpoint_setup_winbond_83553(hose); + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = NULL; + ppc_md.pcibios_fixup_bus = NULL; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = sandpoint_map_irq; + } + else { + if (ppc_md.progress) + ppc_md.progress("Bridge init failed", 0x100); + printk("Host bridge init failed\n"); + } + + return; +} diff -Nru a/arch/ppc/kernel/sandpoint_setup.c b/arch/ppc/kernel/sandpoint_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/sandpoint_setup.c Sat Jun 16 06:00:32 2001 @@ -0,0 +1,694 @@ +/* + * arch/ppc/kernel/sandpoint_setup.c + * + * Board setup routines for the Motorola SPS Sandpoint Test Platform. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * This file adds support for the Motorola SPS Sandpoint Test Platform. + * These boards have a PPMC slot for the processor so any combination + * of cpu and host bridge can be attached. This port is for an 8240 PPMC + * module from Motorola SPS and other closely related cpu/host bridge + * combinations (e.g., 750/755/7400 with MPC107 host bridge). + * The sandpoint itself has a Windbond 83c553 (PCI-ISA bridge, 2 DMA ctlrs, 2 + * cascaded 8259 interrupt ctlrs, 8254 Timer/Counter, and an IDE ctlr), a + * National 87308 (RTC, 2 UARTs, Keyboard & mouse ctlrs, and a floppy ctlr), + * and 4 PCI slots (only 2 of which are usable; the other 2 are keyed for 3.3V + * but are really 5V). + * + * The firmware on the sandpoint is called DINK (not my acronym :). This port + * depends on DINK to do some basic initialization (e.g., initialize the memory + * ctlr) and to ensure that the processor is using MAP B (CHRP map). + * + * The switch settings for the Sandpoint board MUST be as follows: + * S3: down + * S4: up + * S5: up + * S6: down + * + * *** IMPORTANT *** + * + * This port will not work properly as is. You must apply the following patch: + * ftp://ftp.mvista.com/pub/Area51/sandpoint/sp_patch_2_5 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pci.h" +#include "local_irq.h" +#include "open_pic.h" +#include "i8259.h" +#include "todc.h" +#include "mpc10x.h" +#include "sandpoint.h" + +#error "Apply patch: ftp://ftp.mvista.com/pub/Area51/sandpoint/sp_patch_2_5" + +extern u_int openpic_irq(void); +extern void openpic_eoi(void); + +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 unsigned char pckbd_sysrq_xlate[128]; + +static void sandpoint_halt(void); + + +/* + * *** IMPORTANT *** + * + * The first 16 entries of 'sandpoint_openpic_initsenses[]' are there and + * initialized to 0 on purpose. DO NOT REMOVE THEM as the 'offset' parameter + * of 'openpic_init()' does not work for the sandpoint because the 8259 + * interrupt is NOT routed to the EPIC's IRQ 0 AND the EPIC's IRQ 0's offset is + * the same as a normal openpic's IRQ 16 offset. + */ +static u_char sandpoint_openpic_initsenses[] __initdata = { + 0, /* 0-15 not used by EPCI but by 8259 (std PC-type IRQs) */ + 0, /* 1 */ + 0, /* 2 */ + 0, /* 3 */ + 0, /* 4 */ + 0, /* 5 */ + 0, /* 6 */ + 0, /* 7 */ + 0, /* 8 */ + 0, /* 9 */ + 0, /* 10 */ + 0, /* 11 */ + 0, /* 12 */ + 0, /* 13 */ + 0, /* 14 */ + 0, /* 15 */ + 1, /* 16: EPIC IRQ 0: Active Low -- PCI intrs */ + 1, /* 17: EPIC IRQ 1: Active Low -- PCI (possibly 8259) intrs */ + 1, /* 18: EPIC IRQ 2: Active Low -- PCI (possibly 8259) intrs */ + 1 /* 19: EPIC IRQ 3: Active Low -- PCI intrs */ + /* 20: EPIC IRQ 4: Not used */ +}; + + +extern char cmd_line[]; + +static void __init +sandpoint_setup_arch(void) +{ + extern char cmd_line[]; + + + loops_per_jiffy = 100000000 / HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + else +#endif +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0301); /* /dev/hda1 IDE disk */ +#endif + + /* Lookup PCI host bridges */ + sandpoint_find_bridges(); + + printk("Boot arguments: %s\n", cmd_line); + printk("Motorola SPS Sandpoint Test Platform\n"); + printk("Sandpoint port (C) 2000, 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + +#ifdef CONFIG_VGA_CONSOLE + conswitchp = &vga_con; +#elif defined(CONIFG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif + + return; +} + +#define SANDPOINT_87308_CFG_ADDR 0x15c +#define SANDPOINT_87308_CFG_DATA 0x15d + +#define SANDPOINT_87308_CFG_INB(addr, byte) { \ + outb((addr), SANDPOINT_87308_CFG_ADDR); \ + (byte) = inb(SANDPOINT_87308_CFG_DATA); \ +} + +#define SANDPOINT_87308_CFG_OUTB(addr, byte) { \ + outb((addr), SANDPOINT_87308_CFG_ADDR); \ + outb((byte), SANDPOINT_87308_CFG_DATA); \ +} +#define SANDPOINT_87308_DEV_ENABLE(dev_num) { \ + SANDPOINT_87308_CFG_OUTB(0x07, (dev_num)); \ + SANDPOINT_87308_CFG_OUTB(0x30, 0x01); \ +} + +/* + * Initialize the ISA devices on the Nat'l PC87308VUL SuperIO chip. + */ +static void __init +sandpoint_setup_natl_87308(void) +{ + u_char reg; + + /* + * Enable all the devices on the Super I/O chip. + */ + SANDPOINT_87308_DEV_ENABLE(0x00); /* Enable keyboard */ + SANDPOINT_87308_DEV_ENABLE(0x01); /* Enable mouse */ + SANDPOINT_87308_DEV_ENABLE(0x02); /* Enable rtc */ + SANDPOINT_87308_DEV_ENABLE(0x03); /* Enable fdc (floppy) */ + SANDPOINT_87308_DEV_ENABLE(0x04); /* Enable parallel */ + SANDPOINT_87308_DEV_ENABLE(0x05); /* Enable UART 2 */ + SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */ + SANDPOINT_87308_DEV_ENABLE(0x06); /* Enable UART 1 */ + SANDPOINT_87308_CFG_OUTB(0xf0, 0x82); /* Enable bank select regs */ + + /* Set up floppy in PS/2 mode */ + outb(0x09, SIO_CONFIG_RA); + reg = inb(SIO_CONFIG_RD); + reg = (reg & 0x3F) | 0x40; + outb(reg, SIO_CONFIG_RD); + outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */ + + return; +} + +/* + * Fix IDE interrupts. + */ +static void __init +sandpoint_fix_winbond_83553(void) +{ + /* Make all 8259 interrupt level sensitive */ + outb(0xf8, 0x4d0); + outb(0xde, 0x4d1); + + return; +} + +static void __init +sandpoint_init2(void) +{ + /* Do Sandpoint board specific initialization. */ + sandpoint_fix_winbond_83553(); + sandpoint_setup_natl_87308(); + + request_region(0x00,0x20,"dma1"); + request_region(0x20,0x20,"pic1"); + request_region(0x40,0x20,"timer"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xa0,0x20,"pic2"); + request_region(0xc0,0x20,"dma2"); + + return; +} + +/* + * Interrupt setup and service. Interrrupts on the Sandpoint come + * from the four PCI slots plus the 8259 in the Winbond Super I/O (SIO). + * These interrupts are sent to one of four IRQs on the EPIC. + * The SIO shares its interrupt with either slot 2 or slot 3 (INTA#). + * Slot numbering is confusing. Sometimes in the documentation they + * use 0,1,2,3 and others 1,2,3,4. We will use slots 1,2,3,4 and + * map this to IRQ 16, 17, 18, 19. + */ +static void __init +sandpoint_init_IRQ(void) +{ + int i; + + /* + * 3 things cause us to jump through some hoops: + * 1) the EPIC on the 8240 & 107 are not full-blown openpic pic's + * 2) the 8259 is NOT cascaded on the openpic IRQ 0 + * 3) the 8259 shares its interrupt line with some PCI interrupts. + * + * What we'll do is set up the 8259 to be level sensitive, active low + * just like a PCI device. Then, when an interrupt on the IRQ that is + * shared with the 8259 comes in, we'll take a peek at the 8259 to see + * it its generating an interrupt. If it is, we'll handle the 8259 + * interrupt. Otherwise, we'll handle it just like a normal PCI + * interrupt. This does give the 8259 interrupts a higher priority + * than the EPIC ones--hopefully, not a problem. + */ + OpenPIC_InitSenses = sandpoint_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(sandpoint_openpic_initsenses); + + openpic_init(1, 0, NULL, -1); + + /* + * openpic_init() has set up irq_desc[0-23] to be openpic + * interrupts. We need to set irq_desc[0-15] to be 8259 interrupts. + * We then need to request and enable the 8259 irq. + */ + for(i=0; i < NUM_8259_INTERRUPTS; i++) + irq_desc[i].handler = &i8259_pic; + + if (request_irq(SANDPOINT_SIO_IRQ, no_action, SA_INTERRUPT, + "8259 cascade to EPIC", NULL)) { + + printk("Unable to get OpenPIC IRQ %d for cascade\n", + SANDPOINT_SIO_IRQ); + } + + i8259_init(); +} + +static int +sandpoint_get_irq(struct pt_regs *regs) +{ + int irq, cascade_irq; + + irq = openpic_irq(); + + if (irq == SANDPOINT_SIO_IRQ) { + cascade_irq = i8259_irq(smp_processor_id()); + + if (cascade_irq != -1) { + irq = cascade_irq; + openpic_eoi(); + } + } + else if (irq == OPENPIC_VEC_SPURIOUS) { + irq = -1; + } + + return irq; +} + +static void +sandpoint_post_irq(struct pt_regs* regs, int irq) +{ + if (irq >= NUM_8259_INTERRUPTS) { + openpic_eoi(); /* Issue EOI to EPIC */ + } + + return; +} + +static u32 +sandpoint_irq_cannonicalize(u32 irq) +{ + if (irq == 2) + { + return 9; + } + else + { + return irq; + } +} + +static ulong __init +sandpoint_find_end_of_memory(void) +{ + ulong size = 0; + +#if 0 /* Leave out until DINK sets mem ctlr correctly */ + size = mpc10x_get_mem_size(MPC10X_MEM_MAP_B); +#else + size = 32*1024*1024; +#endif + + return size; +} + +/* + * Due to Sandpoint X2 errata, the Port 92 will not work. + */ +static void +sandpoint_restart(char *cmd) +{ + __cli(); + + /* Set exception prefix high - to the firmware */ + _nmask_and_or_msr(0, MSR_IP); + + /* Reset system via Port 92 */ + outb(0x00, 0x92); + outb(0x01, 0x92); + for(;;); /* Spin until reset happens */ +} + +static void +sandpoint_power_off(void) +{ + __cli(); + for(;;); /* No way to shut power off with software */ + /* NOTREACHED */ +} + +static void +sandpoint_halt(void) +{ + sandpoint_power_off(); + /* NOTREACHED */ +} + +static int +sandpoint_get_cpuinfo(char *buffer) +{ + int len; + uint pvid; + + pvid = _get_PVR(); + + len = sprintf( buffer, "vendor\t\t: Motorola SPS\n"); + + len += sprintf( buffer+len, "machine\t\t: Sandpoint\n"); + + len += sprintf( buffer+len, "processor\t: "); + len += sprintf( buffer+len, "PVID: 0x%x, vendor: %s\n", + pvid, (pvid & (1<<15) ? "IBM" : "Motorola")); + + return len; +} + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) +/* + * IDE support. + */ +static int sandpoint_ide_ports_known = 0; +static ide_ioreg_t sandpoint_ide_regbase[MAX_HWIFS]; +static ide_ioreg_t sandpoint_ide_ctl_regbase[MAX_HWIFS]; +static ide_ioreg_t sandpoint_idedma_regbase; + +static void +sandpoint_ide_probe(void) +{ + struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND, + PCI_DEVICE_ID_WINBOND_82C105, + NULL); + + if(pdev) { + sandpoint_ide_regbase[0]=pdev->resource[0].start; + sandpoint_ide_regbase[1]=pdev->resource[2].start; + sandpoint_ide_ctl_regbase[0]=pdev->resource[1].start; + sandpoint_ide_ctl_regbase[1]=pdev->resource[3].start; + sandpoint_idedma_regbase=pdev->resource[4].start; + } + + sandpoint_ide_ports_known = 1; + return; +} + +static void +sandpoint_ide_insw(ide_ioreg_t port, void *buf, int ns) +{ + ide_insw(port+_IO_BASE, buf, ns); + return; +} + +static void +sandpoint_ide_outsw(ide_ioreg_t port, void *buf, int ns) +{ + ide_outsw(port+_IO_BASE, buf, ns); + return; +} + +static int +sandpoint_ide_default_irq(ide_ioreg_t base) +{ + if (sandpoint_ide_ports_known == 0) + sandpoint_ide_probe(); + + if (base == sandpoint_ide_regbase[0]) + return 14; + else if (base == sandpoint_ide_regbase[1]) + return 15; + else + return 0; +} + +static ide_ioreg_t +sandpoint_ide_default_io_base(int index) +{ + if (sandpoint_ide_ports_known == 0) + sandpoint_ide_probe(); + + return sandpoint_ide_regbase[index]; +} + +static int +sandpoint_ide_check_region(ide_ioreg_t from, unsigned int extent) +{ + return check_region(from, extent); +} + +static void +sandpoint_ide_request_region(ide_ioreg_t from, + unsigned int extent, + const char *name) +{ + request_region(from, extent, name); + return; +} + +static void +sandpoint_ide_release_region(ide_ioreg_t from, + unsigned int extent) +{ + release_region(from, extent); + return; +} + +static void +sandpoint_ide_fix_driveid(struct hd_driveid *id) +{ + ppc_generic_ide_fix_driveid(id); + return; +} + +static void __init +sandpoint_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, + ide_ioreg_t ctrl_port, int *irq) +{ + ide_ioreg_t reg = data_port; + uint alt_status_base; + int i; + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw->io_ports[i] = reg++; + } + + if (data_port == sandpoint_ide_regbase[0]) { + alt_status_base = sandpoint_ide_ctl_regbase[0] + 2; + hw->irq = 14; + } + else if (data_port == sandpoint_ide_regbase[1]) { + alt_status_base = sandpoint_ide_ctl_regbase[1] + 2; + hw->irq = 15; + } + else { + alt_status_base = 0; + hw->irq = 0; + } + + if (ctrl_port) { + hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port; + } else { + hw->io_ports[IDE_CONTROL_OFFSET] = alt_status_base; + } + + if (irq != NULL) { + *irq = hw->irq; + } + + return; +} +#endif + +/* + * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1. + */ +static __inline__ void +sandpoint_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) { + + __asm__ __volatile__( + " lis %0,0xf800\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x0ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + :: "r" (bat3u), "r" (bat3l)); + + mapping_set = 1; + } + + return; +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG +#include +#include +#include + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in */ +}; + +void +sandpoint_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned long com_port; + u16 shift; + + com_port = rs_table[0].port; + shift = rs_table[0].iomem_reg_shift; + + while ((c = *s++) != 0) { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = c; + + if (c == '\n') { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + } + } +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +__init void sandpoint_setup_pci_ptrs(void); + +void __init +sandpoint_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ +#ifdef CONFIG_BLK_DEV_INITRD + if ( r4 ) + { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif + + /* take care of cmd line */ + if ( r6 && (((char *) r6) != '\0')) { + *(char *)(r7 + KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6 + KERNELBASE)); + } + + /* Map in board regs, etc. */ + sandpoint_set_bat(); + + todc_info = &mc146818_info; + + isa_io_base = MPC10X_MAPB_ISA_IO_BASE; + isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE; + pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET; + ISA_DMA_THRESHOLD = 0x00ffffff; + DMA_MODE_READ = 0x44; + DMA_MODE_WRITE = 0x48; + + ppc_md.setup_arch = sandpoint_setup_arch; + ppc_md.setup_residual = NULL; + ppc_md.get_cpuinfo = sandpoint_get_cpuinfo; + ppc_md.irq_cannonicalize = sandpoint_irq_cannonicalize; + ppc_md.init_IRQ = sandpoint_init_IRQ; + ppc_md.get_irq = sandpoint_get_irq; + ppc_md.post_irq = sandpoint_post_irq; + ppc_md.init = sandpoint_init2; + + ppc_md.restart = sandpoint_restart; + ppc_md.power_off = sandpoint_power_off; + ppc_md.halt = sandpoint_halt; + + ppc_md.find_end_of_memory = sandpoint_find_end_of_memory; + + ppc_md.time_init = todc_time_init; + ppc_md.set_rtc_time = todc_set_rtc_time; + ppc_md.get_rtc_time = todc_get_rtc_time; + ppc_md.calibrate_decr = todc_calibrate_decr; + + ppc_md.heartbeat = NULL; + ppc_md.heartbeat_reset = 0; + ppc_md.heartbeat_count = 0; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = sandpoint_progress; +#else /* !CONFIG_SERIAL_TEXT_DEBUG */ + ppc_md.progress = NULL; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + + ppc_md.nvram_read_val = todc_mc146818_read_val; + ppc_md.nvram_write_val = todc_mc146818_write_val; + +#ifdef CONFIG_VT + ppc_md.kbd_setkeycode = pckbd_setkeycode; + ppc_md.kbd_getkeycode = pckbd_getkeycode; + ppc_md.kbd_translate = pckbd_translate; + ppc_md.kbd_unexpected_up = pckbd_unexpected_up; + ppc_md.kbd_leds = pckbd_leds; + ppc_md.kbd_init_hw = pckbd_init_hw; +#ifdef CONFIG_MAGIC_SYSRQ + ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; + SYSRQ_KEY = 0x54; +#endif +#endif + +#if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) + ppc_ide_md.insw = sandpoint_ide_insw; + ppc_ide_md.outsw = sandpoint_ide_outsw; + ppc_ide_md.default_irq = sandpoint_ide_default_irq; + ppc_ide_md.default_io_base = sandpoint_ide_default_io_base; + ppc_ide_md.ide_check_region = sandpoint_ide_check_region; + ppc_ide_md.ide_request_region = sandpoint_ide_request_region; + ppc_ide_md.ide_release_region = sandpoint_ide_release_region; + ppc_ide_md.fix_driveid = sandpoint_ide_fix_driveid; + ppc_ide_md.ide_init_hwif = sandpoint_ide_init_hwif_ports; +#endif + ppc_ide_md.io_base = _IO_BASE; + + return; +} diff -Nru a/arch/ppc/kernel/semaphore.c b/arch/ppc/kernel/semaphore.c --- a/arch/ppc/kernel/semaphore.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/kernel/semaphore.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.semaphore.c 1.12 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * PowerPC-specific semaphore code. diff -Nru a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c --- a/arch/ppc/kernel/setup.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/kernel/setup.c Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.setup.c 1.32 05/23/01 00:38:42 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Common prep/pmac/chrp boot and setup code. @@ -28,6 +28,7 @@ #include #include #include +#include #ifdef CONFIG_8xx #include #include @@ -36,16 +37,16 @@ #include #include #endif +#ifdef CONFIG_4xx +#include +#endif #include #include #include #include -#ifdef CONFIG_OAK -#include "oak_setup.h" -#endif /* CONFIG_OAK */ -extern void pmac_init(unsigned long r3, +extern void apus_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, @@ -57,30 +58,89 @@ unsigned long r6, unsigned long r7); -extern void prep_init(unsigned long r3, +extern void gemini_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7); +extern void k2_init(unsigned long r3, + unsigned long r4, + unsigned long r5, + unsigned long r6, + unsigned long r7); + +extern void menf1_init(unsigned long r3, + unsigned long r4, + unsigned long r5, + unsigned long r6, + unsigned long r7); + +extern void mcpn765_init(unsigned long r3, + unsigned long r4, + unsigned long r5, + unsigned long r6, + unsigned long r7); + +extern void mvme5100_init(unsigned long r3, + unsigned long r4, + unsigned long r5, + unsigned long r6, + unsigned long r7); + extern void m8xx_init(unsigned long r3, - unsigned long r4, - unsigned long r5, - unsigned long r6, - unsigned long r7); + unsigned long r4, + unsigned long r5, + unsigned long r6, + unsigned long r7); + +extern void m8260_init(unsigned long r3, + unsigned long r4, + unsigned long r5, + unsigned long r6, + unsigned long r7); + +extern void pcore_init(unsigned long r3, + unsigned long r4, + unsigned long r5, + unsigned long r6, + unsigned long r7); -extern void apus_init(unsigned long r3, +extern void pmac_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7); -extern void gemini_init(unsigned long r3, +extern void prep_init(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7); +extern void prpmc750_init(unsigned long r3, + unsigned long r4, + unsigned long r5, + unsigned long r6, + unsigned long r7); + +extern void sandpoint_init(unsigned long r3, + unsigned long r4, + unsigned long r5, + unsigned long r6, + unsigned long r7); + +extern void spruce_init(unsigned long r3, + unsigned long r4, + unsigned long r5, + unsigned long r6, + unsigned long r7); + +extern void zx4500_init(unsigned long r3, + unsigned long r4, + unsigned long r5, + unsigned long r6, + unsigned long r7); extern void bootx_init(unsigned long r4, unsigned long phys); extern unsigned long reloc_offset(void); @@ -100,7 +160,6 @@ #ifdef CONFIG_ALL_PPC int _machine = 0; -int have_of = 0; #endif /* CONFIG_ALL_PPC */ #ifdef CONFIG_MAGIC_SYSRQ @@ -185,35 +244,15 @@ { ppc_md.halt(); } - + +#ifdef CONFIG_TAU +extern u32 cpu_temp_both(unsigned long cpu); +#else /* !CONFIG_TAU */ unsigned long cpu_temp(void) { - unsigned char thres = 0; - -#if 0 - /* disable thrm2 */ - _set_THRM2( 0 ); - /* threshold 0 C, tid: exceeding threshold, tie: don't generate interrupt */ - _set_THRM1( THRM1_V ); - - /* we need 20us to do the compare - assume 300MHz processor clock */ - _set_THRM3(0); - _set_THRM3(THRM3_E | (300*30)<<18 ); - - udelay(100); - /* wait for the compare to complete */ - /*while ( !(_get_THRM1() & THRM1_TIV) ) ;*/ - if ( !(_get_THRM1() & THRM1_TIV) ) - printk("no tiv\n"); - if ( _get_THRM1() & THRM1_TIN ) - printk("crossed\n"); - /* turn everything off */ - _set_THRM3(0); - _set_THRM1(0); -#endif - - return thres; + return 0; } +#endif /* CONFIG_TAU */ int get_cpuinfo(char *buffer) { @@ -222,6 +261,9 @@ unsigned long i; unsigned int pvr; unsigned short maj, min; +#ifdef CONFIG_TAU + unsigned int temp = 0; +#endif #ifdef CONFIG_SMP #define CPU_PRESENT(x) (cpu_callin_map[(x)]) @@ -244,95 +286,26 @@ len += sprintf(len+buffer,"cpu\t\t: "); pvr = GET_PVR; - - switch (PVR_VER(pvr)) - { - case 0x0001: - len += sprintf(len+buffer, "601\n"); - break; - case 0x0003: - len += sprintf(len+buffer, "603\n"); - break; - case 0x0004: - len += sprintf(len+buffer, "604\n"); - break; - case 0x0006: - len += sprintf(len+buffer, "603e\n"); - break; - case 0x0007: - len += sprintf(len+buffer, "603"); - if (((pvr >> 12) & 0xF) == 1) { - pvr ^= 0x00001000; /* revision fix-up */ - len += sprintf(len+buffer, "r\n"); - } else { - len += sprintf(len+buffer, "ev\n"); - } - break; - case 0x0008: /* 740/750(P) */ - case 0x1008: - len += sprintf(len+buffer, "750%s\n", - PVR_VER(pvr) == 0x1008 ? "P" : ""); - len += sprintf(len+buffer, "temperature \t: %lu C\n", - cpu_temp()); - break; - case 0x0009: /* 604e/604r */ - case 0x000A: - len += sprintf(len+buffer, "604"); - - if (PVR_VER(pvr) == 0x000A || - ((pvr >> 12) & 0xF) != 0) { - pvr &= ~0x00003000; /* revision fix-up */ - len += sprintf(len+buffer, "r\n"); - } else { - len += sprintf(len+buffer, "e\n"); - } - break; - case 0x000C: - len += sprintf(len+buffer, "7400 (G4"); + + if (cur_cpu_spec[i]->pvr_mask) + len += sprintf(len+buffer, "%s", cur_cpu_spec[i]->cpu_name); + else + len += sprintf(len+buffer, "unknown (%08x)", pvr); #ifdef CONFIG_ALTIVEC + if (cur_cpu_spec[i]->cpu_features & CPU_FTR_ALTIVEC) len += sprintf(len+buffer, ", altivec supported"); -#endif /* CONFIG_ALTIVEC */ - len += sprintf(len+buffer, ")\n"); - break; - case 0x0020: - len += sprintf(len+buffer, "403G"); - switch ((pvr >> 8) & 0xFF) { - case 0x02: - len += sprintf(len+buffer, "C\n"); - break; - case 0x14: - len += sprintf(len+buffer, "CX\n"); - break; - } - break; - case 0x0035: - len += sprintf(len+buffer, "POWER4\n"); - break; - case 0x0040: - len += sprintf(len+buffer, "POWER3 (630)\n"); - break; - case 0x0041: - len += sprintf(len+buffer, "POWER3 (630+)\n"); - break; - case 0x0050: - len += sprintf(len+buffer, "8xx\n"); - break; - case 0x0081: - len += sprintf(len+buffer, "82xx\n"); - break; - case 0x4011: - len += sprintf(len+buffer, "405GP\n"); - break; - default: - len += sprintf(len+buffer, "unknown (%08x)\n", pvr); - break; +#endif + len += sprintf(len+buffer, "\n"); + if (cur_cpu_spec[i]->cpu_features & CPU_FTR_TAU) { + len += sprintf(len+buffer, "temperature \t: %lu C\n", + cpu_temp()); } - + /* * Assume here that all clock rates are the same in a * smp system. -- Cort */ -#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_8260) +#if defined(CONFIG_ALL_PPC) if ( have_of ) { struct device_node *cpu_node; @@ -356,7 +329,7 @@ len += sprintf(len+buffer, "clock\t\t: %dMHz\n", *fp / 1000000); } -#endif /* !CONFIG_4xx && !CONFIG_8xx */ +#endif /* CONFIG_ALL_PPC */ if (ppc_md.setup_residual != NULL) { @@ -379,11 +352,12 @@ break; } - len += sprintf(len+buffer, "revision\t: %hd.%hd\n", maj, min); + len += sprintf(len+buffer, "revision\t: %hd.%hd (pvr %04x %04x)\n", + maj, min, PVR_VER(pvr), PVR_REV(pvr)); len += sprintf(buffer+len, "bogomips\t: %lu.%02lu\n", - (CD(loops_per_jiffy)+2500)/(500000/HZ), - (CD(loops_per_jiffy)+2500)/(5000/HZ) % 100); + CD(loops_per_jiffy)/(500000/HZ), + CD(loops_per_jiffy)/(5000/HZ) % 100); bogosum += CD(loops_per_jiffy); } @@ -391,8 +365,8 @@ if ( i ) len += sprintf(buffer+len, "\n"); len += sprintf(buffer+len,"total bogomips\t: %lu.%02lu\n", - (bogosum+2500)/(500000/HZ), - (bogosum+2500)/(5000/HZ) % 100); + bogosum/500000, + bogosum/5000 % 100); #endif /* CONFIG_SMP */ /* @@ -441,11 +415,15 @@ } #endif /* CONFIG_ALL_PPC */ -#ifdef CONFIG_6xx +#if defined(CONFIG_6xx) || defined(CONFIG_PPC64BRIDGE) /* * We're called here very early in the boot. We determine the machine * type and call the appropriate low-level setup functions. * -- Cort + * + * Note that the kernel may be running at an address which is different + * from the address that it was linked at, so we must use RELOC/PTRRELOC + * to access static data (including strings). -- paulus */ __init unsigned long @@ -454,65 +432,36 @@ extern char __bss_start, _end; unsigned long phys; unsigned long offset = reloc_offset(); - unsigned long local_have_of = 1, local_machine; - struct bi_record *rec; - + /* Default */ phys = offset + KERNELBASE; - -#if defined(CONFIG_APUS) - return phys; -#endif - + /* First zero the BSS -- use memset, some arches don't have * caches on yet */ - memset_io(PTRRELOC(&__bss_start),0 , &_end - &__bss_start); + memset_io(PTRRELOC(&__bss_start), 0, &_end - &__bss_start); -#if defined(CONFIG_ALL_PPC) || defined(CONFIG_GEMINI) +#if defined(CONFIG_ALL_PPC) || defined(CONFIG_PPC64BRIDGE) /* If we came here from BootX, clear the screen, * set up some pointers and return. */ -#if defined(CONFIG_ALL_PPC) if ((r3 == 0x426f6f58) && (r5 == 0)) { bootx_init(r4, phys); return phys; } -#endif /* check if we're prep, return if we are */ if ( *(unsigned long *)(0) == 0xdeadc0de ) return phys; - - /* - * See if we have any bootloader info passed along. If we do, - * get the machine type and find out if we have OF. - * - * The strategy here is to assume that we want to call prom_init() - * unless the bootinfo data passed to us tell us that we don't - * have OF. - * -- Cort - */ - rec = (struct bi_record *)_ALIGN((ulong)PTRRELOC(&__bss_start)+(1<<20)-1,(1<<20)); - if ( rec->tag == BI_FIRST ) - { - for ( ; rec->tag != BI_LAST ; - rec = (struct bi_record *)((ulong)rec + rec->size) ) - { - ulong *data = rec->data; - if ( rec->tag == BI_MACHTYPE ) - { - local_machine = data[0]; - local_have_of = data[1]; - } - } - } - if ( local_have_of ) - phys = prom_init( r3, r4, (prom_entry)r5); + /* + * for now, don't use bootinfo because it breaks yaboot 0.5 + * and assume that if we didn't find a magic number, we have OF + */ + phys = prom_init( r3, r4, (prom_entry)r5); #endif - + return phys; } -#endif /* CONFIG_6xx */ +#endif /* CONFIG_6xx || CONFIG_PPC64BRIDGE */ /* * Find out what kind of machine we're on and save any data we need @@ -522,6 +471,10 @@ identify_machine(unsigned long r3, unsigned long r4, unsigned long r5, unsigned long r6, unsigned long r7) { +#ifdef CONFIG_CMDLINE + strcpy(cmd_line, CONFIG_CMDLINE); +#endif /* CONFIG_CMDLINE */ + parse_bootinfo(); if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100); @@ -532,10 +485,11 @@ { /* prep boot loader tells us if we're prep or not */ if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) - { _machine = _MACH_prep; - } else - have_of = 1; + else + /* If we aren't PReP, we can find out if we're Pmac + * or CHRP with this. */ + intuit_machine_type(); } if ( have_of ) @@ -543,9 +497,8 @@ /* prom_init has already been called from __start */ if (boot_infos) relocate_nodes(); - /* we need to set _machine before calling finish_device_tree */ - if (_machine == 0) - intuit_machine_type(); + + /* _machine must be defined by now, so this is safe. */ finish_device_tree(); /* * If we were booted via quik, r3 points to the physical @@ -558,6 +511,7 @@ * otherwise they contain 0xdeadbeef. */ if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) { + cmd_line[0] = 0; strncpy(cmd_line, (char *)r3 + KERNELBASE, sizeof(cmd_line)); } else if (boot_infos != 0) { @@ -589,7 +543,6 @@ initrd_below_start_ok = 1; } #endif - cmd_line[0] = 0; chosen = find_devices("chosen"); if (chosen != NULL) { p = get_property(chosen, "bootargs", NULL); @@ -616,18 +569,36 @@ chrp_init(r3, r4, r5, r6, r7); break; default: - printk("Unknown machine type in identify_machine!\n"); + printk("Unknown machine type in identify_machine()!\n"); } #elif defined(CONFIG_APUS) apus_init(r3, r4, r5, r6, r7); #elif defined(CONFIG_GEMINI) gemini_init(r3, r4, r5, r6, r7); -#elif defined(CONFIG_4xx) - oak_init(r3, r4, r5, r6, r7); +#elif defined(CONFIG_K2) + k2_init(r3, r4, r5, r6, r7); #elif defined(CONFIG_8xx) m8xx_init(r3, r4, r5, r6, r7); #elif defined(CONFIG_8260) m8260_init(r3, r4, r5, r6, r7); +#elif defined(CONFIG_MENF1) + menf1_init(r3, r4, r5, r6, r7); +#elif defined(CONFIG_MCPN765) + mcpn765_init(r3, r4, r5, r6, r7); +#elif defined(CONFIG_MVME5100) + mvme5100_init(r3, r4, r5, r6, r7); +#elif defined(CONFIG_PCORE) + pcore_init(r3, r4, r5, r6, r7); +#elif defined(CONFIG_PRPMC750) + prpmc750_init(r3, r4, r5, r6, r7); +#elif defined(CONFIG_SANDPOINT) + sandpoint_init(r3, r4, r5, r6, r7); +#elif defined(CONFIG_SPRUCE) + spruce_init(r3, r4, r5, r6, r7); +#elif defined(CONFIG_4xx) + oak_init(r3, r4, r5, r6, r7); +#elif defined(CONFIG_ZX4500) + zx4500_init(r3, r4, r5, r6, r7); #else #error "No board type has been defined for identify_machine()!" #endif @@ -670,6 +641,13 @@ return 0; } +#if defined(CONFIG_SPRUCE) +int boot_mem_size; /* Used with the BI_MEMSIZE bootinfo parameter to + * store the memory size value reported by the boot + * loader. + */ +#endif + int parse_bootinfo(void) { struct bi_record *rec; @@ -712,9 +690,13 @@ #ifdef CONFIG_ALL_PPC case BI_MACHTYPE: _machine = data[0]; - have_of = data[1]; break; #endif /* CONFIG_ALL_PPC */ +#ifdef CONFIG_SPRUCE + case BI_MEMSIZE: + boot_mem_size = data[0]; + break; +#endif /* CONFIG_SPRUCE */ } } @@ -724,8 +706,7 @@ /* Checks "l2cr=xxxx" command-line option */ int ppc_setup_l2cr(char *str) { - if ( ((_get_PVR() >> 16) == 8) || ((_get_PVR() >> 16) == 12) ) - { + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) { unsigned long val = simple_strtoul(str, NULL, 0); printk(KERN_INFO "l2cr set to %lx\n", val); _set_L2CR(0); /* force invalidate by disable cache */ @@ -777,18 +758,13 @@ * Systems with OF can look in the properties on the cpu node(s) * for a possibly more accurate value. */ - dcache_bsize = icache_bsize = 32; /* most common value */ - switch (_get_PVR() >> 16) { - case 1: /* 601, with unified cache */ - ucache_bsize = 32; - break; - /* XXX need definitions in here for 8xx etc. */ - case 0x40: - case 0x41: - case 0x35: /* 64-bit POWER3, POWER3+, POWER4 */ - dcache_bsize = icache_bsize = 128; - break; - } + if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPLIT_ID_CACHE) { + dcache_bsize = cur_cpu_spec[0]->dcache_bsize; + icache_bsize = cur_cpu_spec[0]->icache_bsize; + ucache_bsize = 0; + } else + ucache_bsize = dcache_bsize = icache_bsize + = cur_cpu_spec[0]->dcache_bsize; /* reboot on panic */ panic_timeout = 180; @@ -809,7 +785,7 @@ ppc_md.setup_arch(); if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); -#ifdef CONFIG_PCI +#if defined(CONFIG_PCI) && defined(CONFIG_ALL_PPC) /* We create the "pci-OF-bus-map" property now so it appear in the * /proc device tree */ @@ -825,7 +801,7 @@ prom_add_property(find_path_device("/"), of_prop); } } -#endif /* CONFIG_PCI */ +#endif /* CONFIG_PCI && CONFIG_ALL_PPC */ paging_init(); sort_exception_table(); diff -Nru a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c --- a/arch/ppc/kernel/signal.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/kernel/signal.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.signal.c 1.7 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/signal.c diff -Nru a/arch/ppc/kernel/sleep.S b/arch/ppc/kernel/sleep.S --- a/arch/ppc/kernel/sleep.S Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/kernel/sleep.S Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.sleep.S 1.7 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * This file contains sleep low-level functions for PowerBook G3. @@ -194,7 +194,7 @@ lis r3,0x2000 /* Ku = 1, VSID = 0 */ li r4,0 3: mtsrin r3,r4 - addi r3,r3,1 /* increment VSID */ + addi r3,r3,0x111 /* increment VSID */ addis r4,r4,0x1000 /* address of next segment */ bdnz 3b diff -Nru a/arch/ppc/kernel/smp.c b/arch/ppc/kernel/smp.c --- a/arch/ppc/kernel/smp.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/kernel/smp.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.smp.c 1.25 05/23/01 00:38:42 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Smp support for ppc. diff -Nru a/arch/ppc/kernel/softemu8xx.c b/arch/ppc/kernel/softemu8xx.c --- a/arch/ppc/kernel/softemu8xx.c Sat Jun 16 06:00:30 2001 +++ b/arch/ppc/kernel/softemu8xx.c Sat Jun 16 06:00:30 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.softemu8xx.c 1.8 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Software emulation of some PPC instructions for the 8xx core. diff -Nru a/arch/ppc/kernel/spruce_pci.c b/arch/ppc/kernel/spruce_pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/spruce_pci.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,174 @@ +/* + * arch/ppc/kernel/spruce_pci.c + * + * PCI support for IBM Spruce + * + * Author: Johnnie Peters + * jpeters@mvista.com + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "cpc700.h" +#include "pci_auto.h" +#include "pci.h" + +static inline int __init +spruce_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + {0, 0, 0, 0}, /* IDSEL 0 - unused */ + {23, 24, 25, 26}, /* IDSEL 1 - PCI slot 3 */ + {24, 25, 26, 23}, /* IDSEL 2 - PCI slot 2 */ + {25, 26, 23, 24}, /* IDSEL 3 - PCI slot 1 */ + {26, 23, 24, 25}, /* IDSEL 4 - PCI slot 0 */ + {0, 0, 0, 0}, /* IDSEL 5 - unused */ + {0, 0, 0, 0}, /* IDSEL 6 - unused */ + {0, 0, 0, 0}, /* IDSEL 7 - unused */ + {0, 0, 0, 0}, /* IDSEL 8 - unused */ + {0, 0, 0, 0}, /* IDSEL 9 - unused */ + {0, 0, 0, 0}, /* IDSEL 10 - unused */ + {0, 0, 0, 0}, /* IDSEL 11 - unused */ + {1, 0, 0, 0}, /* IDSEL 12 - ATM */ + {0, 0, 0, 0}, /* IDSEL 13 - Ethernet */ + {0, 0, 0, 0}, /* IDSEL 14 - Drawbridge */ + {6, 7, 7, 7}, /* IDSEL 15 - PMC Site */ + }; + + const long min_idsel = 0, max_idsel = 15, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +void +spruce_route_non0(struct pci_dev *dev) +{ + struct pci_bus *pbus; /* Parent bus structure pointer */ + struct pci_dev *tdev = dev; /* Temporary pci_dev pointer */ + unsigned int devnum; /* Accumulated device number */ + unsigned char intpin; /* PCI interrupt pin */ + struct pci_controller *hose; /* PCI controller */ + + /* Check for valid PCI dev pointer */ + if (dev == NULL) return; + + /* Get a pointer to our pci_controller descriptor */ + hose = pci_bus_to_hose(dev->bus->number); + /* Initialize bridge IDSEL variable */ + devnum = PCI_SLOT(dev->devfn); + + /* Read the interrupt pin of the device */ + pcibios_read_config_byte(dev->bus->number, dev->devfn, + PCI_INTERRUPT_PIN, &intpin); + + /* If device doesn't request an interrupt, return */ + if ( (intpin < 1) || (intpin > 4) ) + return; + + intpin--; + + /* + * Walk up to the top bus, adjusting the interrupt pin for the + *standard PCI bus swizzle. + */ + do { + intpin = bridge_swizzle(intpin, devnum); + pbus = tdev->bus; /* up one level */ + tdev = pbus->self; + devnum = PCI_SLOT(tdev->devfn); + } while(tdev->bus->number != hose->first_busno); + + dev->irq = spruce_map_irq(pbus->self, devnum, intpin); + + /* Write calculated interrupt value to header and device list */ + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); +} + +void spruce_pcibios_fixup(void) +{ + struct pci_dev * dev; + + pci_for_each_dev(dev) { + if (pci_bus_to_hose(dev->bus->number)->first_busno) + spruce_route_non0(dev); + } +} + +void spruce_pcibios_fixup_resources(struct pci_dev *dev) +{ + int i; + + if ((dev->vendor == PCI_VENDOR_ID_IBM) && + (dev->device == PCI_DEVICE_ID_IBM_CPC710_PCI64)) + { + for (i=0; iresource[i].start = 0; + dev->resource[i].end = 0; + } + } +} + + +void spruce_find_bridges(void) +{ + struct pci_controller *hose_a; + + /* Setup PCI32 hose */ + hose_a = pcibios_alloc_controller(); + if (!hose_a) + return; + + hose_a->first_busno = 0; + hose_a->last_busno = 0xff; + hose_a->pci_mem_offset = SPRUCE_PCI_PHY_MEM_BASE; + hose_a->io_space.start = SPRUCE_PCI_LOWER_IO; + hose_a->io_space.end = SPRUCE_PCI_UPPER_IO; + hose_a->mem_space.start = SPRUCE_PCI_LOWER_MEM; + hose_a->mem_space.end = SPRUCE_PCI_UPPER_MEM; + hose_a->io_base_virt = (void *)SPRUCE_ISA_IO_BASE; + + setup_indirect_pci(hose_a, SPRUCE_PCI_CONFIG_ADDR, SPRUCE_PCI_CONFIG_DATA); + + hose_a->last_busno = pciauto_bus_scan(hose_a, hose_a->first_busno); + + ppc_md.pcibios_fixup = spruce_pcibios_fixup; + ppc_md.pcibios_fixup_resources = spruce_pcibios_fixup_resources; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = spruce_map_irq; +} diff -Nru a/arch/ppc/kernel/spruce_pic.c b/arch/ppc/kernel/spruce_pic.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/spruce_pic.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,246 @@ +/* + * arch/ppc/kernel/spruce_pic.c + * + * Interrupt controller support for IBM Spruce + * + * Authors: Matt Porter and Johnnie Peters + * mporter@mvista.com + * jpeters@mvista.com + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "local_irq.h" +#include "cpc700.h" +#include + +void spruce_unmask_irq(unsigned int); +void spruce_mask_irq(unsigned int); +void spruce_mask_and_ack_irq(unsigned int); +static void spruce_end_irq(unsigned int); + +void cpc700_pic_init_irq(unsigned int); +int cpc700_pic_get_irq(void); + +struct hw_interrupt_type spruce_pic = { + "CPC700 PIC", + NULL, + NULL, + spruce_unmask_irq, + spruce_mask_irq, + spruce_mask_and_ack_irq, + NULL, + NULL +}; + +/* + * Table used to ensure proper programming of IRQs 0-16. + * + * First entry is the sensitivity (level/edge), second is the polarity. + */ +static u_int cpc700_irq_assigns[27][2] = { + { 1, 1 }, /* IRQ 0: ECC Correctable Error - rising edge */ + { 1, 1 }, /* IRQ 1: PCI Write Mem Range - rising edge */ + { 0, 1 }, /* IRQ 2: PCI Write Command Reg - active high */ + { 0, 1 }, /* IRQ 3: UART 0 - active high */ + { 0, 1 }, /* IRQ 4: UART 1 - active high */ + { 0, 1 }, /* IRQ 5: ICC 0 - active high */ + { 0, 1 }, /* IRQ 6: ICC 1 - active high */ + { 0, 1 }, /* IRQ 7: GPT Compare 0 - active high */ + { 0, 1 }, /* IRQ 8: GPT Compare 1 - active high */ + { 0, 1 }, /* IRQ 9: GPT Compare 2 - active high */ + { 0, 1 }, /* IRQ 10: GPT Compare 3 - active high */ + { 0, 1 }, /* IRQ 11: GPT Compare 4 - active high */ + { 0, 1 }, /* IRQ 12: GPT Capture 0 - active high */ + { 0, 1 }, /* IRQ 13: GPT Capture 1 - active high */ + { 0, 1 }, /* IRQ 14: GPT Capture 2 - active high */ + { 0, 1 }, /* IRQ 15: GPT Capture 3 - active high */ + { 0, 1 }, /* IRQ 16: GPT Capture 4 - active high */ + { 0, 0 }, /* IRQ 17: Reserved */ + { 0, 0 }, /* IRQ 18: Reserved */ + { 0, 0 }, /* IRQ 19: Reserved */ + { 0, 1 }, /* IRQ 20: FPGA EXT_IRQ0 - active high */ + { 1, 1 }, /* IRQ 21: Mouse - rising edge */ + { 1, 1 }, /* IRQ 22: Keyboard - rising edge */ + { 0, 0 }, /* IRQ 23: PCI Slot 3 - active low */ + { 0, 0 }, /* IRQ 24: PCI Slot 2 - active low */ + { 0, 0 }, /* IRQ 25: PCI Slot 1 - active low */ + { 0, 0 }, /* IRQ 26: PCI Slot 0 - active low */ +}; + +void +spruce_unmask_irq(unsigned int irq) +{ + unsigned int tr_bits; + + /* + * IRQ 31 is largest IRQ supported. + * IRQs 17-19 are reserved. + */ + if ((irq <= 31) && ((irq < 17) || (irq > 19))) { + tr_bits = CPC700_IN_32(CPC700_UIC_UICTR); + + if ((tr_bits & (1 << (31 - irq))) == 0) { + /* level trigger interrupt, clear bit in status + * register */ + CPC700_OUT_32(CPC700_UIC_UICSR, 1 << (31 - irq)); + } + + /* Know IRQ fits in entry 0 of ppc_cached_irq_mask[] */ + ppc_cached_irq_mask[0] |= CPC700_UIC_IRQ_BIT(irq); + + CPC700_OUT_32(CPC700_UIC_UICER, ppc_cached_irq_mask[0]); + } + return; +} + +void +spruce_mask_irq(unsigned int irq) +{ + /* + * IRQ 31 is largest IRQ supported. + * IRQs 17-19 are reserved. + */ + if ((irq <= 31) && ((irq < 17) || (irq > 19))) { + /* Know IRQ fits in entry 0 of ppc_cached_irq_mask[] */ + ppc_cached_irq_mask[0] &= + ~CPC700_UIC_IRQ_BIT(irq); + + CPC700_OUT_32(CPC700_UIC_UICER, ppc_cached_irq_mask[0]); + } + return; +} + +void +spruce_mask_and_ack_irq(unsigned int irq) +{ + u_int bit; + + /* + * IRQ 31 is largest IRQ supported. + * IRQs 17-19 are reserved. + */ + if ((irq <= 31) && ((irq < 17) || (irq > 19))) { + /* Know IRQ fits in entry 0 of ppc_cached_irq_mask[] */ + bit = CPC700_UIC_IRQ_BIT(irq); + + ppc_cached_irq_mask[0] &= ~bit; + CPC700_OUT_32(CPC700_UIC_UICER, ppc_cached_irq_mask[0]); + CPC700_OUT_32(CPC700_UIC_UICSR, bit); /* Write 1 clears IRQ */ + } + return; +} + +__init void +spruce_init_IRQ(void) +{ + int i; + + ppc_cached_irq_mask[0] = 0; + CPC700_OUT_32(CPC700_UIC_UICER, 0x00000000); /* Disable all irq's */ + CPC700_OUT_32(CPC700_UIC_UICSR, 0xffffffff); /* Clear cur intrs */ + CPC700_OUT_32(CPC700_UIC_UICCR, 0xffffffff); /* Gen INT not MCP */ + CPC700_OUT_32(CPC700_UIC_UICPR, 0x00000000); /* Active low */ + CPC700_OUT_32(CPC700_UIC_UICTR, 0x00000000); /* Level Sensitive */ + CPC700_OUT_32(CPC700_UIC_UICVR, CPC700_UIC_UICVCR_0_HI); + /* IRQ 0 is highest */ + + for (i = 0; i < 17; i++) { + irq_desc[i].handler = &spruce_pic; + cpc700_pic_init_irq(i); + } + + for (i = 20; i < 27; i++) { + irq_desc[i].handler = &spruce_pic; + cpc700_pic_init_irq(i); + } + + return; +} + +void +cpc700_pic_init_irq(unsigned int irq) +{ + unsigned int tmp; + + /* Set interrupt sense */ + tmp = CPC700_IN_32(CPC700_UIC_UICTR); + if (cpc700_irq_assigns[irq][0] == 0) { + tmp &= ~CPC700_UIC_IRQ_BIT(irq); + } else { + tmp |= CPC700_UIC_IRQ_BIT(irq); + } + CPC700_OUT_32(CPC700_UIC_UICTR, tmp); + + /* Set interrupt polarity */ + tmp = CPC700_IN_32(CPC700_UIC_UICPR); + if (cpc700_irq_assigns[irq][1]) { + tmp |= CPC700_UIC_IRQ_BIT(irq); + } else { + tmp &= ~CPC700_UIC_IRQ_BIT(irq); + } + CPC700_OUT_32(CPC700_UIC_UICPR, tmp); + + /* Set interrupt critical */ + tmp = CPC700_IN_32(CPC700_UIC_UICCR); + tmp |= CPC700_UIC_IRQ_BIT(irq); + CPC700_OUT_32(CPC700_UIC_UICCR, tmp); + + return; +} + +/* + * Find the highest IRQ that generating an interrupt, if any. + */ +int +spruce_get_irq(void) +{ + int irq = 0; + u_int irq_status, irq_test = 1; + + irq_status = CPC700_IN_32(CPC700_UIC_UICMSR); + + do + { + if (irq_status & irq_test) + break; + irq++; + irq_test <<= 1; + } while (irq < NR_IRQS); + + + if (irq == NR_IRQS) + irq = 33; + + return (31 - irq); +} diff -Nru a/arch/ppc/kernel/spruce_setup.c b/arch/ppc/kernel/spruce_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/spruce_setup.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,240 @@ +/* + * arch/ppc/kernel/spruce_setup.c + * + * Board setup routines for IBM Spruce + * + * Author: Johnnie Peters + * jpeters@mvista.com + * + * Copyright 2000 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN + * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * 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., + * 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +extern void spruce_init_IRQ(void); +extern int spruce_get_irq(struct pt_regs *); +extern void spruce_find_bridges(void); +extern void spruce_setup_pci_ptrs(void); + + +extern int pckbd_setkeycode(unsigned int, unsigned int); +extern int pckbd_getkeycode(unsigned int); +extern int pckbd_translate(unsigned char, unsigned char *, char); +extern char pckbd_unexpected_up(unsigned char); +extern void pckbd_leds(unsigned char); +extern void pckbd_init_hw(void); +extern unsigned char pckbd_sysrq_xlate[128]; + +int +spruce_set_rtc_time( unsigned long now ) +{ + return 0; +} + +unsigned long +spruce_get_rtc_time(void) +{ + return 0; +} + +void __init spruce_calibrate_decr(void) +{ + int freq, divisor = 4; + + /* determine processor bus speed */ + freq = SPRUCE_BUS_SPEED; + tb_ticks_per_jiffy = freq / HZ / divisor; + tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); +} + +int +spruce_get_cpuinfo(char *buffer) +{ + int len; + + len = sprintf( buffer, "vendor\t\t: IBM\n"); + + len += sprintf( buffer+len, "machine\t\t: Spruce\n"); + + len += sprintf( buffer+len, "L2\t\t: 256 Kb\n"); + + len += sprintf( buffer+len, "memory type\t: SDRAM\n"); + + len += sprintf(buffer+len, "\n"); + + return len; +} + +extern char cmd_line[]; + +void __init +spruce_setup_arch(void) +{ + unsigned int cpu; + extern char cmd_line[]; + + /* init to some ~sane value until calibrate_delay() runs */ + loops_per_jiffy = 50000000 / HZ; + + /* Setup PCI host bridges */ + spruce_find_bridges(); + +#ifdef CONFIG_ROOT_NFS + /* bootable from nfsroot */ + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + /* bootable from SCSI */ + ROOT_DEV = to_kdev_t(0x0801); /* /dev/sda1 */ +#endif + + printk("Boot arguments: %s\n", cmd_line); + + /* Identify the system */ + printk("System Identification: IBM Spruce\n"); + printk("IBM Spruce port (C) 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + + /* Identify the CPU manufacturer */ + cpu = _get_PVR(); + printk("CPU manufacturer: IBM [rev=%04x]\n", cpu & 0xffff); + _set_L2CR(0x80000000); +} + +void +spruce_restart(char *cmd) +{ + __cli(); + + /* SRR0 has system reset vector, SRR1 has default MSR value */ + /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ + __asm__ __volatile__ + ("\n\ + lis 3,0xfff0 + ori 3,3,0x0100 + mtspr 26,3 + li 3,0 + mtspr 27,3 + rfi + "); + for(;;); +} + +void +spruce_power_off(void) +{ + for(;;); +} + +void +spruce_halt(void) +{ + spruce_restart(NULL); +} + +extern int boot_mem_size; + +unsigned long __init +spruce_find_end_of_memory(void) +{ + return boot_mem_size; +} + +void __init +spruce_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ +#ifdef CONFIG_BLK_DEV_INITRD + if ( r4 ) + { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif + + /* take care of cmd line */ + if ( r6 && (((char *) r6) != '\0')) + { + *(char *)(r7+KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6+KERNELBASE)); + } + + isa_io_base = SPRUCE_ISA_IO_BASE; + isa_mem_base = SPRUCE_ISA_MEM_BASE; + pci_dram_offset = SPRUCE_PCI_SYS_MEM_BASE; + + ppc_md.setup_arch = spruce_setup_arch; + ppc_md.setup_residual = NULL; + ppc_md.get_cpuinfo = spruce_get_cpuinfo; + ppc_md.irq_cannonicalize = NULL; + ppc_md.init_IRQ = spruce_init_IRQ; + ppc_md.get_irq = spruce_get_irq; + ppc_md.init = NULL; + + ppc_md.find_end_of_memory = spruce_find_end_of_memory; + + ppc_md.restart = spruce_restart; + ppc_md.power_off = spruce_power_off; + ppc_md.halt = spruce_halt; + + /* Spruce has a DS9034? */ + ppc_md.time_init = NULL; + ppc_md.set_rtc_time = spruce_set_rtc_time; + ppc_md.get_rtc_time = spruce_get_rtc_time; + ppc_md.calibrate_decr = spruce_calibrate_decr; + +#ifdef CONFIG_VT + /* Spruce has a PS2 styke 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.kbd_sysrq_xlate = pckbd_sysrq_xlate; + SYSRQ_KEY = 0x54; +#endif +#endif +} diff -Nru a/arch/ppc/kernel/syscalls.c b/arch/ppc/kernel/syscalls.c --- a/arch/ppc/kernel/syscalls.c Sat Jun 16 06:00:30 2001 +++ b/arch/ppc/kernel/syscalls.c Sat Jun 16 06:00:30 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.syscalls.c 1.8 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/sys_ppc.c diff -Nru a/arch/ppc/kernel/temp.c b/arch/ppc/kernel/temp.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/temp.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,232 @@ +/* + * temp.c Thermal management for cpu's with Thermal Assist Units + * + * Written by Troy Benjegerdes + * + * TODO: + * make this work + * + * dynamic power management to limit peak CPU temp (using ICTC) + * + * Blue sky: use cpu load (from scheduler) and ICTC to extend battery life in + * portables, and add a 'performance/watt' metric somewhere in /proc + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static struct tau_temp +{ + unsigned char low; + unsigned char high; + int interrupts; +} tau[NR_CPUS]; + +struct timer_list tau_timer; + +/* TODO: put these in a /proc interface, with some sanity checks, and maybe + * dynamic adjustment to minimize # of interrupts */ +/* configurable values for step size and how much to expand the window when + * we get an interrupt. These are based on the limit that was out of range */ +#define step_size 2 /* step size when temp goes out of range */ +#define window_expand 1 /* expand the window by this much */ +/* configurable values for shrinking the window */ +#define shrink_timer 2*HZ /* period between shrinking the window */ +#define min_window 2 /* minimum window size, degrees C */ + +/* + * TAU interrupts - called when we have a thermal assist unit interrupt + * with interrupts disabled + */ + +void set_thresholds(unsigned long cpu){ + /* + * setup THRM1, + * threshold, valid bit, enable interrupts, interrupt when below threshold + */ + mtspr(SPRN_THRM1, THRM1_THRES(tau[cpu].low) | THRM1_V | THRM1_TIE | THRM1_TID); + + /* setup THRM2, + * threshold, valid bit, enable interrupts, interrupt when above threshhold + */ + mtspr (SPRN_THRM2, THRM1_THRES(tau[cpu].high) | THRM1_V | THRM1_TIE); +} + +void TAUException(struct pt_regs * regs) +{ + unsigned long cpu = smp_processor_id(); + + hardirq_enter(cpu); + tau[cpu].interrupts++; + +#if 0 /* this is somewhat goofy on smp */ + /* Reset the shrink timer, since we just had an interrupt */ + mod_timer(&tau_timer, jiffies + shrink_timer); +#endif + + /* if both thresholds are crossed, the step_sizes cancel out + * and the window winds up getting expanded twice. */ + if(mfspr(SPRN_THRM1) & THRM1_TIV){ /* is valid? */ + if(mfspr(SPRN_THRM1) & THRM1_TIN){ /* crossed low threshold */ + tau[cpu].low -= step_size; + tau[cpu].high -= (step_size - window_expand); + } + } + if(mfspr(SPRN_THRM2) & THRM1_TIV){ /* is valid? */ + if(mfspr(SPRN_THRM2) & THRM1_TIN){ /* crossed high threshold */ + tau[cpu].low += (step_size - window_expand); + tau[cpu].high += step_size; + } + } + set_thresholds(cpu); + + hardirq_exit(cpu); + return; +} + +static void tau_timeout(void * info) +{ + unsigned long cpu = smp_processor_id(); + unsigned long flags; + int size; + int shrink; + + + + /* disabling interrupts *should* be okay */ + save_flags(flags); cli(); + + size = tau[cpu].high - tau[cpu].low; + if (size > min_window){ + /* do an exponential shrink of half the amount currently over size */ + shrink = (2 + size - min_window) / 4; + if (shrink){ + tau[cpu].low += shrink; + tau[cpu].high -= shrink; + } else { /* size must have been min_window + 1 */ + tau[cpu].low += 1; + #if 1 /* debug */ + if ((tau[cpu].high - tau[cpu].low) != min_window){ + printk("temp.c: line %d, logic error\n", __LINE__); + } + #endif + } + } + set_thresholds(cpu); + restore_flags(flags); +} + +static void tau_timeout_smp(unsigned long unused) +{ + + /* schedule ourselves to be run again */ + mod_timer(&tau_timer, jiffies + shrink_timer) ; +#ifdef CONFIG_SMP + smp_call_function(tau_timeout, NULL, 1, 0); +#endif + tau_timeout(NULL); +} + +/* + * setup the TAU + * + * Set things up to use THRM1 as a temperature lower bound, and THRM2 as an upper bound. + * Start off at zero + */ + +int tau_initialized = 0; + +void TAU_init_smp(void * info) +{ + unsigned long cpu = smp_processor_id(); + + tau[cpu].low = 0; + tau[cpu].high = 0; + + + + /* set these to a reasonable value and let the timer shrink the + * window */ + tau[cpu].low = 30; + tau[cpu].high = 60; + + + /* + * Enable thermal sensor and set up sample interval timer + * need 20 us to do the compare.. until a nice 'cpu_speed' function + * call is implemented, just assume a 500 mhz clock. It doesn't really + * matter if we take too long for a compare since it's all interrupt + * driven anyway. + * + * use a extra long time.. (60 us @ 500 mhz) + */ + mtspr(SPRN_THRM3, THRM3_SITV(500*60) | THRM3_E); + + set_thresholds(cpu); +} + +int __init TAU_init(void) +{ + switch (PVR_VER(_get_PVR())){ + case 0x0008: /* 740/750 */ + case 0x1008: /* 750P */ + case 0x000C: /* G4 */ + case 0x8000: /* 7450 */ + case 0x800c: /* 7410 */ + break; + default: + printk("Thermal assist unit not available\n"); + tau_initialized = 0; + return 1; + } + + + /* first, set up the window shrinking timer */ + init_timer(&tau_timer); + tau_timer.function = tau_timeout_smp; + tau_timer.expires = jiffies + shrink_timer; + add_timer(&tau_timer); + +#ifdef CONFIG_SMP + smp_call_function(TAU_init_smp, NULL, 1, 0); +#endif + TAU_init_smp(NULL); + + printk("Thermal assist unit initialized\n"); + tau_initialized = 1; + + return 0; +} + +__initcall(TAU_init); + +/* + * return current temp + */ + +u32 cpu_temp_both(unsigned long cpu){ + return((tau[cpu].high << 16) | tau[cpu].low); +} + +int cpu_temp(unsigned long cpu){ + return ((tau[cpu].high + tau[cpu].low)/2); +} + +int tau_interrupts(unsigned long cpu){ + return ((tau[cpu].interrupts)); +} diff -Nru a/arch/ppc/kernel/time.c b/arch/ppc/kernel/time.c --- a/arch/ppc/kernel/time.c Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/kernel/time.c Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.time.c 1.18 06/06/01 22:33:09 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Common time routines among all ppc machines. diff -Nru a/arch/ppc/kernel/todc.h b/arch/ppc/kernel/todc.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/todc.h Sat Jun 16 06:00:32 2001 @@ -0,0 +1,104 @@ +/* + * include/asm-ppc/todc.h + * + * Definitions for the M48Txx and mc146818 series of Time of day/Real Time + * Clock chips. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * Support for the M48T37/M48T59/.../mc146818 Real Time Clock chips. + * Purpose is to make one generic file that handles all of these chips instead + * of every platform implementing the same code over & over again. + */ + +#ifndef __PPC_KERNEL_TODC_H +#define __PPC_KERNEL_TODC_H + +typedef struct { + uint rtc_type; /* your particular chip */ + + /* + * Following are the addresses of the AS0, AS1, and DATA registers + * of these chips. Note that these are board-specific. + */ + u_char *nvram_as0; + u_char *nvram_as1; + u_char *nvram_data; + + /* + * Following is the number of AS0 address bits. This is normally + * 8 but some bad hardware routes address lines incorrectly. + */ + int as0_bits; + + /* Following are the register offsets for the particular chip */ + int year; + int month; + int day_of_month; + int day_of_week; + int hours; + int minutes; + int seconds; + int control_b; + int control_a; + int watchdog; + int interrupts; + int alarm_date; + int alarm_hour; + int alarm_minutes; + int alarm_seconds; + int century; + int flags; +} todc_info_t; + +/* + * Define the types of TODC/RTC variants that are supported in + * arch/ppc/kernel/todc_time.c + * Make a new one of these for any chip somehow differs from what's already + * defined. That way, if you ever need to put in code to touch those + * bits/registers in todc_time.c, you can put it inside an + * 'if (todc_info->rtc_type == TODC_TYPE_XXX)' so you won't break + * anyone else. + */ +#define TODC_TYPE_MK48T35 1 +#define TODC_TYPE_MK48T37 2 +#define TODC_TYPE_MK48T59 3 +#define TODC_TYPE_MC146818 100 /* Leave room for more m48txx's */ + +#ifndef BCD_TO_BIN +#define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10) +#endif + +#ifndef BIN_TO_BCD +#define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10) +#endif + +extern todc_info_t *todc_info; +extern todc_info_t m48t35_info; +extern todc_info_t m48t37_info; +extern todc_info_t m48t59_info; +extern todc_info_t mc146818_info; + +u_char todc_direct_read_val(int addr); +void todc_direct_write_val(int addr, unsigned char val); +u_char todc_m48txx_read_val(int addr); +void todc_m48txx_write_val(int addr, unsigned char val); +u_char todc_mc146818_read_val(int addr); +void todc_mc146818_write_val(int addr, unsigned char val); + +long todc_time_init(void); +unsigned long todc_get_rtc_time(void); +int todc_set_rtc_time(unsigned long nowtime); +void todc_calibrate_decr(void); + +#endif /* __PPC_KERNEL_TODC_H */ diff -Nru a/arch/ppc/kernel/todc_time.c b/arch/ppc/kernel/todc_time.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/todc_time.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,502 @@ +/* + * arch/ppc/kernel/todc_time.c + * + * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818 + * Real Time Clocks/Timekeepers. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "todc.h" + +/* + * Depending on the hardware on your board and your board design, the + * RTC/NVRAM may be accessed either directly (like normal memory) or via + * address/data registers. If your board uses the direct method, set + * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and + * 'nvram_as1' NULL. If your board uses address/data regs to access nvram, + * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the + * address of the upper byte (leave NULL if using mv146818), and set + * 'nvram_data' to the address of the 8-bit data register. + * + * You also need to set 'ppc_md.nvram_read_val' and 'ppc_md.nvram_write_val' to + * the proper routines. There are standard ones defined further down in + * this file that you can use. + * + * There is a built in assumption that the RTC and NVRAM are accessed by the + * same mechanism (i.e., ppc_md.nvram_read_val, etc works for both). + */ + +/* + * 'todc_info' should be initialized in your *_setup.c file to + * point to a fully initialized 'todc_info_t' structure. + * This structure holds all the register offsets for your particular + * TODC/RTC chip. + */ +todc_info_t *todc_info = NULL; + +/* + * Allocate & initialize sample 'todc_info_t' structures for the M48T35, M48T37, + * M48T59, and M146818. You can use these ones, add others, or you can make + * your own in your *_setup.c file. + */ +todc_info_t m48t35_info = { + TODC_TYPE_MK48T35, /* rtc_type */ + + (u_char *)0, /* nvram_as0 -- board specific */ + (u_char *)0, /* nvram_as1 -- board specific */ + (u_char *)0, /* nvram_data -- board specific */ + + 8, /* as0_bits */ + + 0x7fff, /* year */ + 0x7ffe, /* month */ + 0x7ffd, /* day_of_month */ + 0x7ffc, /* day_of_week */ + 0x7ffb, /* hours */ + 0x7ffa, /* minutes */ + 0x7ff9, /* seconds */ + 0x7ff9, /* control_b */ + 0x7ff8, /* control_a */ + 0xffff, /* watchdog -- not used */ + 0xffff, /* interrupts -- not used */ + 0xffff, /* alarm_date -- not used */ + 0xffff, /* alarm_hour -- not used */ + 0xffff, /* alarm_minutes -- not used */ + 0xffff, /* alarm_seconds -- not used */ + 0xffff, /* century -- not used */ + 0xffff /* flags -- not used */ +}; + +todc_info_t m48t37_info = { + TODC_TYPE_MK48T37, /* rtc_type */ + + (u_char *)0, /* nvram_as0 -- board specific */ + (u_char *)0, /* nvram_as1 -- board specific */ + (u_char *)0, /* nvram_data -- board specific */ + + 8, /* as0_bits */ + + 0x7fff, /* year */ + 0x7ffe, /* month */ + 0x7ffd, /* day_of_month */ + 0x7ffc, /* day_of_week */ + 0x7ffb, /* hours */ + 0x7ffa, /* minutes */ + 0x7ff9, /* seconds */ + 0x7ff9, /* control_b */ + 0x7ff8, /* control_a */ + 0x7ff7, /* watchdog */ + 0x7ff6, /* interrupts */ + 0x7ff5, /* alarm_date */ + 0x7ff4, /* alarm_hour */ + 0x7ff3, /* alarm_minutes */ + 0x7ff2, /* alarm_seconds */ + 0x7ff1, /* century */ + 0x7ff0 /* flags */ +}; + +todc_info_t m48t59_info = { + TODC_TYPE_MK48T59, /* rtc_type */ + + (u_char *)0, /* nvram_as0 -- board specific */ + (u_char *)0, /* nvram_as1 -- board specific */ + (u_char *)0, /* nvram_data -- board specific */ + + 8, /* as0_bits */ + + 0x1fff, /* year */ + 0x1ffe, /* month */ + 0x1ffd, /* day_of_month */ + 0x1ffc, /* day_of_week */ + 0x1ffb, /* hours */ + 0x1ffa, /* minutes */ + 0x1ff9, /* seconds */ + 0x1ff9, /* control_b */ + 0x1ff8, /* control_a */ + 0x1ff7, /* watchdog */ + 0x1ff6, /* interrupts */ + 0x1ff5, /* alarm_date */ + 0x1ff4, /* alarm_hour */ + 0x1ff3, /* alarm_minutes */ + 0x1ff2, /* alarm_seconds */ + 0x1ff1, /* century */ + 0x1ff0 /* flags */ +}; + +todc_info_t mc146818_info = { + TODC_TYPE_MC146818, /* rtc_type */ + + (u_char *)0x70, /* nvram_as0 -- ISA address, can modify */ + (u_char *)0, /* nvram_as1 -- not used */ + (u_char *)0x71, /* nvram_data -- ISA address, can modify */ + + 8, /* as0_bits */ + + 0x09, /* year */ + 0x08, /* month */ + 0x07, /* day_of_month */ + 0x06, /* day_of_week */ + 0x04, /* hours */ + 0x02, /* minutes */ + 0x00, /* seconds */ + 0x0a, /* control_b -- used for Register A */ + 0x0b, /* control_a -- used for Register B */ + 0x0c, /* watchdog -- used for Register C */ + 0x0d, /* interrupts -- used for Register D */ + 0xff, /* alarm_date -- not used */ + 0x05, /* alarm_hour */ + 0x03, /* alarm_minutes */ + 0x01, /* alarm_seconds */ + 0xff, /* century -- not used */ + 0xff /* flags -- not used */ +}; + +#ifdef RTC_FREQ_SELECT +#undef RTC_FREQ_SELECT +#define RTC_FREQ_SELECT control_b /* Register A */ +#endif + +#ifdef RTC_CONTROL +#undef RTC_CONTROL +#define RTC_CONTROL control_a /* Register B */ +#endif + +#ifdef RTC_INTR_FLAGS +#undef RTC_INTR_FLAGS +#define RTC_INTR_FLAGS watchdog /* Register C */ +#endif + +#ifdef RTC_VALID +#undef RTC_VALID +#define RTC_VALID interrupts /* Register D */ +#endif + +/* Access routines when RTC accessed directly (like normal memory) */ +u_char +todc_direct_read_val(int addr) +{ + return readb(todc_info->nvram_data + addr); +} + +void +todc_direct_write_val(int addr, unsigned char val) +{ + writeb(val, todc_info->nvram_data + addr); + return; +} + +/* Access routines for accessing m48txx type chips via addr/data regs */ +u_char +todc_m48txx_read_val(int addr) +{ + outb(addr, todc_info->nvram_as0); + outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); + return inb(todc_info->nvram_data); +} + +void +todc_m48txx_write_val(int addr, unsigned char val) +{ + outb(addr, todc_info->nvram_as0); + outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); + outb(val, todc_info->nvram_data); + return; +} + +/* Access routines for accessing mc146818 type chips via addr/data regs */ +u_char +todc_mc146818_read_val(int addr) +{ + outb(addr, todc_info->nvram_as0); + return inb(todc_info->nvram_data); +} + +void +todc_mc146818_write_val(int addr, unsigned char val) +{ + outb(addr, todc_info->nvram_as0); + outb(val, todc_info->nvram_data); + return; +} + +/* + * TODC routines + * + * There is some ugly stuff in that there are assumptions for the mc146818. + * + * Assumptions: + * - todc_info->control_a has the offset as mc146818 Register B reg + * - todc_info->control_b has the offset as mc146818 Register A reg + * - m48txx control reg's write enable or 'W' bit is same as + * mc146818 Register B 'SET' bit (i.e., 0x80) + * + * These assumptions were made to make the code simpler. + */ +long __init +todc_time_init(void) +{ + u_char cntl_b; + static u_char not_initialized = 1; + + /* Make sure clocks are running */ + if (not_initialized) { + cntl_b = ppc_md.nvram_read_val(todc_info->control_b); + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + if ((cntl_b & 0x70) != 0x20) { + printk(KERN_INFO "TODC %s %s\n", + "real-time-clock was stopped.", + "Now starting..."); + cntl_b &= ~0x70; + cntl_b |= 0x20; + } + } + else { /* must be a m48txx type */ + u_char val; + + /* Check & clear STOP bit in control B register */ + if (cntl_b & MK48T59_RTC_CB_STOP) { + printk(KERN_INFO "TODC %s %s\n", + "real-time-clock was stopped.", + "Now starting..."); + cntl_b &= ~MK48T59_RTC_CB_STOP; + } + + /* Make sure READ & WRITE bits are cleared. */ + val = ppc_md.nvram_read_val(todc_info->control_a); + val &= ~(MK48T59_RTC_CA_WRITE | MK48T59_RTC_CA_READ); + ppc_md.nvram_write_val(todc_info->control_a, val); + } + + ppc_md.nvram_write_val(todc_info->control_b, cntl_b); + not_initialized = 0; + } + + return 0; +} + +/* + * There is some ugly stuff in that there are assumptions that for a mc146818, + * the todc_info->control_a has the offset of the mc146818 Register B reg and + * that the register'ss 'SET' bit is the same as the m48txx's write enable + * bit in the control register of the m48txx (i.e., 0x80). + * + * It was done to make the code look simpler. + */ +ulong +todc_get_rtc_time(void) +{ + uint year, mon, day, hour, min, sec; + uint limit, i; + u_char save_control, uip; + + save_control = ppc_md.nvram_read_val(todc_info->control_a); + + if (todc_info->rtc_type != TODC_TYPE_MC146818) { + limit = 1; + ppc_md.nvram_write_val(todc_info->control_a, + (save_control | MK48T59_RTC_CA_READ)); + } + else { + limit = 100000000; + } + + for (i=0; irtc_type == TODC_TYPE_MC146818) { + uip = ppc_md.nvram_read_val(todc_info->RTC_FREQ_SELECT); + } + + sec = ppc_md.nvram_read_val(todc_info->seconds); + min = ppc_md.nvram_read_val(todc_info->minutes); + hour = ppc_md.nvram_read_val(todc_info->hours); + day = ppc_md.nvram_read_val(todc_info->day_of_month); + mon = ppc_md.nvram_read_val(todc_info->month); + year = ppc_md.nvram_read_val(todc_info->year); + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + uip |= ppc_md.nvram_read_val( + todc_info->RTC_FREQ_SELECT); + if ((uip & RTC_UIP) == 0) break; + } + } + + if (todc_info->rtc_type != TODC_TYPE_MC146818) { + save_control &= ~MK48T59_RTC_CA_READ; /* in case it was set */ + ppc_md.nvram_write_val(todc_info->control_a, save_control); + } + + if ((todc_info->rtc_type != TODC_TYPE_MC146818) || + ((save_control & RTC_DM_BINARY) == 0) || + RTC_ALWAYS_BCD) { + + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(day); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + + year = year + 1900; + if (year < 1970) { + year += 100; + } + + return mktime(year, mon, day, hour, min, sec); +} + +int +todc_set_rtc_time(unsigned long nowtime) +{ + struct rtc_time tm; + u_char save_control, save_freq_select; + + to_tm(nowtime, &tm); + + save_control = ppc_md.nvram_read_val(todc_info->control_a); + + /* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */ + ppc_md.nvram_write_val(todc_info->control_a, + (save_control | MK48T59_RTC_CA_WRITE)); + save_control &= ~MK48T59_RTC_CA_WRITE; /* in case it was set */ + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + save_freq_select = + ppc_md.nvram_read_val(todc_info->RTC_FREQ_SELECT); + ppc_md.nvram_write_val(todc_info->RTC_FREQ_SELECT, + save_freq_select | RTC_DIV_RESET2); + } + + + tm.tm_year = (tm.tm_year - 1900) % 100; + + if ((todc_info->rtc_type != TODC_TYPE_MC146818) || + ((save_control & RTC_DM_BINARY) == 0) || + RTC_ALWAYS_BCD) { + + BIN_TO_BCD(tm.tm_sec); + BIN_TO_BCD(tm.tm_min); + BIN_TO_BCD(tm.tm_hour); + BIN_TO_BCD(tm.tm_mon); + BIN_TO_BCD(tm.tm_mday); + BIN_TO_BCD(tm.tm_year); + } + + ppc_md.nvram_write_val(todc_info->seconds, tm.tm_sec); + ppc_md.nvram_write_val(todc_info->minutes, tm.tm_min); + ppc_md.nvram_write_val(todc_info->hours, tm.tm_hour); + ppc_md.nvram_write_val(todc_info->month, tm.tm_mon); + ppc_md.nvram_write_val(todc_info->day_of_month, tm.tm_mday); + ppc_md.nvram_write_val(todc_info->year, tm.tm_year); + + ppc_md.nvram_write_val(todc_info->control_a, save_control); + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + ppc_md.nvram_write_val(todc_info->RTC_FREQ_SELECT, + save_freq_select); + } + + return 0; +} + +/* + * Manipulates read bit to reliably read seconds at a high rate. + */ +unsigned char todc_read_timereg(int addr) +{ + unsigned char save_control, val; + + save_control = ppc_md.nvram_read_val(todc_info->control_a); + if (todc_info->rtc_type != TODC_TYPE_MC146818) { + ppc_md.nvram_write_val(todc_info->control_a, + (save_control | MK48T59_RTC_CA_READ)); + } + val = ppc_md.nvram_read_val(addr); + if (todc_info->rtc_type != TODC_TYPE_MC146818) { + save_control &= ~MK48T59_RTC_CA_READ; /* in case it was set */ + ppc_md.nvram_write_val(todc_info->control_a, save_control); + } + return val; +} + +/* + * This was taken from prep_setup.c + * Use the NVRAM RTC to time a second to calibrate the decrementer. + */ +void __init +todc_calibrate_decr(void) +{ + ulong freq; + ulong tbl, tbu; + long i, loop_count; + u_char sec; + + todc_time_init(); + + /* + * 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. + */ + /* + * Need to make sure the tbl doesn't roll over so if tbu increments + * during this test, we need to do it again. + */ + loop_count = 0; + + sec = todc_read_timereg(todc_info->seconds); + + do { + tbu = get_tbu(); + + for (i = 0 ; i < 10000000 ; i++) {/* may take up to 1 second */ + tbl = get_tbl(); + + if (todc_read_timereg(todc_info->seconds) != sec) { + break; + } + } + + sec = todc_read_timereg(todc_info->seconds); + + for (i = 0 ; i < 10000000 ; i++) { /* Should take 1 second */ + freq = get_tbl(); + + if (todc_read_timereg(todc_info->seconds) != sec) { + break; + } + } + + freq -= tbl; + } while ((get_tbu() != tbu) && (++loop_count < 2)); + + 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); + + return; +} diff -Nru a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c --- a/arch/ppc/kernel/traps.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/kernel/traps.c Sat Jun 16 06:00:24 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.traps.c 1.11 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/kernel/traps.c @@ -82,7 +82,6 @@ spin_lock_irq(&oops_lock); printk("Oops: %s, sig: %ld\n", str, err); show_regs(fp); - print_backtrace((unsigned long *)fp->gpr[1]); spin_unlock_irq(&oops_lock); /* do_exit() should take care of panic'ing from an interrupt * context so we don't handle it here @@ -186,7 +185,6 @@ } #endif show_regs(regs); - print_backtrace((unsigned long *)regs->gpr[1]); panic("System Management Interrupt"); } @@ -334,7 +332,6 @@ debugger(regs); #endif show_regs(regs); - print_backtrace((unsigned long *)regs->gpr[1]); panic("kernel stack overflow"); } @@ -375,12 +372,14 @@ } #endif +#if !defined(CONFIG_TAU) void TAUException(struct pt_regs *regs) { printk("TAU trap at PC: %lx, SR: %lx, vector=%lx\n", regs->nip, regs->msr, regs->trap); } +#endif void __init trap_init(void) { diff -Nru a/arch/ppc/kernel/walnut_setup.c b/arch/ppc/kernel/walnut_setup.c --- a/arch/ppc/kernel/walnut_setup.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/kernel/walnut_setup.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.walnut_setup.c 1.5 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * diff -Nru a/arch/ppc/kernel/walnut_setup.h b/arch/ppc/kernel/walnut_setup.h --- a/arch/ppc/kernel/walnut_setup.h Sat Jun 16 06:00:28 2001 +++ b/arch/ppc/kernel/walnut_setup.h Sat Jun 16 06:00:28 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.walnut_setup.h 1.5 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * diff -Nru a/arch/ppc/kernel/xics.c b/arch/ppc/kernel/xics.c --- a/arch/ppc/kernel/xics.c Sat Jun 16 06:00:28 2001 +++ b/arch/ppc/kernel/xics.c Sat Jun 16 06:00:28 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.xics.c 1.5 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/xics.c diff -Nru a/arch/ppc/kernel/xics.h b/arch/ppc/kernel/xics.h --- a/arch/ppc/kernel/xics.h Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/kernel/xics.h Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.xics.h 1.5 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/kernel/xics.h diff -Nru a/arch/ppc/kernel/zx4500.h b/arch/ppc/kernel/zx4500.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/zx4500.h Sat Jun 16 06:00:30 2001 @@ -0,0 +1,64 @@ +/* * arch/ppc/kernel/zx4500.h + * + * Board setup routines for Znyx ZX4500 cPCI board. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#ifndef __PPC_KERNEL_ZX4500_H_ +#define __PPC_KERNEL_ZX4500_H_ + +/* + * Define the addresses of CPLD registers in CLPD area. + */ +#define ZX4500_CPLD_BOARD_ID 0xff800001 +#define ZX4500_CPLD_REV 0xff800002 +#define ZX4500_CPLD_RESET 0xff800011 +#define ZX4500_CPLD_PHY1 0xff800014 +#define ZX4500_CPLD_PHY2 0xff800015 +#define ZX4500_CPLD_PHY3 0xff800016 +#define ZX4500_CPLD_SYSCTL 0xff800017 +#define ZX4500_CPLD_EXT_FLASH 0xff800018 +#define ZX4500_CPLD_DUAL1 0xff800019 +#define ZX4500_CPLD_DUAL2 0xff80001A +#define ZX4500_CPLD_STATUS 0xff800030 +#define ZX4500_CPLD_STREAM 0xff800032 +#define ZX4500_CPLD_PHY1_LED 0xff800034 +#define ZX4500_CPLD_PHY2_LED 0xff800035 +#define ZX4500_CPLD_PHY3_LED 0xff800036 +#define ZX4500_CPLD_PHY1_LNK 0xff80003C +#define ZX4500_CPLD_PHY2_LNK 0xff80003D +#define ZX4500_CPLD_PHY3_LNK 0xff80003E + +#define ZX4500_CPLD_RESET_SOFT 0x01 /* Soft Reset */ +#define ZX4500_CPLD_RESET_XBUS 0x40 /* Reset entire board */ + +#define ZX4500_CPLD_SYSCTL_PMC 0x01 /* Enable INTA/B/C/D from PMC */ +#define ZX4500_CPLD_SYSCTL_BCM 0x04 /* Enable INTA from BCM */ +#define ZX4500_CPLD_SYSCTL_SINTA 0x08 /* Enable SINTA from 21554 */ +#define ZX4500_CPLD_SYSCTL_WD 0x20 /* Enable Watchdog Timer */ +#define ZX4500_CPLD_SYSCTL_PMC_TRI 0x80 /* Tri-state PMC EREADY */ + +#define ZX4500_CPLD_DUAL2_LED_PULL 0x01 /* Pull LED */ +#define ZX4500_CPLD_DUAL2_LED_EXT_FAULT 0x02 /* External Fault LED */ +#define ZX4500_CPLD_DUAL2_LED_INT_FAULT 0x04 /* Internal Fault LED */ +#define ZX4500_CPLD_DUAL2_LED_OK 0x08 /* OK LED */ +#define ZX4500_CPLD_DUAL2_LED_CLK 0x10 /* CLK LED */ + +/* + * Defines related to boot string stored in flash. + */ +#define ZX4500_BOOT_STRING_ADDR 0xfff7f000 +#define ZX4500_BOOT_STRING_LEN 80 + + +void zx4500_find_bridges(void); + +#endif /* __PPC_KERNEL_ZX4500_H_ */ diff -Nru a/arch/ppc/kernel/zx4500_pci.c b/arch/ppc/kernel/zx4500_pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/zx4500_pci.c Sat Jun 16 06:00:32 2001 @@ -0,0 +1,127 @@ +/* + * arch/ppc/kernel/zx4500_pci.c + * + * PCI setup routines for Znyx ZX4500 cPCI boards. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "pci.h" +#include "pci_auto.h" +#include "mpc10x.h" +#include "zx4500.h" + +/* + * Znyx ZX4500 interrupt routes. + */ +static inline int +zx4500_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) +{ + static char pci_irq_table[][4] = + /* + * PCI IDSEL/INTPIN->INTLINE + * A B C D + */ + { + { 19, 0, 0, 0 }, /* IDSEL 21 - 21554 PCI-cPCI bridge */ + { 18, 0, 0, 0 }, /* IDSEL 22 - BCM5600 INTA */ + { 16, 20, 16, 20 }, /* IDSEL 23 - PPMC Slot */ + }; + + const long min_idsel = 21, max_idsel = 23, irqs_per_slot = 4; + return PCI_IRQ_TABLE_LOOKUP; +} + +void __init +zx4500_board_init(struct pci_controller *hose) +{ + uint val; + u_char sysctl; + + /* + * CPLD Registers are mapped in by BAT 3 in zx4500_setup_arch(). + * + * Turn off all interrupts routed through the CPLD. + * Also, turn off watchdog timer and drive PMC EREADY low. + */ + sysctl = in_8((volatile u_char *)ZX4500_CPLD_SYSCTL); + sysctl &= ~(ZX4500_CPLD_SYSCTL_PMC | + ZX4500_CPLD_SYSCTL_BCM | + ZX4500_CPLD_SYSCTL_SINTA | + ZX4500_CPLD_SYSCTL_WD | + ZX4500_CPLD_SYSCTL_PMC_TRI); + out_8((volatile u_char *)ZX4500_CPLD_SYSCTL, sysctl); + + /* + * Kludge the size that BAR2 of the 21554 asks for + * (i.e., set Upstream I/O or Memory 0 Setup Register). + * Old versions of SROM wants 1 GB which is too large, make it ask + * for 256 MB. + */ + early_read_config_dword(hose, 0, PCI_DEVFN(21,0), 0xc4, &val); + + if (val != 0) { + early_write_config_dword(hose, + 0, + PCI_DEVFN(21,0), + 0xc4, + val | 0xf0000000); + } + + return; +} + +void __init +zx4500_find_bridges(void) +{ + struct pci_controller *hose; + + hose = pcibios_alloc_controller(); + + if (!hose) + return; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + if (mpc10x_bridge_init(hose, + MPC10X_MEM_MAP_B, + MPC10X_MEM_MAP_B, + MPC10X_MAPB_EUMB_BASE) == 0) { + + /* Initialize the board */ + zx4500_board_init(hose); + + /* scan PCI bus */ + hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); + + ppc_md.pcibios_fixup = NULL; + ppc_md.pcibios_fixup_bus = NULL; + ppc_md.pci_swizzle = common_swizzle; + ppc_md.pci_map_irq = zx4500_map_irq; + } + else { + if (ppc_md.progress) + ppc_md.progress("Bridge init failed", 0x100); + printk("Host bridge init failed\n"); + } + + return; +} diff -Nru a/arch/ppc/kernel/zx4500_setup.c b/arch/ppc/kernel/zx4500_setup.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/zx4500_setup.c Sat Jun 16 06:00:31 2001 @@ -0,0 +1,383 @@ +/* + * arch/ppc/kernel/zx4500_setup.c + * + * Board setup routines for Znyx ZX4500 family of cPCI boards. + * + * Author: Mark A. Greer + * mgreer@mvista.com + * + * Copyright 2000, 2001 MontaVista Software Inc. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +/* + * This file adds support for the Znyx ZX4500 series of cPCI boards. + * These boards have an 8240, UART on the processor bus, a PPMC slot (for now + * the card in this slot can _not_ be a monarch), Broadcom BCM5600, and an + * Intel 21554 bridge. + * + * Currently, this port assumes that the 8240 is the master and performs PCI + * arbitration, etc. It is also assumed that the 8240 is wired to come up + * using memory MAP B (CHRP map). + * + * Note: This board port will not work properly as it is. You must apply the + * patch that is at ftp://ftp.mvista.com/pub/Area51/zx4500/zx_patch_2_5 + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pci.h" +#include "pci_auto.h" +#include "local_irq.h" +#include "open_pic.h" +#include "mpc10x.h" +#include "zx4500.h" + +#error "Apply patch: ftp://ftp.mvista.com/pub/Area51/zx4500/zx_patch_2_5" + +static u_char zx4500_openpic_initsenses[] __initdata = { + 0, /* 0-15 are not used on an 8240 EPIC */ + 0, /* 1 */ + 0, /* 2 */ + 0, /* 3 */ + 0, /* 4 */ + 0, /* 5 */ + 0, /* 6 */ + 0, /* 7 */ + 0, /* 8 */ + 0, /* 9 */ + 0, /* 10 */ + 0, /* 11 */ + 0, /* 12 */ + 0, /* 13 */ + 0, /* 14 */ + 0, /* 15 */ + 1, /* 16: EPIC IRQ 0: Active Low -- PMC #INTA & #INTC */ + 1, /* 17: EPIC IRQ 1: Active Low -- UART */ + 1, /* 18: EPIC IRQ 2: Active Low -- BCM5600 #INTA */ + 1, /* 19: EPIC IRQ 3: Active Low -- 21554 #SINTA */ + 1, /* 20: EPIC IRQ 4: Active Low -- PMC #INTB & #INTD */ +}; + + +extern char cmd_line[]; + +static void __init +zx4500_setup_arch(void) +{ + char boot_string[ZX4500_BOOT_STRING_LEN + 1]; + char *boot_arg; + extern char cmd_line[]; + + + loops_per_jiffy = 50000000 / HZ; + +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) + ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); + else +#endif +#if defined(CONFIG_ROOT_NFS) + ROOT_DEV = to_kdev_t(0x00FF); /* /dev/nfs pseudo device */ +#else + ROOT_DEV = to_kdev_t(0x0801); /* /dev/sda1 SCSI disk */ +#endif + + /* Get boot string from flash */ + strncpy(boot_string, + (char *)ZX4500_BOOT_STRING_ADDR, + ZX4500_BOOT_STRING_LEN); + boot_string[ZX4500_BOOT_STRING_LEN] = '\0'; + + /* Can be delimited by 0xff */ + boot_arg = strchr(boot_string, 0xff); + + if (boot_arg != NULL) { + *boot_arg = '\0'; + } + + /* First 3 chars must be 'dev'. If not, ignore. */ + if (!strncmp(boot_string, "dev", 3)) { + /* skip 'dev?' and any blanks after it */ + boot_arg = strchr(boot_string, ' '); + + if (boot_arg != NULL) { + while (*boot_arg == ' ') boot_arg++; + strcat(cmd_line, " "); + strcat(cmd_line, boot_arg); + } + } + + /* nothing but serial consoles... */ + printk("Boot arguments: %s\n", cmd_line); + printk("Znyx ZX4500 Series High Performance Switch\n"); + printk("ZX4500 port (C) 2000, 2001 MontaVista Software, Inc. (source@mvista.com)\n"); + + /* Lookup PCI host bridge */ + zx4500_find_bridges(); + + printk("ZX4500 Board ID: 0x%x, Revision #: 0x%x\n", + in_8((volatile u_char *)ZX4500_CPLD_BOARD_ID), + in_8((volatile u_char *)ZX4500_CPLD_REV)); + + return; +} + +static ulong __init +zx4500_find_end_of_memory(void) +{ + return mpc10x_get_mem_size(MPC10X_MEM_MAP_B); +} + +/* + * Enable interrupts routed thru CPLD to reach the 8240's EPIC. + * Need to enable all 4 PMC intrs, BCM INTA, and 21554 SINTA to 8240. + * UART intrs routed directly to 8240 (not thru CPLD). + */ +static void __init +zx4500_enable_cpld_intrs(void) +{ + u_char sysctl; + + sysctl = in_8((volatile u_char *)ZX4500_CPLD_SYSCTL); + sysctl |= (ZX4500_CPLD_SYSCTL_PMC | + ZX4500_CPLD_SYSCTL_BCM | + ZX4500_CPLD_SYSCTL_SINTA); + out_8((volatile u_char *)ZX4500_CPLD_SYSCTL, sysctl); + + return; +} + +static void __init +zx4500_init_IRQ(void) +{ + OpenPIC_InitSenses = zx4500_openpic_initsenses; + OpenPIC_NumInitSenses = sizeof(zx4500_openpic_initsenses); + + openpic_init(1, 0, NULL, -1); + + zx4500_enable_cpld_intrs(); /* Allow CPLD to route intrs to 8240 */ + + return; +} + +static void +zx4500_restart(char *cmd) +{ + __cli(); + + out_8((volatile u_char *)ZX4500_CPLD_RESET, ZX4500_CPLD_RESET_XBUS); + for (;;); + + panic("Restart failed.\n"); + /* NOTREACHED */ +} + +static void +zx4500_power_off(void) +{ + __cli(); + for(;;); /* No way to shut power off with software */ + /* NOTREACHED */ +} + +static void +zx4500_halt(void) +{ + zx4500_power_off(); + /* NOTREACHED */ +} + +static int +zx4500_get_bus_speed(void) +{ + int bus_speed; + + bus_speed = 100000000; + + return bus_speed; +} + +static int +zx4500_get_cpuinfo(char *buffer) +{ + int len; + uint pvid; + + pvid = _get_PVR(); + + len = sprintf( buffer, "vendor\t\t: Znyx\n"); + + len += sprintf( buffer+len, "machine\t\t: ZX4500\n"); + + len += sprintf( buffer+len, "processor\t: PVID: 0x%x, vendor: %s\n", + pvid, (pvid & (1<<15) ? "IBM" : "Motorola")); + +#if 0 + len += sprintf( buffer+len, "cpu speed\t: %dMhz\n", + zx4500_get_cpu_speed()/1000000); +#endif + + len += sprintf( buffer+len, "bus speed\t: %dMhz\n", + zx4500_get_bus_speed()/1000000); + + return len; +} + +static void __init +zx4500_calibrate_decr(void) +{ + ulong freq; + + freq = zx4500_get_bus_speed() / 4; + + 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); + + return; +} + +/* + * Set BAT 3 to map 0xf0000000 to end of physical memory space 1-1. + */ +static __inline__ void +zx4500_set_bat(void) +{ + unsigned long bat3u, bat3l; + static int mapping_set = 0; + + if (!mapping_set) { + + __asm__ __volatile__( + " lis %0,0xf800\n \ + ori %1,%0,0x002a\n \ + ori %0,%0,0x0ffe\n \ + mtspr 0x21e,%0\n \ + mtspr 0x21f,%1\n \ + isync\n \ + sync " + :: "r" (bat3u), "r" (bat3l)); + + mapping_set = 1; + } + + return; +} + +#ifdef CONFIG_SERIAL_TEXT_DEBUG +#include +#include +#include + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in */ +}; + +void +zx4500_progress(char *s, unsigned short hex) +{ + volatile char c; + volatile unsigned long com_port; + u16 shift; + + com_port = rs_table[0].port; + shift = rs_table[0].iomem_reg_shift; + + while ((c = *s++) != 0) { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = c; + + if (c == '\n') { + while ((*((volatile unsigned char *)com_port + + (UART_LSR << shift)) & UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = '\r'; + } + } +} +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + +void __init +zx4500_init(unsigned long r3, unsigned long r4, unsigned long r5, + unsigned long r6, unsigned long r7) +{ +#ifdef CONFIG_BLK_DEV_INITRD + if (r4) + { + initrd_start = r4 + KERNELBASE; + initrd_end = r5 + KERNELBASE; + } +#endif + + /* take care of cmd line */ + if (r6 && (((char *) r6) != '\0')) { + *(char *)(r7+KERNELBASE) = 0; + strcpy(cmd_line, (char *)(r6+KERNELBASE)); + } + + /* Map in board registers, etc. */ + zx4500_set_bat(); + + isa_io_base = MPC10X_MAPB_ISA_IO_BASE; + isa_mem_base = MPC10X_MAPB_ISA_MEM_BASE; + pci_dram_offset = MPC10X_MAPB_DRAM_OFFSET; + + ppc_md.setup_arch = zx4500_setup_arch; + ppc_md.setup_residual = NULL; + ppc_md.get_cpuinfo = zx4500_get_cpuinfo; + ppc_md.irq_cannonicalize = NULL; + ppc_md.init_IRQ = zx4500_init_IRQ; + ppc_md.get_irq = openpic_get_irq; + ppc_md.post_irq = NULL; + ppc_md.init = NULL; + + ppc_md.restart = zx4500_restart; + ppc_md.power_off = zx4500_power_off; + ppc_md.halt = zx4500_halt; + + ppc_md.find_end_of_memory = zx4500_find_end_of_memory; + + ppc_md.calibrate_decr = zx4500_calibrate_decr; + + ppc_md.heartbeat = NULL; + ppc_md.heartbeat_reset = 0; + ppc_md.heartbeat_count = 0; + +#ifdef CONFIG_SERIAL_TEXT_DEBUG + ppc_md.progress = zx4500_progress; +#else /* !CONFIG_SERIAL_TEXT_DEBUG */ + ppc_md.progress = NULL; +#endif /* CONFIG_SERIAL_TEXT_DEBUG */ + + return; +} diff -Nru a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile --- a/arch/ppc/lib/Makefile Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/lib/Makefile Sat Jun 16 06:00:20 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.7 05/17/01 18:14:22 cort +# BK Id: %F% %I% %G% %U% %#% # # # Makefile for ppc-specific library files.. diff -Nru a/arch/ppc/lib/checksum.S b/arch/ppc/lib/checksum.S --- a/arch/ppc/lib/checksum.S Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/lib/checksum.S Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.checksum.S 1.5 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * This file contains assembly-language implementations diff -Nru a/arch/ppc/lib/locks.c b/arch/ppc/lib/locks.c --- a/arch/ppc/lib/locks.c Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/lib/locks.c Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.locks.c 1.8 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Locks for smp ppc @@ -16,18 +16,20 @@ #include #include -#define DEBUG_LOCKS 1 - +#undef DEBUG_LOCKS #undef INIT_STUCK #define INIT_STUCK 200000000 /*0xffffffff*/ +#ifdef SPINLOCK_DEBUG + void _spin_lock(spinlock_t *lock) { - int cpu = smp_processor_id(); #ifdef DEBUG_LOCKS + int cpu = smp_processor_id(); unsigned int stuck = INIT_STUCK; #endif /* DEBUG_LOCKS */ while (__spin_trylock(&lock->lock)) { + while((unsigned volatile long)lock->lock != 0) { #ifdef DEBUG_LOCKS if(!--stuck) { printk("_spin_lock(%p) CPU#%d NIP %p" @@ -39,22 +41,25 @@ /*xchg_u32((void *)&lock->lock,0);*/ } #endif /* DEBUG_LOCKS */ + } } +#ifdef DEBUG_LOCKS lock->owner_pc = (unsigned long)__builtin_return_address(0); lock->owner_cpu = cpu; +#endif } int spin_trylock(spinlock_t *lock) { if (__spin_trylock(&lock->lock)) return 0; +#ifdef DEBUG_LOCKS lock->owner_cpu = smp_processor_id(); lock->owner_pc = (unsigned long)__builtin_return_address(0); +#endif return 1; } - - void _spin_unlock(spinlock_t *lp) { #ifdef DEBUG_LOCKS @@ -66,13 +71,14 @@ printk("_spin_unlock(%p): cpu %d trying clear of cpu %d pc %lx val %lx\n", lp, smp_processor_id(), (int)lp->owner_cpu, lp->owner_pc,lp->lock); -#endif /* DEBUG_LOCKS */ lp->owner_pc = lp->owner_cpu = 0; +#endif /* DEBUG_LOCKS */ wmb(); lp->lock = 0; - wmb(); } +#endif + /* * Just like x86, implement read-write locks as a 32-bit counter * with the high bit (sign) being the "write" bit. @@ -87,7 +93,6 @@ again: /* get our read lock in there */ - wmb(); atomic_inc((atomic_t *) &(rw)->lock); if ( (signed long)((rw)->lock) < 0) /* someone has a write lock */ { @@ -120,7 +125,6 @@ #endif /* DEBUG_LOCKS */ wmb(); atomic_dec((atomic_t *) &(rw)->lock); - wmb(); } void _write_lock(rwlock_t *rw) @@ -131,7 +135,6 @@ #endif /* DEBUG_LOCKS */ again: - wmb(); if ( test_and_set_bit(31,&(rw)->lock) ) /* someone has a write lock */ { while ( (rw)->lock & (1<<31) ) /* wait for write lock */ @@ -180,71 +183,4 @@ #endif /* DEBUG_LOCKS */ wmb(); clear_bit(31,&(rw)->lock); - wmb(); -} - -void __lock_kernel(struct task_struct *task) -{ -#ifdef DEBUG_LOCKS - unsigned long stuck = INIT_STUCK; - - if ( (signed long)(task->lock_depth) < 0 ) - { - printk("__lock_kernel(): %s/%d (nip %08lX) lock depth %x\n", - task->comm,task->pid,task->thread.regs->nip, - task->lock_depth); - } -#endif /* DEBUG_LOCKS */ - - if (atomic_inc_return((atomic_t *) &task->lock_depth) != 1) - return; - /* mine! */ - while (__spin_trylock(&klock_info.kernel_flag)) { -#ifdef DEBUG_LOCKS - if(!--stuck) { - printk("_lock_kernel() CPU#%d NIP %p\n", - smp_processor_id(), - __builtin_return_address(0)); - stuck = INIT_STUCK; - } -#endif /* DEBUG_LOCKS */ - } - - klock_info.akp = smp_processor_id(); - /* my kernel mode! mine!!! */ -} - -void __unlock_kernel(struct task_struct *task) -{ -#ifdef DEBUG_LOCKS - if ((task->lock_depth == 0) || (klock_info.kernel_flag != KLOCK_HELD)) - { - printk("__unlock_kernel(): %s/%d (nip %08lX) " - "lock depth %x flags %lx\n", - task->comm,task->pid,task->thread.regs->nip, - task->lock_depth, klock_info.kernel_flag); - klock_info.akp = NO_PROC_ID; - klock_info.kernel_flag = 0; - return; - } -#endif /* DEBUG_LOCKS */ - if (atomic_dec_and_test((atomic_t *) &task->lock_depth)) - { - wmb(); - klock_info.akp = NO_PROC_ID; - wmb(); - klock_info.kernel_flag = KLOCK_CLEAR; - wmb(); - } -} - -void reacquire_kernel_lock(struct task_struct *task, int cpu,int depth) -{ - if (depth) - { - __cli(); - __lock_kernel(task); - task->lock_depth = depth; - __sti(); - } } diff -Nru a/arch/ppc/lib/strcase.c b/arch/ppc/lib/strcase.c --- a/arch/ppc/lib/strcase.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/lib/strcase.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.strcase.c 1.5 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include diff -Nru a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S --- a/arch/ppc/lib/string.S Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/lib/string.S Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.string.S 1.5 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * String handling functions for PowerPC. diff -Nru a/arch/ppc/math-emu/Makefile b/arch/ppc/math-emu/Makefile --- a/arch/ppc/math-emu/Makefile Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/math-emu/Makefile Sat Jun 16 06:00:17 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:22 cort +# BK Id: %F% %I% %G% %U% %#% # # # diff -Nru a/arch/ppc/math-emu/double.h b/arch/ppc/math-emu/double.h --- a/arch/ppc/math-emu/double.h Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/math-emu/double.h Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.double.h 1.5 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Definitions for IEEE Double Precision diff -Nru a/arch/ppc/math-emu/fabs.c b/arch/ppc/math-emu/fabs.c --- a/arch/ppc/math-emu/fabs.c Sat Jun 16 06:00:26 2001 +++ b/arch/ppc/math-emu/fabs.c Sat Jun 16 06:00:26 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fabs.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fadd.c b/arch/ppc/math-emu/fadd.c --- a/arch/ppc/math-emu/fadd.c Sat Jun 16 06:00:28 2001 +++ b/arch/ppc/math-emu/fadd.c Sat Jun 16 06:00:28 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fadd.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fadds.c b/arch/ppc/math-emu/fadds.c --- a/arch/ppc/math-emu/fadds.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/math-emu/fadds.c Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fadds.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fcmpo.c b/arch/ppc/math-emu/fcmpo.c --- a/arch/ppc/math-emu/fcmpo.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/math-emu/fcmpo.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fcmpo.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fcmpu.c b/arch/ppc/math-emu/fcmpu.c --- a/arch/ppc/math-emu/fcmpu.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/math-emu/fcmpu.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fcmpu.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fctiw.c b/arch/ppc/math-emu/fctiw.c --- a/arch/ppc/math-emu/fctiw.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/math-emu/fctiw.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fctiw.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fctiwz.c b/arch/ppc/math-emu/fctiwz.c --- a/arch/ppc/math-emu/fctiwz.c Sat Jun 16 06:00:28 2001 +++ b/arch/ppc/math-emu/fctiwz.c Sat Jun 16 06:00:28 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fctiwz.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fdiv.c b/arch/ppc/math-emu/fdiv.c --- a/arch/ppc/math-emu/fdiv.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/math-emu/fdiv.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fdiv.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fdivs.c b/arch/ppc/math-emu/fdivs.c --- a/arch/ppc/math-emu/fdivs.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/math-emu/fdivs.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fdivs.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fmadd.c b/arch/ppc/math-emu/fmadd.c --- a/arch/ppc/math-emu/fmadd.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/math-emu/fmadd.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fmadd.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fmadds.c b/arch/ppc/math-emu/fmadds.c --- a/arch/ppc/math-emu/fmadds.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/math-emu/fmadds.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fmadds.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fmr.c b/arch/ppc/math-emu/fmr.c --- a/arch/ppc/math-emu/fmr.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/math-emu/fmr.c Sat Jun 16 06:00:24 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fmr.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fmsub.c b/arch/ppc/math-emu/fmsub.c --- a/arch/ppc/math-emu/fmsub.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/math-emu/fmsub.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fmsub.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fmsubs.c b/arch/ppc/math-emu/fmsubs.c --- a/arch/ppc/math-emu/fmsubs.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/math-emu/fmsubs.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fmsubs.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fmul.c b/arch/ppc/math-emu/fmul.c --- a/arch/ppc/math-emu/fmul.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/math-emu/fmul.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fmul.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fmuls.c b/arch/ppc/math-emu/fmuls.c --- a/arch/ppc/math-emu/fmuls.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/math-emu/fmuls.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fmuls.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fnabs.c b/arch/ppc/math-emu/fnabs.c --- a/arch/ppc/math-emu/fnabs.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/math-emu/fnabs.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fnabs.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fneg.c b/arch/ppc/math-emu/fneg.c --- a/arch/ppc/math-emu/fneg.c Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/math-emu/fneg.c Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fneg.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fnmadd.c b/arch/ppc/math-emu/fnmadd.c --- a/arch/ppc/math-emu/fnmadd.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/math-emu/fnmadd.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fnmadd.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fnmadds.c b/arch/ppc/math-emu/fnmadds.c --- a/arch/ppc/math-emu/fnmadds.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/math-emu/fnmadds.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fnmadds.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fnmsub.c b/arch/ppc/math-emu/fnmsub.c --- a/arch/ppc/math-emu/fnmsub.c Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/math-emu/fnmsub.c Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fnmsub.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fnmsubs.c b/arch/ppc/math-emu/fnmsubs.c --- a/arch/ppc/math-emu/fnmsubs.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/math-emu/fnmsubs.c Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fnmsubs.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fres.c b/arch/ppc/math-emu/fres.c --- a/arch/ppc/math-emu/fres.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/math-emu/fres.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fres.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/frsp.c b/arch/ppc/math-emu/frsp.c --- a/arch/ppc/math-emu/frsp.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/math-emu/frsp.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.frsp.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/frsqrte.c b/arch/ppc/math-emu/frsqrte.c --- a/arch/ppc/math-emu/frsqrte.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/math-emu/frsqrte.c Sat Jun 16 06:00:24 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.frsqrte.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fsel.c b/arch/ppc/math-emu/fsel.c --- a/arch/ppc/math-emu/fsel.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/math-emu/fsel.c Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fsel.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fsqrt.c b/arch/ppc/math-emu/fsqrt.c --- a/arch/ppc/math-emu/fsqrt.c Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/math-emu/fsqrt.c Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fsqrt.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fsqrts.c b/arch/ppc/math-emu/fsqrts.c --- a/arch/ppc/math-emu/fsqrts.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/math-emu/fsqrts.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fsqrts.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fsub.c b/arch/ppc/math-emu/fsub.c --- a/arch/ppc/math-emu/fsub.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/math-emu/fsub.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fsub.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/fsubs.c b/arch/ppc/math-emu/fsubs.c --- a/arch/ppc/math-emu/fsubs.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/math-emu/fsubs.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fsubs.c 1.6 05/17/01 18:14:22 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/lfd.c b/arch/ppc/math-emu/lfd.c --- a/arch/ppc/math-emu/lfd.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/math-emu/lfd.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.lfd.c 1.6 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/lfs.c b/arch/ppc/math-emu/lfs.c --- a/arch/ppc/math-emu/lfs.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/math-emu/lfs.c Sat Jun 16 06:00:24 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.lfs.c 1.6 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/math.c b/arch/ppc/math-emu/math.c --- a/arch/ppc/math-emu/math.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/math-emu/math.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.math.c 1.6 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/math-emu/math.c diff -Nru a/arch/ppc/math-emu/mcrfs.c b/arch/ppc/math-emu/mcrfs.c --- a/arch/ppc/math-emu/mcrfs.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/math-emu/mcrfs.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mcrfs.c 1.6 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/mffs.c b/arch/ppc/math-emu/mffs.c --- a/arch/ppc/math-emu/mffs.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/math-emu/mffs.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mffs.c 1.6 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/mtfsb0.c b/arch/ppc/math-emu/mtfsb0.c --- a/arch/ppc/math-emu/mtfsb0.c Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/math-emu/mtfsb0.c Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mtfsb0.c 1.6 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/mtfsb1.c b/arch/ppc/math-emu/mtfsb1.c --- a/arch/ppc/math-emu/mtfsb1.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/math-emu/mtfsb1.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mtfsb1.c 1.6 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/mtfsf.c b/arch/ppc/math-emu/mtfsf.c --- a/arch/ppc/math-emu/mtfsf.c Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/math-emu/mtfsf.c Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mtfsf.c 1.6 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/mtfsfi.c b/arch/ppc/math-emu/mtfsfi.c --- a/arch/ppc/math-emu/mtfsfi.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/math-emu/mtfsfi.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mtfsfi.c 1.6 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/op-1.h b/arch/ppc/math-emu/op-1.h --- a/arch/ppc/math-emu/op-1.h Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/math-emu/op-1.h Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.op-1.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Basic one-word fraction declaration and manipulation. diff -Nru a/arch/ppc/math-emu/op-2.h b/arch/ppc/math-emu/op-2.h --- a/arch/ppc/math-emu/op-2.h Sat Jun 16 06:00:26 2001 +++ b/arch/ppc/math-emu/op-2.h Sat Jun 16 06:00:26 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.op-2.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Basic two-word fraction declaration and manipulation. diff -Nru a/arch/ppc/math-emu/op-4.h b/arch/ppc/math-emu/op-4.h --- a/arch/ppc/math-emu/op-4.h Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/math-emu/op-4.h Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.op-4.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Basic four-word fraction declaration and manipulation. diff -Nru a/arch/ppc/math-emu/op-common.h b/arch/ppc/math-emu/op-common.h --- a/arch/ppc/math-emu/op-common.h Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/math-emu/op-common.h Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.op-common.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #define _FP_DECL(wc, X) \ diff -Nru a/arch/ppc/math-emu/sfp-machine.h b/arch/ppc/math-emu/sfp-machine.h --- a/arch/ppc/math-emu/sfp-machine.h Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/math-emu/sfp-machine.h Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.sfp-machine.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* Machine-dependent software floating-point definitions. PPC version. Copyright (C) 1997 Free Software Foundation, Inc. diff -Nru a/arch/ppc/math-emu/single.h b/arch/ppc/math-emu/single.h --- a/arch/ppc/math-emu/single.h Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/math-emu/single.h Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.single.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Definitions for IEEE Single Precision diff -Nru a/arch/ppc/math-emu/soft-fp.h b/arch/ppc/math-emu/soft-fp.h --- a/arch/ppc/math-emu/soft-fp.h Sat Jun 16 06:00:23 2001 +++ b/arch/ppc/math-emu/soft-fp.h Sat Jun 16 06:00:23 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.soft-fp.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #ifndef SOFT_FP_H #define SOFT_FP_H diff -Nru a/arch/ppc/math-emu/stfd.c b/arch/ppc/math-emu/stfd.c --- a/arch/ppc/math-emu/stfd.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/math-emu/stfd.c Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.stfd.c 1.6 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/stfiwx.c b/arch/ppc/math-emu/stfiwx.c --- a/arch/ppc/math-emu/stfiwx.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/math-emu/stfiwx.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.stfiwx.c 1.6 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/stfs.c b/arch/ppc/math-emu/stfs.c --- a/arch/ppc/math-emu/stfs.c Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/math-emu/stfs.c Sat Jun 16 06:00:24 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.stfs.c 1.6 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include #include diff -Nru a/arch/ppc/math-emu/types.c b/arch/ppc/math-emu/types.c --- a/arch/ppc/math-emu/types.c Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/math-emu/types.c Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.types.c 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ #include "soft-fp.h" diff -Nru a/arch/ppc/math-emu/udivmodti4.c b/arch/ppc/math-emu/udivmodti4.c --- a/arch/ppc/math-emu/udivmodti4.c Sat Jun 16 06:00:27 2001 +++ b/arch/ppc/math-emu/udivmodti4.c Sat Jun 16 06:00:27 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.udivmodti4.c 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny. */ diff -Nru a/arch/ppc/mm/4xx_tlb.c b/arch/ppc/mm/4xx_tlb.c --- a/arch/ppc/mm/4xx_tlb.c Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/mm/4xx_tlb.c Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.4xx_tlb.c 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * diff -Nru a/arch/ppc/mm/4xx_tlb.h b/arch/ppc/mm/4xx_tlb.h --- a/arch/ppc/mm/4xx_tlb.h Sat Jun 16 06:00:18 2001 +++ b/arch/ppc/mm/4xx_tlb.h Sat Jun 16 06:00:18 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.4xx_tlb.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * diff -Nru a/arch/ppc/mm/Makefile b/arch/ppc/mm/Makefile --- a/arch/ppc/mm/Makefile Sat Jun 16 06:00:27 2001 +++ b/arch/ppc/mm/Makefile Sat Jun 16 06:00:27 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:23 cort +# BK Id: %F% %I% %G% %U% %#% # # # Makefile for the linux ppc-specific parts of the memory manager. @@ -9,8 +9,20 @@ # # Note 2! The CFLAGS definition is now in the main makefile... +USE_STANDARD_AS_RULE := true + +ifdef CONFIG_PPC64BRIDGE +EXTRA_AFLAGS := -Wa,-mppc64bridge +endif + O_TARGET := mm.o obj-y := fault.o init.o mem_pieces.o extable.o + +ifneq ($(CONFIG_8xx),y) +ifneq ($(CONFIG_4xx),y) +obj-y += hashtable.o +endif +endif obj-$(CONFIG_4xx) += 4xx_tlb.o diff -Nru a/arch/ppc/mm/extable.c b/arch/ppc/mm/extable.c --- a/arch/ppc/mm/extable.c Sat Jun 16 06:00:26 2001 +++ b/arch/ppc/mm/extable.c Sat Jun 16 06:00:26 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.extable.c 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * linux/arch/ppc/mm/extable.c diff -Nru a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c --- a/arch/ppc/mm/fault.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/mm/fault.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.fault.c 1.10 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * arch/ppc/mm/fault.c @@ -44,11 +44,12 @@ int debugger_kernel_faults = 1; #endif -unsigned long htab_reloads = 0; /* updated by head.S:hash_page() */ -unsigned long htab_evicts = 0; /* updated by head.S:hash_page() */ -unsigned long pte_misses = 0; /* updated by do_page_fault() */ -unsigned long pte_errors = 0; /* updated by do_page_fault() */ -unsigned int probingmem = 0; +unsigned long htab_reloads; /* updated by hashtable.S:hash_page() */ +unsigned long htab_evicts; /* updated by hashtable.S:hash_page() */ +unsigned long htab_preloads; /* updated by hashtable.S:add_hash_page() */ +unsigned long pte_misses; /* updated by do_page_fault() */ +unsigned long pte_errors; /* updated by do_page_fault() */ +unsigned int probingmem; extern void die_if_kernel(char *, struct pt_regs *, long); void bad_page_fault(struct pt_regs *, unsigned long, int sig); diff -Nru a/arch/ppc/mm/hashtable.S b/arch/ppc/mm/hashtable.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/mm/hashtable.S Sat Jun 16 06:00:31 2001 @@ -0,0 +1,631 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * arch/ppc/kernel/hashtable.S + * + * $Id: hashtable.S,v 1.6 1999/10/08 01:56:15 paulus Exp $ + * + * PowerPC version + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP + * Copyright (C) 1996 Cort Dougan + * Adapted for Power Macintosh by Paul Mackerras. + * Low-level exception handlers and MMU support + * rewritten by Paul Mackerras. + * Copyright (C) 1996 Paul Mackerras. + * + * This file contains low-level assembler routines for managing + * the PowerPC MMU hash table. (PPC 8xx processors don't use a + * hash table, so this file is not used on them.) + * + * 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 +#include +#include "../kernel/ppc_asm.h" +#include +#include +#include +#include + +#ifdef CONFIG_SMP + .comm hash_table_lock,4 +#endif /* CONFIG_SMP */ + +/* + * Load a PTE into the hash table, if possible. + * The address is in r4, and r3 contains an access flag: + * _PAGE_RW (0x400) if a write. + * r23 contains the SRR1 value, from which we use the MSR_PR bit. + * SPRG3 contains the physical address of the current task's thread. + * + * Returns to the caller if the access is illegal or there is no + * mapping for the address. Otherwise it places an appropriate PTE + * in the hash table and returns from the exception. + * Uses r0, r2 - r7, ctr, lr. + */ + .text + .globl hash_page +hash_page: +#ifdef CONFIG_PPC64BRIDGE + mfmsr r0 + clrldi r0,r0,1 /* make sure it's in 32-bit mode */ + MTMSRD(r0) + isync +#endif + tophys(r7,0) /* gets -KERNELBASE into r7 */ +#ifdef CONFIG_SMP + addis r2,r7,hash_table_lock@h + ori r2,r2,hash_table_lock@l + mfspr r5,SPRG3 + lwz r0,PROCESSOR-THREAD(r5) + oris r0,r0,0x0fff + b 10f +11: lwz r6,0(r2) + cmpwi 0,r6,0 + bne 11b +10: lwarx r6,0,r2 + cmpwi 0,r6,0 + bne- 11b + stwcx. r0,0,r2 + bne- 10b + isync +#endif + /* Get PTE (linux-style) and check access */ + lis r0,KERNELBASE@h /* check if kernel address */ + cmplw 0,r4,r0 + mfspr r2,SPRG3 /* current task's THREAD (phys) */ + ori r3,r3,_PAGE_USER|_PAGE_PRESENT /* test low addresses as user */ + lwz r5,PGDIR(r2) /* virt page-table root */ + blt+ 112f /* assume user more likely */ + lis r5,swapper_pg_dir@ha /* if kernel address, use */ + addi r5,r5,swapper_pg_dir@l /* kernel page table */ + rlwimi r3,r23,32-12,29,29 /* MSR_PR -> _PAGE_USER */ +112: add r5,r5,r7 /* convert to phys addr */ + rlwimi r5,r4,12,20,29 /* insert top 10 bits of address */ + lwz r5,0(r5) /* get pmd entry */ + rlwinm. r5,r5,0,0,19 /* extract address of pte page */ +#ifdef CONFIG_SMP + beq- hash_page_out /* return if no mapping */ +#else + /* XXX it seems like the 601 will give a machine fault on the + rfi if its alignment is wrong (bottom 4 bits of address are + 8 or 0xc) and we have had a not-taken conditional branch + to the address following the rfi. */ + beqlr- +#endif + add r2,r5,r7 /* convert to phys addr */ + rlwimi r2,r4,22,20,29 /* insert next 10 bits of address */ + rlwinm r0,r3,32-3,24,24 /* _PAGE_RW access -> _PAGE_DIRTY */ + ori r0,r0,_PAGE_ACCESSED|_PAGE_HASHPTE + + /* + * Update the linux PTE atomically. We do the lwarx up-front + * because almost always, there won't be a permission violation + * and there won't already be an HPTE, and thus we will have + * to update the PTE to set _PAGE_HASHPTE. -- paulus. + */ +retry: + lwarx r6,0,r2 /* get linux-style pte */ + andc. r5,r3,r6 /* check access & ~permission */ +#ifdef CONFIG_SMP + bne- hash_page_out /* return if access not permitted */ +#else + bnelr- +#endif + or r5,r0,r6 /* set accessed/dirty bits */ + stwcx. r5,0,r2 /* attempt to update PTE */ + bne- retry /* retry if someone got there first */ + + mfsrin r3,r4 /* get segment reg for segment */ + mr r2,r8 /* we have saved r2 but not r8 */ + bl create_hpte /* add the hash table entry */ + mr r8,r2 + +/* + * htab_reloads counts the number of times we have to fault an + * HPTE into the hash table. This should only happen after a + * fork (because fork does a flush_tlb_mm) or a vmalloc or ioremap. + * Where a page is faulted into a process's address space, + * update_mmu_cache gets called to put the HPTE into the hash table + * and those are counted as preloads rather than reloads. + */ + addis r2,r7,htab_reloads@ha + lwz r3,htab_reloads@l(r2) + addi r3,r3,1 + stw r3,htab_reloads@l(r2) + +#ifdef CONFIG_SMP + eieio + addis r2,r7,hash_table_lock@ha + li r0,0 + stw r0,hash_table_lock@l(r2) +#endif + + /* Return from the exception */ + lwz r3,_CCR(r21) + lwz r4,_LINK(r21) + lwz r5,_CTR(r21) + mtcrf 0xff,r3 + mtlr r4 + mtctr r5 + lwz r0,GPR0(r21) + lwz r1,GPR1(r21) + lwz r2,GPR2(r21) + lwz r3,GPR3(r21) + lwz r4,GPR4(r21) + lwz r5,GPR5(r21) + lwz r6,GPR6(r21) + lwz r7,GPR7(r21) + /* we haven't used xer */ + mtspr SRR1,r23 + mtspr SRR0,r22 + lwz r20,GPR20(r21) + lwz r22,GPR22(r21) + lwz r23,GPR23(r21) + lwz r21,GPR21(r21) + RFI + +#ifdef CONFIG_SMP +hash_page_out: + eieio + addis r2,r7,hash_table_lock@ha + li r0,0 + stw r0,hash_table_lock@l(r2) + blr +#endif /* CONFIG_SMP */ + +/* + * Add an entry for a particular page to the hash table. + * + * add_hash_page(unsigned context, unsigned long va, pte_t pte) + * + * We assume any necessary modifications to the pte (e.g. setting + * the accessed bit) have already been done and that there is actually + * a hash table in use (i.e. we're not on a 603). + */ +_GLOBAL(add_hash_page) + mflr r0 + stw r0,4(r1) + + /* Convert context and va to VSID */ + mulli r3,r3,897*16 /* multiply context by context skew */ + rlwinm r0,r4,4,28,31 /* get ESID (top 4 bits of va) */ + mulli r0,r0,0x111 /* multiply by ESID skew */ + add r3,r3,r0 /* note create_hpte trims to 24 bits */ + + /* + * We disable interrupts here, even on UP, because we don't + * want to race with hash_page, and because we want the + * _PAGE_HASHPTE bit to be a reliable indication of whether + * the HPTE exists (or at least whether one did once). -- paulus + */ + mfmsr r10 + SYNC + rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ + mtmsr r0 + SYNC + +#ifdef CONFIG_SMP + lis r9,hash_table_lock@h + ori r9,r9,hash_table_lock@l + lwz r8,PROCESSOR(r2) + oris r8,r8,10 +10: lwarx r7,0,r9 + cmpi 0,r7,0 + bne- 11f + stwcx. r8,0,r9 + beq+ 12f +11: lwz r7,0(r9) + cmpi 0,r7,0 + beq 10b + b 11b +12: isync +#endif + + /* + * Fetch the linux pte and test and set _PAGE_HASHPTE atomically. + * If _PAGE_HASHPTE was already set, we don't replace the existing + * HPTE, so we just unlock and return. + */ + mr r7,r5 +1: lwarx r6,0,r7 + andi. r0,r6,_PAGE_HASHPTE + bne 9f /* if HASHPTE already set, done */ + ori r5,r6,_PAGE_ACCESSED|_PAGE_HASHPTE + stwcx. r5,0,r7 + bne- 1b + + li r7,0 /* no address offset needed */ + bl create_hpte + + lis r8,htab_preloads@ha + lwz r3,htab_preloads@l(r8) + addi r3,r3,1 + stw r3,htab_preloads@l(r8) + +9: +#ifdef CONFIG_SMP + eieio + li r0,0 + stw r0,0(r9) /* clear hash_table_lock */ +#endif + + lwz r0,4(r1) + mtlr r0 + + /* reenable interrupts */ + mtmsr r10 + SYNC + blr + +/* + * This routine adds a hardware PTE to the hash table. + * It is designed to be called with the MMU either on or off. + * r3 contains the VSID, r4 contains the virtual address, + * r5 contains the linux PTE, r6 contains the old value of the + * linux PTE (before setting _PAGE_HASHPTE) and r7 contains the + * offset to be added to addresses (0 if the MMU is on, + * -KERNELBASE if it is off). + * On SMP, the caller should have the hash_table_lock held. + * We assume that the caller has (or will) set the _PAGE_HASHPTE + * bit in the linux PTE in memory. The value passed in r6 should + * be the old linux PTE value; if it doesn't have _PAGE_HASHPTE set + * this routine will skip the search for an existing HPTE. + * This procedure modifies r0, r3 - r6, r8, cr0. + * -- paulus. + * + * For speed, 4 of the instructions get patched once the size and + * physical address of the hash table are known. These definitions + * of Hash_base and Hash_bits below are just an example. + */ +Hash_base = 0xc0180000 +Hash_bits = 12 /* e.g. 256kB hash table */ +Hash_msk = (((1 << Hash_bits) - 1) * 64) + +#ifndef CONFIG_PPC64BRIDGE +/* defines for the PTE format for 32-bit PPCs */ +#define PTE_SIZE 8 +#define PTEG_SIZE 64 +#define LG_PTEG_SIZE 6 +#define LDPTEu lwzu +#define STPTE stw +#define CMPPTE cmpw +#define PTE_H 0x40 +#define PTE_V 0x80000000 +#define TST_V(r) rlwinm. r,r,0,0,0 +#define SET_V(r) oris r,r,PTE_V@h +#define CLR_V(r,t) rlwinm r,r,0,1,31 + +#else +/* defines for the PTE format for 64-bit PPCs */ +#define PTE_SIZE 16 +#define PTEG_SIZE 128 +#define LG_PTEG_SIZE 7 +#define LDPTEu ldu +#define STPTE std +#define CMPPTE cmpd +#define PTE_H 2 +#define PTE_V 1 +#define TST_V(r) andi. r,r,PTE_V +#define SET_V(r) ori r,r,PTE_V +#define CLR_V(r,t) li t,PTE_V; andc r,r,t +#endif /* CONFIG_PPC64BRIDGE */ + +#define HASH_LEFT 31-(LG_PTEG_SIZE+Hash_bits-1) +#define HASH_RIGHT 31-LG_PTEG_SIZE + +_GLOBAL(create_hpte) + /* Convert linux-style PTE (r5) to low word of PPC-style PTE (r8) */ + rlwinm r8,r5,32-10,31,31 /* _PAGE_RW -> PP lsb */ + rlwinm r0,r5,32-7,31,31 /* _PAGE_DIRTY -> PP lsb */ + and r8,r8,r0 /* writable if _RW & _DIRTY */ + rlwimi r5,r5,32-1,30,30 /* _PAGE_USER -> PP msb */ + rlwimi r5,r5,32-2,31,31 /* _PAGE_USER -> PP lsb */ + ori r8,r8,0xe14 /* clear out reserved bits and M */ + andc r8,r5,r8 /* PP = user? (rw&dirty? 2: 3): 0 */ +#ifdef CONFIG_SMP + ori r8,r8,_PAGE_COHERENT /* set M (coherence required) */ +#endif + +#ifdef CONFIG_POWER4 + /* + * XXX hack hack hack - translate 32-bit "physical" addresses + * in the linux page tables to 42-bit real addresses in such + * a fashion that we can get at the I/O we need to access. + * -- paulus + */ + cmpwi r8,0 + rlwinm r0,r8,16,16,30 + bge 57f + cmplwi r0,0xfe00 + li r0,0x3fd + bne 56f + li r0,0x3ff +56: sldi r0,r0,32 + or r8,r8,r0 +57: +#endif + + /* Construct the high word of the PPC-style PTE (r5) */ +#ifndef CONFIG_PPC64BRIDGE + rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ + rlwimi r5,r4,10,26,31 /* put in API (abbrev page index) */ +#else /* CONFIG_PPC64BRIDGE */ + clrlwi r3,r3,8 /* reduce vsid to 24 bits */ + sldi r5,r3,12 /* shift vsid into position */ + rlwimi r5,r4,16,20,24 /* put in API (abbrev page index) */ +#endif /* CONFIG_PPC64BRIDGE */ + SET_V(r5) /* set V (valid) bit */ + + /* Get the address of the primary PTE group in the hash table (r3) */ + .globl hash_page_patch_A +hash_page_patch_A: + addis r0,r7,Hash_base@h /* base address of hash table */ + rlwimi r0,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* VSID -> hash */ + rlwinm r3,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */ + xor r3,r3,r0 /* make primary hash */ + li r0,8 /* PTEs/group */ + + /* + * Test the _PAGE_HASHPTE bit in the old linux PTE, and skip the search + * if it is clear, meaning that the HPTE isn't there already... + */ + andi. r6,r6,_PAGE_HASHPTE + beq+ 10f /* no PTE: go look for an empty slot */ + tlbie r4 + + addis r4,r7,htab_hash_searches@ha + lwz r6,htab_hash_searches@l(r4) + addi r6,r6,1 /* count how many searches we do */ + stw r6,htab_hash_searches@l(r4) + + /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */ + mtctr r0 + addi r4,r3,-PTE_SIZE +1: LDPTEu r6,PTE_SIZE(r4) /* get next PTE */ + CMPPTE 0,r6,r5 + bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ + beq+ found_slot + + /* Search the secondary PTEG for a matching PTE */ + ori r5,r5,PTE_H /* set H (secondary hash) bit */ + .globl hash_page_patch_B +hash_page_patch_B: + xoris r4,r3,Hash_msk>>16 /* compute secondary hash */ + xori r4,r4,(-PTEG_SIZE & 0xffff) + addi r4,r4,-PTE_SIZE + mtctr r0 +2: LDPTEu r6,PTE_SIZE(r4) + CMPPTE 0,r6,r5 + bdnzf 2,2b + beq+ found_slot + xori r5,r5,PTE_H /* clear H bit again */ + + /* Search the primary PTEG for an empty slot */ +10: mtctr r0 + addi r4,r3,-PTE_SIZE /* search primary PTEG */ +1: LDPTEu r6,PTE_SIZE(r4) /* get next PTE */ + TST_V(r6) /* test valid bit */ + bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ + beq+ found_empty + + /* update counter of times that the primary PTEG is full */ + addis r4,r7,primary_pteg_full@ha + lwz r6,primary_pteg_full@l(r4) + addi r6,r6,1 + stw r6,primary_pteg_full@l(r4) + + /* Search the secondary PTEG for an empty slot */ + ori r5,r5,PTE_H /* set H (secondary hash) bit */ + .globl hash_page_patch_C +hash_page_patch_C: + xoris r4,r3,Hash_msk>>16 /* compute secondary hash */ + xori r4,r4,(-PTEG_SIZE & 0xffff) + addi r4,r4,-PTE_SIZE + mtctr r0 +2: LDPTEu r6,PTE_SIZE(r4) + TST_V(r6) + bdnzf 2,2b + beq+ found_empty + xori r5,r5,PTE_H /* clear H bit again */ + + /* + * Choose an arbitrary slot in the primary PTEG to overwrite. + * Since both the primary and secondary PTEGs are full, and we + * have no information that the PTEs in the primary PTEG are + * more important or useful than those in the secondary PTEG, + * and we know there is a definite (although small) speed + * advantage to putting the PTE in the primary PTEG, we always + * put the PTE in the primary PTEG. + */ + addis r4,r7,next_slot@ha + lwz r6,next_slot@l(r4) + addi r6,r6,PTE_SIZE + andi. r6,r6,7*PTE_SIZE +#ifdef CONFIG_POWER4 + /* + * Since we don't have BATs on POWER4, we rely on always having + * PTEs in the hash table to map the hash table and the code + * that manipulates it in virtual mode, namely flush_hash_page and + * flush_hash_segments. Otherwise we can get a DSI inside those + * routines which leads to a deadlock on the hash_table_lock on + * SMP machines. We avoid this by never overwriting the first + * PTE of each PTEG if it is already valid. + * -- paulus. + */ + bne 102f + li r6,PTE_SIZE +102: +#endif /* CONFIG_POWER4 */ + stw r6,next_slot@l(r4) + add r4,r3,r6 + + /* update counter of evicted pages */ + addis r6,r7,htab_evicts@ha + lwz r3,htab_evicts@l(r6) + addi r3,r3,1 + stw r3,htab_evicts@l(r6) + +#ifndef CONFIG_SMP + /* Store PTE in PTEG */ +found_empty: + STPTE r5,0(r4) +found_slot: + STPTE r8,PTE_SIZE/2(r4) + +#else /* CONFIG_SMP */ +/* + * Between the tlbie above and updating the hash table entry below, + * another CPU could read the hash table entry and put it in its TLB. + * There are 3 cases: + * 1. using an empty slot + * 2. updating an earlier entry to change permissions (i.e. enable write) + * 3. taking over the PTE for an unrelated address + * + * In each case it doesn't really matter if the other CPUs have the old + * PTE in their TLB. So we don't need to bother with another tlbie here, + * which is convenient as we've overwritten the register that had the + * address. :-) The tlbie above is mainly to make sure that this CPU comes + * and gets the new PTE from the hash table. + * + * We do however have to make sure that the PTE is never in an invalid + * state with the V bit set. + */ +found_empty: +found_slot: + CLR_V(r5,r0) /* clear V (valid) bit in PTE */ + STPTE r5,0(r4) + sync + tlbsync + sync + STPTE r8,PTE_SIZE/2(r4) /* put in correct RPN, WIMG, PP bits */ + sync + SET_V(r5) + STPTE r5,0(r4) /* finally set V bit in PTE */ +#endif /* CONFIG_SMP */ + + sync /* make sure pte updates get to memory */ + blr + + .comm next_slot,4 + .comm primary_pteg_full,4 + .comm htab_hash_searches,4 + +/* + * Flush the entry for a particular page from the hash table. + * + * flush_hash_page(unsigned context, unsigned long va, pte_t *ptep) + * + * We assume that there is a hash table in use (Hash != 0). + */ +_GLOBAL(flush_hash_page) + /* Convert context and va to VSID */ + mulli r3,r3,897*16 /* multiply context by context skew */ + rlwinm r0,r4,4,28,31 /* get ESID (top 4 bits of va) */ + mulli r0,r0,0x111 /* multiply by ESID skew */ + add r3,r3,r0 /* note code below trims to 24 bits */ + + /* + * We disable interrupts here, even on UP, because we want + * the _PAGE_HASHPTE bit to be a reliable indication of + * whether the HPTE exists. -- paulus + */ + mfmsr r10 + SYNC + rlwinm r0,r10,0,17,15 /* clear bit 16 (MSR_EE) */ + mtmsr r0 + SYNC + +#ifdef CONFIG_SMP + lis r9,hash_table_lock@h + ori r9,r9,hash_table_lock@l + lwz r8,PROCESSOR(r2) + oris r8,r8,9 +10: lwarx r7,0,r9 + cmpi 0,r7,0 + bne- 11f + stwcx. r8,0,r9 + beq+ 12f +11: lwz r7,0(r9) + cmpi 0,r7,0 + beq 10b + b 11b +12: isync +#endif + + /* + * Check the _PAGE_HASHPTE bit in the linux PTE. If it is + * already clear, we're done. If not, clear it (atomically) + * and proceed. -- paulus. + */ +1: lwarx r6,0,r5 /* fetch the pte */ + andi. r0,r6,_PAGE_HASHPTE + beq 9f /* done if HASHPTE is already clear */ + rlwinm r6,r6,0,31,29 /* clear HASHPTE bit */ + stwcx. r6,0,r5 /* update the pte */ + bne- 1b + + /* Construct the high word of the PPC-style PTE (r5) */ +#ifndef CONFIG_PPC64BRIDGE + rlwinm r5,r3,7,1,24 /* put VSID in 0x7fffff80 bits */ + rlwimi r5,r4,10,26,31 /* put in API (abbrev page index) */ +#else /* CONFIG_PPC64BRIDGE */ + clrlwi r3,r3,8 /* reduce vsid to 24 bits */ + sldi r5,r3,12 /* shift vsid into position */ + rlwimi r5,r4,16,20,24 /* put in API (abbrev page index) */ +#endif /* CONFIG_PPC64BRIDGE */ + SET_V(r5) /* set V (valid) bit */ + + /* Get the address of the primary PTE group in the hash table (r3) */ + .globl flush_hash_patch_A +flush_hash_patch_A: + lis r8,Hash_base@h /* base address of hash table */ + rlwimi r8,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* VSID -> hash */ + rlwinm r3,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */ + xor r3,r3,r8 /* make primary hash */ + li r8,8 /* PTEs/group */ + + /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */ + mtctr r8 + addi r7,r3,-PTE_SIZE +1: LDPTEu r0,PTE_SIZE(r7) /* get next PTE */ + CMPPTE 0,r0,r5 + bdnzf 2,1b /* loop while ctr != 0 && !cr0.eq */ + beq+ 3f + + /* Search the secondary PTEG for a matching PTE */ + ori r5,r5,PTE_H /* set H (secondary hash) bit */ + .globl flush_hash_patch_B +flush_hash_patch_B: + xoris r7,r3,Hash_msk>>16 /* compute secondary hash */ + xori r7,r7,(-PTEG_SIZE & 0xffff) + addi r7,r7,-PTE_SIZE + mtctr r8 +2: LDPTEu r0,PTE_SIZE(r7) + CMPPTE 0,r0,r5 + bdnzf 2,2b + bne- 4f /* should never fail to find it */ + +3: li r0,0 + STPTE r0,0(r7) /* invalidate entry */ +4: sync + tlbie r4 /* in hw tlb too */ + sync + +#ifdef CONFIG_SMP + tlbsync +9: sync + li r0,0 + stw r0,0(r9) /* clear hash_table_lock */ +#endif + +9: mtmsr r10 + SYNC + blr diff -Nru a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c --- a/arch/ppc/mm/init.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/mm/init.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.init.c 1.22 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * PowerPC version @@ -62,6 +62,7 @@ #include #include #include +#include #include "mem_pieces.h" @@ -73,9 +74,15 @@ #define PGTOKB(pages) (((pages) * PAGE_SIZE) >> 10) +mm_context_t next_mmu_context; +unsigned long context_map[(LAST_CONTEXT+1) / (8*sizeof(unsigned long))]; +#ifdef FEW_CONTEXTS +atomic_t nr_free_contexts; +struct mm_struct *context_mm[LAST_CONTEXT+1]; +void steal_context(void); +#endif /* FEW_CONTEXTS */ + int prom_trashed; -atomic_t next_mmu_context; -rwlock_t context_overflow_lock __cacheline_aligned = RW_LOCK_UNLOCKED; unsigned long *end_of_DRAM; unsigned long total_memory; unsigned long total_lowmem; @@ -96,6 +103,7 @@ extern char __openfirmware_begin, __openfirmware_end; unsigned long ioremap_base; unsigned long ioremap_bot; +unsigned long ioremap_1to1_end; unsigned long avail_start; extern int num_memory; extern struct mem_info memory[]; @@ -187,12 +195,6 @@ /* max amount of low RAM to map in */ unsigned long __max_low_memory = MAX_LOW_MEM; -void __bad_pte(pmd_t *pmd) -{ - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); - pmd_val(*pmd) = (unsigned long) BAD_PAGETABLE; -} - int do_check_pgt_cache(int low, int high) { int freed = 0; @@ -211,35 +213,6 @@ return freed; } -/* - * BAD_PAGE is the page that is used for page faults when linux - * is out-of-memory. Older versions of linux just did a - * do_exit(), but using this instead means there is less risk - * for a process dying in kernel mode, possibly leaving a inode - * unused etc.. - * - * BAD_PAGETABLE is the accompanying page-table: it is initialized - * to point to BAD_PAGE entries. - * - * ZERO_PAGE is a special page that is used for zero-initialized - * data and COW. - */ -pte_t *empty_bad_page_table; - -pte_t * __bad_pagetable(void) -{ - clear_page(empty_bad_page_table); - return empty_bad_page_table; -} - -void *empty_bad_page; - -pte_t __bad_page(void) -{ - clear_page(empty_bad_page); - return pte_mkdirty(mk_pte_phys(__pa(empty_bad_page), PAGE_SHARED)); -} - void show_mem(void) { int i,free = 0,total = 0,reserved = 0; @@ -319,21 +292,10 @@ void si_meminfo(struct sysinfo *val) { - int i; - - i = max_mapnr; - val->totalram = 0; + val->totalram = totalram_pages; val->sharedram = 0; val->freeram = nr_free_pages(); val->bufferram = atomic_read(&buffermem_pages); - while (i-- > 0) { - if (PageReserved(mem_map+i)) - continue; - val->totalram++; - if (!atomic_read(&mem_map[i].count)) - continue; - val->sharedram += atomic_read(&mem_map[i].count) - 1; - } val->totalhigh = totalhigh_pages; val->freehigh = nr_free_highpages(); val->mem_unit = PAGE_SIZE; @@ -354,9 +316,9 @@ /* * Choose an address to map it to. * Once the vmalloc system is running, we use it. - * Before then, we map addresses >= ioremap_base - * virt == phys; for addresses below this we use - * space going down from ioremap_base (ioremap_bot + * Before then, we map addresses between ioremap_base + * and ioremap_1to1_end virt == phys; for other addresses + * we use space going down from ioremap_base (ioremap_bot * records where we're up to). */ p = addr & PAGE_MASK; @@ -366,7 +328,7 @@ * If the address lies within the first 16 MB, assume it's in ISA * memory space */ - if ( p < 16*1024*1024 ) + if (p < 16*1024*1024) p += _ISA_MEM_BASE; /* @@ -404,11 +366,7 @@ return NULL; v = VMALLOC_VMADDR(area->addr); } else { -#ifndef CONFIG_HIGHMEM - if (p >= ioremap_base) -#else - if (p >= ioremap_base && p < PKMAP_BASE) -#endif /* CONFIG_HIGHMEM */ + if (p >= ioremap_base && p < ioremap_1to1_end) v = p; else v = (ioremap_bot -= size); @@ -482,14 +440,16 @@ if (pg != 0) { err = 0; set_pte(pg, mk_pte_phys(pa & PAGE_MASK, __pgprot(flags))); - if (mem_init_done) - flush_hash_page(0, va); +#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) + if (mem_init_done && Hash != 0) + flush_hash_page(0, va, pg); +#endif /* !4xx && !8xx */ } spin_unlock(&init_mm.page_table_lock); return err; } -#ifndef CONFIG_8xx +#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) /* * TLB flushing: * @@ -510,19 +470,14 @@ void local_flush_tlb_all(void) { -#ifdef CONFIG_PPC64BRIDGE - /* XXX this assumes that the vmalloc arena starts no lower than - * 0xd0000000 on 64-bit machines. */ - flush_hash_segments(0xd, 0xffffff); -#else - /* this could cause problems on SMP with nobats -- paulus */ - /* XXX no hash_table_lock? interesting -- paulus */ - __clear_user(Hash, Hash_size); - _tlbia(); + /* aargh!!! */ + /* just flush the kernel part of the address space, that's + all that the current callers of this require. -- paulus. */ + local_flush_tlb_range(&init_mm, TASK_SIZE, ~0UL); + #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); #endif /* CONFIG_SMP */ -#endif /* CONFIG_PPC64BRIDGE */ } /* @@ -533,30 +488,18 @@ void local_flush_tlb_mm(struct mm_struct *mm) { - if (mm->context == 0) { - /* don't try to reassign a new context to the kernel */ - /* - * This could cause problems on SMP if we aren't using - * the BATs (e.g. on POWER4 or if the nobats option is used). - * The problem scenario is that one cpu is doing - * flush_hash_page or similar when another cpu clears - * out the HPTEs which map the flush_hash_page text - * and the hash table. hash_page will then deadlock. - * We need some way to have "protected" HPTEs or else - * do all hash-table manipulation with the MMU off. - * -- paulus. - */ -#ifdef CONFIG_PPC64BRIDGE - flush_hash_segments(0xd, 0xf); -#else - flush_hash_segments(0xc, 0xf); -#endif CONFIG_PPC64BRIDGE + if (Hash == 0) { _tlbia(); return; } - mm->context = NO_CONTEXT; - if (mm == current->mm) - activate_mm(mm, mm); + + if (mm->map_count) { + struct vm_area_struct *mp; + for (mp = mm->mmap; mp != NULL; mp = mp->vm_next) + local_flush_tlb_range(mm, mp->vm_start, mp->vm_end); + } else + local_flush_tlb_range(mm, 0, TASK_SIZE); + #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); #endif @@ -565,10 +508,21 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr) { - if (vmaddr < TASK_SIZE) - flush_hash_page(vma->vm_mm->context, vmaddr); - else - flush_hash_page(0, vmaddr); + struct mm_struct *mm; + pmd_t *pmd; + pte_t *pte; + + if (Hash == 0) { + _tlbie(vmaddr); + return; + } + mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm; + pmd = pmd_offset(pgd_offset(mm, vmaddr), vmaddr); + if (!pmd_none(*pmd)) { + pte = pte_offset(pmd, vmaddr); + if (pte_val(*pte) & _PAGE_HASHPTE) + flush_hash_page(mm->context, vmaddr, pte); + } #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); #endif @@ -576,28 +530,43 @@ /* - * for each page addr in the range, call MMU_invalidate_page() - * if the range is very large and the hash table is small it might be - * faster to do a search of the hash table and just invalidate pages - * that are in the range but that's for study later. - * -- Cort + * For each address in the range, find the pte for the address + * and check _PAGE_HASHPTE bit; if it is set, find and destroy + * the corresponding HPTE. */ void local_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) { - start &= PAGE_MASK; + pmd_t *pmd; + pte_t *pte; + unsigned long pmd_end; + unsigned int ctx = mm->context; - if (mm->context != 0) { - if (end > TASK_SIZE) - end = TASK_SIZE; - if (end - start > 20 * PAGE_SIZE) { - flush_tlb_mm(mm); - return; - } + if (Hash == 0) { + _tlbia(); + return; } - - for (; start < end; start += PAGE_SIZE) - flush_hash_page(mm->context, start); + start &= PAGE_MASK; + if (start >= end) + return; + pmd = pmd_offset(pgd_offset(mm, start), start); + do { + pmd_end = (start + PGDIR_SIZE) & PGDIR_MASK; + if (!pmd_none(*pmd)) { + if (!pmd_end || pmd_end > end) + pmd_end = end; + pte = pte_offset(pmd, start); + do { + if ((pte_val(*pte) & _PAGE_HASHPTE) != 0) + flush_hash_page(ctx, start, pte); + start += PAGE_SIZE; + ++pte; + } while (start && start < pmd_end); + } else { + start = pmd_end; + } + ++pmd; + } while (start && start < end); #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); @@ -605,59 +574,6 @@ } /* - * The context counter has overflowed. - * We set mm->context to NO_CONTEXT for all mm's in the system. - * We assume we can get to all mm's by looking as tsk->mm for - * all tasks in the system. - */ -void -mmu_context_overflow(void) -{ - struct task_struct *tsk; - - printk(KERN_DEBUG "mmu_context_overflow\n"); - /* acquire the write lock for context overflow */ - write_lock (&context_overflow_lock); - /* recheck if overflow still exists */ - if (atomic_read(&next_mmu_context) == LAST_CONTEXT) { - read_lock(&tasklist_lock); - for_each_task(tsk) { - if (tsk->mm) - tsk->mm->context = NO_CONTEXT; - } - read_unlock(&tasklist_lock); - flush_hash_segments(0x10, 0xffffff); -#ifdef CONFIG_SMP - smp_send_tlb_invalidate(0); -#endif - atomic_set(&next_mmu_context, 0); - } - write_unlock (&context_overflow_lock); - /* make sure current always has a context */ - /* need to check to assure current task has an mm */ - /* - idle thread does not have an MM */ - if (current->mm) { - current->mm->context = MUNGE_CONTEXT(atomic_inc_return(&next_mmu_context)); - set_context(current->mm->context, current->mm->pgd); - } -} -#else /* CONFIG_8xx */ -void -mmu_context_overflow(void) -{ - atomic_set(&next_mmu_context, -1); -} -#endif /* CONFIG_8xx */ - -void flush_page_to_ram(struct page *page) -{ - unsigned long vaddr = (unsigned long) kmap(page); - __flush_page_to_ram(vaddr); - kunmap(page); -} - -#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) -/* * Set up one of the I/D BAT (block address translation) register pairs. * The parameters are not checked; in particular size must be a power * of 2 between 128k and 256M. @@ -768,10 +684,10 @@ f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED; #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) /* Allows stub to set breakpoints everywhere */ - f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; + f |= _PAGE_RW | _PAGE_DIRTY; #else if ((char *) v < _stext || (char *) v >= etext) - f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE; + f |= _PAGE_RW | _PAGE_DIRTY; #ifndef CONFIG_8xx else /* On the powerpc (not 8xx), no user access @@ -839,16 +755,59 @@ #ifdef CONFIG_BLK_DEV_INITRD void free_initrd_mem(unsigned long start, unsigned long end) { + printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); + for (; start < end; start += PAGE_SIZE) { ClearPageReserved(virt_to_page(start)); set_page_count(virt_to_page(start), 1); free_page(start); totalram_pages++; } - printk ("Freeing initrd memory: %ldk freed\n", (end - start) >> 10); } #endif +/* + * Initialize the context management stuff. + */ +static void mmu_context_init(void) +{ + context_map[0] = 1; /* init_mm uses context 0 */ + next_mmu_context = 1; +#ifdef FEW_CONTEXTS + atomic_set(&nr_free_contexts, LAST_CONTEXT); + context_mm[0] = &init_mm; +#endif /* FEW_CONTEXTS */ +} + +#ifdef FEW_CONTEXTS +/* + * Steal a context from a task that has one at the moment. + * This is only used on 8xx and 4xx and we presently assume that + * they don't do SMP. If they do then this will have to check + * whether the MM we steal is in use. + * We also assume that this is only used on systems that don't + * use an MMU hash table - this is true for 8xx and 4xx. + * This isn't an LRU system, it just frees up each context in + * turn (sort-of pseudo-random replacement :). This would be the + * place to implement an LRU scheme if anyone was motivated to do it. + * -- paulus + */ +void steal_context(void) +{ + struct mm_struct *mm; + + /* free up context `next_mmu_context' */ + /* if we shouldn't free context 0, don't... */ +#ifdef CONFIG_4xx + if (next_mmu_context == 0) + next_mmu_context = 1; +#endif /* CONFIG_4xx */ + mm = context_mm[next_mmu_context]; + flush_tlb_mm(mm); + destroy_context(mm); +} +#endif /* FEW_CONTEXTS */ + extern boot_infos_t *disp_bi; /* @@ -903,6 +862,8 @@ mtspr(SPRN_DCCR, 0x80000000); /* 128 MB of data space at 0x0. */ mtspr(SPRN_ICCR, 0x80000000); /* 128 MB of instr. space at 0x0. */ + + mmu_context_init(); } #else /* !CONFIG_4xx */ @@ -927,27 +888,32 @@ #if !defined(CONFIG_8xx) if ( ppc_md.progress ) ppc_md.progress("MMU:hash init", 0x300); hash_init(); -#ifndef CONFIG_PPC64BRIDGE - _SDR1 = __pa(Hash) | (Hash_mask >> 10); -#endif - - ioremap_base = 0xf8000000; #endif /* CONFIG_8xx */ + /* + * Addresses between ioremap_base and ioremap_1to1_end + * must NOT include any BAT mappings which don't have + * virtual == physical. + */ + ioremap_base = 0xf8000000; +#ifdef CONFIG_HIGHMEM + ioremap_1to1_end = PKMAP_BASE; +#else + ioremap_1to1_end = 0xffffffff; +#endif /* CONFIG_HIGHMEM */ + if ( ppc_md.progress ) ppc_md.progress("MMU:mapin", 0x301); /* Map in all of RAM starting at KERNELBASE */ mapin_ram(); -#if defined(CONFIG_POWER4) - ioremap_base = ioremap_bot = 0xfffff000; - isa_io_base = (unsigned long) ioremap(0xffd00000, 0x200000) + 0x100000; - -#elif defined(CONFIG_8xx) + /* Map in I/O resources */ +#if defined(CONFIG_8xx) /* Now map in some of the I/O space that is generically needed * or shared with multiple devices. * All of this fits into the same 4Mbyte region, so it only * requires one page table page. */ + ioremap_base = 0; ioremap(IMAP_ADDR, IMAP_SIZE); #ifdef CONFIG_MBX ioremap(NVRAM_ADDR, NVRAM_SIZE); @@ -974,7 +940,7 @@ #ifdef CONFIG_PCI ioremap(PCI_CSR_ADDR, PCI_CSR_SIZE); #endif -#else /* !CONFIG_POWER4 && !CONFIG_8xx */ +#else /* !CONFIG_8xx */ /* * Setup the bat mappings we're going to load that cover * the io areas. RAM was mapped by mapin_ram(). @@ -986,6 +952,7 @@ setbat(0, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); setbat(1, 0xf0000000, 0xc0000000, 0x08000000, IO_PAGE); ioremap_base = 0xf0000000; + ioremap_1to1_end = 0xf0000000; break; case _MACH_chrp: /* @@ -994,7 +961,9 @@ * down and slap your hands. If it causes problems please email me. * -- Cort */ -#ifndef CONFIG_POWER3 +#ifdef CONFIG_PPC64BRIDGE + setbat(0, 0xf8000000, 0xf8000000, 0x04000000, IO_PAGE); +#else setbat(0, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); setbat(1, 0x90000000, 0x90000000, 0x10000000, IO_PAGE); #endif @@ -1012,6 +981,50 @@ setbat(0, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE); setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); break; + case _MACH_k2: + setbat(0, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); + setbat(1, 0xff000000, 0xff000000, 0x01000000, IO_PAGE); + ioremap_base = 0xff000000; /* will break HIGHMEM */ + break; + case _MACH_menf1: + setbat(0, 0xf8000000, 0xf8000000, 0x08000000, IO_PAGE); + setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); + ioremap_base = 0xf8000000; + break; + case _MACH_mcpn765: + setbat(0, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE); + setbat(1, 0x90000000, 0x90000000, 0x10000000, IO_PAGE); + ioremap_base = 0xf0000000; + break; + case _MACH_mvme5100: + setbat(0, 0xf0000000, 0xf0000000, 0x10000000, IO_PAGE); + setbat(1, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); + ioremap_base = 0xf0000000; + break; + case _MACH_pcore: + setbat(0, 0xfe000000, 0xfe000000, 0x02000000, IO_PAGE); + ioremap_base = 0xfe000000; + break; + case _MACH_prpmc750: + setbat(0, 0x80000000, 0x80000000, 0x10000000, IO_PAGE); + setbat(1, 0xf0000000, 0xc0000000, 0x08000000, IO_PAGE); + setbat(3, 0xf8000000, 0xf8000000, 0x08000000, IO_PAGE); + ioremap_base = 0xf0000000; + ioremap_1to1_end = 0xf0000000; + break; + case _MACH_spruce: + setbat(0, SPRUCE_PCI_MEM_BASE, SPRUCE_PCI_PHY_MEM_BASE, + 0x10000000, IO_PAGE); + setbat(1, SPRUCE_PCI_IO_BASE, SPRUCE_PCI_PHY_IO_BASE, + 0x10000000, IO_PAGE); + ioremap_base = SPRUCE_PCI_PHY_MEM_BASE; + break; + case _MACH_sandpoint: + case _MACH_zx4500: + setbat(0, 0xf8000000, 0xf8000000, 0x08000000, IO_PAGE); + setbat(1, 0xb0000000, 0xb0000000, 0x10000000, IO_PAGE); + ioremap_base = 0xf8000000; + break; case _MACH_8260: /* Map the IMMR, plus anything else we can cover * in that upper space according to the memory controller @@ -1024,7 +1037,7 @@ break; } ioremap_bot = ioremap_base; -#endif /* CONFIG_POWER4 || CONFIG_8xx */ +#endif /* CONFIG_8xx */ if ( ppc_md.progress ) ppc_md.progress("MMU:exit", 0x211); #ifdef CONFIG_BOOTX_TEXT @@ -1032,6 +1045,8 @@ if (_machine == _MACH_Pmac || _machine == _MACH_chrp) map_bootx_text(); #endif + + mmu_context_init(); } #endif /* CONFIG_4xx */ @@ -1095,12 +1110,6 @@ #endif /* CONFIG_HIGHMEM */ /* - * Grab some memory for bad_page and bad_pagetable to use. - */ - empty_bad_page = alloc_bootmem_pages(PAGE_SIZE); - empty_bad_page_table = alloc_bootmem_pages(PAGE_SIZE); - - /* * All pages are DMA-able so we put them all in the DMA zone. */ zones_size[ZONE_DMA] = total_lowmem >> PAGE_SHIFT; @@ -1128,7 +1137,6 @@ 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 */ @@ -1208,8 +1216,10 @@ int Hash_bits, mb, mb2; unsigned int hmask, h; - extern unsigned int hash_page_patch_A[], hash_page_patch_B[], - hash_page_patch_C[], hash_page[]; + extern unsigned int hash_page_patch_A[]; + extern unsigned int hash_page_patch_B[], hash_page_patch_C[]; + extern unsigned int hash_page[]; + extern unsigned int flush_hash_patch_A[], flush_hash_patch_B[]; #ifdef CONFIG_PPC64BRIDGE /* The hash table has already been allocated and initialized @@ -1259,6 +1269,7 @@ if ( Hash_size ) { Hash = mem_pieces_find(Hash_size, Hash_size); cacheable_memzero(Hash, Hash_size); + _SDR1 = __pa(Hash) | (Hash_mask >> 10); } else Hash = 0; #endif /* CONFIG_PPC64BRIDGE */ @@ -1271,10 +1282,10 @@ Hash_end = (PTE *) ((unsigned long)Hash + Hash_size); /* - * Patch up the instructions in head.S:hash_page + * Patch up the instructions in hashtable.S:create_hpte */ hash_page_patch_A[0] = (hash_page_patch_A[0] & ~0xffff) - | (__pa(Hash) >> 16); + | ((unsigned int)(Hash) >> 16); hash_page_patch_A[1] = (hash_page_patch_A[1] & ~0x7c0) | (mb << 6); hash_page_patch_A[2] = (hash_page_patch_A[2] & ~0x7c0) @@ -1283,10 +1294,6 @@ | hmask; hash_page_patch_C[0] = (hash_page_patch_C[0] & ~0xffff) | hmask; -#if 0 /* see hash_page in head.S, note also patch_C ref below */ - hash_page_patch_D[0] = (hash_page_patch_D[0] & ~0xffff) - | hmask; -#endif /* * Ensure that the locations we've patched have been written * out from the data cache and invalidated in the instruction @@ -1294,6 +1301,19 @@ */ flush_icache_range((unsigned long) &hash_page_patch_A[0], (unsigned long) &hash_page_patch_C[1]); + /* + * Patch up the instructions in hashtable.S:flush_hash_page + */ + flush_hash_patch_A[0] = (flush_hash_patch_A[0] & ~0xffff) + | ((unsigned int)(Hash) >> 16); + flush_hash_patch_A[1] = (flush_hash_patch_A[1] & ~0x7c0) + | (mb << 6); + flush_hash_patch_A[2] = (flush_hash_patch_A[2] & ~0x7c0) + | (mb2 << 6); + flush_hash_patch_B[0] = (flush_hash_patch_B[0] & ~0xffff) + | hmask; + flush_icache_range((unsigned long) &flush_hash_patch_A[0], + (unsigned long) &flush_hash_patch_B[1]); } else { Hash_end = 0; @@ -1306,6 +1326,7 @@ flush_icache_range((unsigned long) &hash_page[0], (unsigned long) &hash_page[1]); } + if ( ppc_md.progress ) ppc_md.progress("hash:done", 0x205); } #endif /* !CONFIG_4xx && !CONFIG_8xx */ @@ -1320,7 +1341,7 @@ unsigned long kstart, ksize; /* - * Initially, available phyiscal memory is equivalent to all + * Initially, available physical memory is equivalent to all * physical memory. */ @@ -1356,4 +1377,78 @@ if (Hash) mem_pieces_remove(&phys_avail, __pa(Hash), Hash_size, 1); #endif /* CONFIG_PPC64BRIDGE */ +} + +/* + * This is called when a page has been modified by the kernel. + * It just marks the page as not i-cache clean. We do the i-cache + * flush later when the page is given to a user process, if necessary. + */ +void flush_dcache_page(struct page *page) +{ + clear_bit(PG_arch_1, &page->flags); +} + +#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) +/* + * This is called at the end of handling a user page fault, when the + * fault has been handled by updating a PTE in the linux page tables. + * We use it to preload an HPTE into the hash table corresponding to + * the updated linux PTE. + */ +void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, + pte_t pte) +{ + struct mm_struct *mm; + pmd_t *pmd; + pte_t *ptep; + static int nopreload; + + if (Hash == 0 || nopreload) + return; + mm = (address < TASK_SIZE)? vma->vm_mm: &init_mm; + pmd = pmd_offset(pgd_offset(mm, address), address); + if (!pmd_none(*pmd)) { + ptep = pte_offset(pmd, address); + add_hash_page(mm->context, address, ptep); + } +} +#endif /* !4xx && !8xx */ + +/* + * set_pte stores a linux PTE into the linux page table. + * On machines which use an MMU hash table we avoid changing the + * _PAGE_HASHPTE bit. + * If the new PTE has _PAGE_EXEC set, meaning that the user wants + * to be able to execute out of the page, we check if the page is + * i-cache dirty and flush it if so, and mark it clean. + */ +void set_pte(pte_t *ptep, pte_t pte) +{ +#if _PAGE_HASHPTE != 0 + pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE); +#else + *ptep = pte; +#endif + if ((pte_val(pte) & _PAGE_EXEC) + && (pte_val(pte) & PAGE_MASK) < total_memory) { + struct page *page = pte_page(pte); + if (!test_bit(PG_arch_1, &page->flags)) { + __flush_dcache_icache((unsigned long)kmap(page)); + kunmap(page); + set_bit(PG_arch_1, &page->flags); + } + } +} + +void clear_user_page(void *page, unsigned long vaddr, struct page *realpage) +{ + clear_page(page); + clear_bit(PG_arch_1, &realpage->flags); +} + +void copy_user_page(void *to, void *from, unsigned long vaddr, struct page *page) +{ + copy_page(to, from); + clear_bit(PG_arch_1, &page->flags); } diff -Nru a/arch/ppc/mm/mem_pieces.c b/arch/ppc/mm/mem_pieces.c --- a/arch/ppc/mm/mem_pieces.c Sat Jun 16 06:00:16 2001 +++ b/arch/ppc/mm/mem_pieces.c Sat Jun 16 06:00:16 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mem_pieces.c 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (c) 1996 Paul Mackerras diff -Nru a/arch/ppc/mm/mem_pieces.h b/arch/ppc/mm/mem_pieces.h --- a/arch/ppc/mm/mem_pieces.h Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/mm/mem_pieces.h Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.mem_pieces.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (c) 1996 Paul Mackerras diff -Nru a/arch/ppc/vmlinux.lds b/arch/ppc/vmlinux.lds --- a/arch/ppc/vmlinux.lds Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/vmlinux.lds Sat Jun 16 06:00:19 2001 @@ -69,6 +69,10 @@ __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; + __start___ftr_fixup = .; + __ftr_fixup : { *(__ftr_fixup) } + __stop___ftr_fixup = .; + . = ALIGN(32); .data.cacheline_aligned : { *(.data.cacheline_aligned) } diff -Nru a/arch/ppc/xmon/Makefile b/arch/ppc/xmon/Makefile --- a/arch/ppc/xmon/Makefile Sat Jun 16 06:00:24 2001 +++ b/arch/ppc/xmon/Makefile Sat Jun 16 06:00:24 2001 @@ -1,4 +1,4 @@ -# BK Id: SCCS/s.Makefile 1.3 05/17/01 18:14:23 cort +# BK Id: %F% %I% %G% %U% %#% # # Makefile for xmon diff -Nru a/arch/ppc/xmon/adb.c b/arch/ppc/xmon/adb.c --- a/arch/ppc/xmon/adb.c Sat Jun 16 06:00:28 2001 +++ b/arch/ppc/xmon/adb.c Sat Jun 16 06:00:28 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.adb.c 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) 1996 Paul Mackerras. diff -Nru a/arch/ppc/xmon/ansidecl.h b/arch/ppc/xmon/ansidecl.h --- a/arch/ppc/xmon/ansidecl.h Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/xmon/ansidecl.h Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ansidecl.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* ANSI and traditional C compatability macros Copyright 1991, 1992 Free Software Foundation, Inc. diff -Nru a/arch/ppc/xmon/nonstdio.h b/arch/ppc/xmon/nonstdio.h --- a/arch/ppc/xmon/nonstdio.h Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/xmon/nonstdio.h Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.nonstdio.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ typedef int FILE; extern FILE *xmon_stdin, *xmon_stdout; diff -Nru a/arch/ppc/xmon/ppc-dis.c b/arch/ppc/xmon/ppc-dis.c --- a/arch/ppc/xmon/ppc-dis.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/xmon/ppc-dis.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc-dis.c 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* ppc-dis.c -- Disassemble PowerPC instructions Copyright 1994 Free Software Foundation, Inc. diff -Nru a/arch/ppc/xmon/ppc-opc.c b/arch/ppc/xmon/ppc-opc.c --- a/arch/ppc/xmon/ppc-opc.c Sat Jun 16 06:00:19 2001 +++ b/arch/ppc/xmon/ppc-opc.c Sat Jun 16 06:00:19 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc-opc.c 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* ppc-opc.c -- PowerPC opcode list Copyright 1994 Free Software Foundation, Inc. diff -Nru a/arch/ppc/xmon/ppc.h b/arch/ppc/xmon/ppc.h --- a/arch/ppc/xmon/ppc.h Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/xmon/ppc.h Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.ppc.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* ppc.h -- Header file for PowerPC opcode table Copyright 1994 Free Software Foundation, Inc. diff -Nru a/arch/ppc/xmon/privinst.h b/arch/ppc/xmon/privinst.h --- a/arch/ppc/xmon/privinst.h Sat Jun 16 06:00:25 2001 +++ b/arch/ppc/xmon/privinst.h Sat Jun 16 06:00:25 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.privinst.h 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) 1996 Paul Mackerras. diff -Nru a/arch/ppc/xmon/setjmp.c b/arch/ppc/xmon/setjmp.c --- a/arch/ppc/xmon/setjmp.c Sat Jun 16 06:00:22 2001 +++ b/arch/ppc/xmon/setjmp.c Sat Jun 16 06:00:22 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.setjmp.c 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) 1996 Paul Mackerras. diff -Nru a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c --- a/arch/ppc/xmon/start.c Sat Jun 16 06:00:17 2001 +++ b/arch/ppc/xmon/start.c Sat Jun 16 06:00:17 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.start.c 1.12 05/21/01 21:39:13 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) 1996 Paul Mackerras. @@ -85,6 +85,26 @@ use_screen = 1; #endif } + if (!use_screen && (np = find_devices("escc")) != NULL) { + /* + * look for the device node for the serial port + * we're using and see if it says it has a modem + */ + char *name = xmon_use_sccb? "ch-b": "ch-a"; + char *slots; + int l; + + np = np->child; + while (np != NULL && strcmp(np->name, name) != 0) + np = np->sibling; + if (np != NULL) { + /* XXX should parse this properly */ + slots = get_property(np, "slot-names", &l); + if (slots != NULL && l >= 10 + && strcmp(slots+4, "Modem") == 0) + via_modem = 1; + } + } prom_drawstring("xmon uses "); if (use_screen) prom_drawstring("screen and keyboard\n"); @@ -544,7 +564,9 @@ xmon_enter(void) { #ifdef CONFIG_ADB_PMU - pmu_suspend(); + if (_machine == _MACH_Pmac) { + pmu_suspend(); + } #endif } @@ -552,6 +574,8 @@ xmon_leave(void) { #ifdef CONFIG_ADB_PMU - pmu_resume(); + if (_machine == _MACH_Pmac) { + pmu_resume(); + } #endif } diff -Nru a/arch/ppc/xmon/start_8xx.c b/arch/ppc/xmon/start_8xx.c --- a/arch/ppc/xmon/start_8xx.c Sat Jun 16 06:00:20 2001 +++ b/arch/ppc/xmon/start_8xx.c Sat Jun 16 06:00:20 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.start_8xx.c 1.7 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Copyright (C) 1996 Paul Mackerras. diff -Nru a/arch/ppc/xmon/subr_prf.c b/arch/ppc/xmon/subr_prf.c --- a/arch/ppc/xmon/subr_prf.c Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/xmon/subr_prf.c Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.subr_prf.c 1.5 05/17/01 18:14:23 cort + * BK Id: %F% %I% %G% %U% %#% */ /* * Written by Cort Dougan to replace the version originally used diff -Nru a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c --- a/arch/ppc/xmon/xmon.c Sat Jun 16 06:00:15 2001 +++ b/arch/ppc/xmon/xmon.c Sat Jun 16 06:00:15 2001 @@ -1,5 +1,5 @@ /* - * BK Id: SCCS/s.xmon.c 1.12 06/09/01 22:18:05 paulus + * BK Id: %F% %I% %G% %U% %#% */ /* * Routines providing a simple monitor for use on the PowerMac. @@ -1017,7 +1017,8 @@ seg_end = (seg << 28) | 0x0ffff000; if (seg_end > hash_end) seg_end = hash_end; - dump_hash_table_seg((hash_ctx << 4) + seg, seg_start, seg_end); + dump_hash_table_seg((hash_ctx << 4) + (seg * 0x111), + seg_start, seg_end); seg_start = seg_end + 0x1000; } } diff -Nru a/drivers/Makefile b/drivers/Makefile --- a/drivers/Makefile Sat Jun 16 06:00:24 2001 +++ b/drivers/Makefile Sat Jun 16 06:00:24 2001 @@ -24,7 +24,7 @@ subdir-$(CONFIG_TC) += tc subdir-$(CONFIG_VT) += video subdir-$(CONFIG_MAC) += macintosh -subdir-$(CONFIG_ALL_PPC) += macintosh +subdir-$(CONFIG_PPC) += macintosh subdir-$(CONFIG_USB) += usb subdir-$(CONFIG_INPUT) += input subdir-$(CONFIG_PHONE) += telephony diff -Nru a/drivers/block/swim3.c b/drivers/block/swim3.c --- a/drivers/block/swim3.c Sat Jun 16 06:00:17 2001 +++ b/drivers/block/swim3.c Sat Jun 16 06:00:17 2001 @@ -33,6 +33,7 @@ #define MAJOR_NR FLOPPY_MAJOR #include +#include static int floppy_blocksizes[2] = {512,512}; static int floppy_sizes[2] = {2880,2880}; @@ -248,10 +249,7 @@ int swim3_init(void); #ifndef CONFIG_PMAC_PBOOK -static inline int check_media_bay(struct device_node *which_bay, int what) -{ - return 1; -} +#define check_media_bay(which, what) 1 #endif static void swim3_select(struct floppy_state *fs, int sel) @@ -1014,10 +1012,14 @@ revalidate: floppy_revalidate, }; +static devfs_handle_t floppy_devfs_handle; + int swim3_init(void) { struct device_node *swim; + floppy_devfs_handle = devfs_mk_dir(NULL, "floppy", NULL); + swim = find_devices("floppy"); while (swim && (floppy_count < MAX_FLOPPIES)) { @@ -1034,7 +1036,7 @@ if (floppy_count > 0) { - if (register_blkdev(MAJOR_NR, "fd", &floppy_fops)) { + if (devfs_register_blkdev(MAJOR_NR, "fd", &floppy_fops)) { printk(KERN_ERR "Unable to get major %d for floppy\n", MAJOR_NR); return -EBUSY; @@ -1051,7 +1053,9 @@ { struct device_node *mediabay; struct floppy_state *fs = &floppy_states[floppy_count]; - + char floppy_name[16]; + devfs_handle_t floppy_handle; + if (swim->n_addrs < 2) { printk(KERN_INFO "swim3: expecting 2 addrs (n_addrs:%d, n_intrs:%d)\n", @@ -1108,6 +1112,12 @@ printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, mediabay ? "in media bay" : ""); + sprintf(floppy_name, "%s%d", floppy_devfs_handle ? "" : "floppy", + floppy_count); + floppy_handle = devfs_register(floppy_devfs_handle, floppy_name, + DEVFS_FL_DEFAULT, MAJOR_NR, floppy_count, + S_IFBLK | S_IRUSR | S_IWUSR | S_IRGRP |S_IWGRP, + &floppy_fops, NULL); floppy_count++; diff -Nru a/drivers/char/keyboard.c b/drivers/char/keyboard.c --- a/drivers/char/keyboard.c Sat Jun 16 06:00:16 2001 +++ b/drivers/char/keyboard.c Sat Jun 16 06:00:16 2001 @@ -322,7 +322,7 @@ compute_shiftstate(); kbd->slockstate = 0; /* play it safe */ #else - keysym = U(plain_map[keycode]); + keysym = U(key_maps[0][keycode]); type = KTYP(keysym); if (type == KT_SHIFT) (*key_handler[type])(keysym & 0xff, up_flag); @@ -750,7 +750,7 @@ k = i*BITS_PER_LONG; for(j=0; j #include -#ifdef CONFIG_MAC_SERIAL -#define SERIAL_DEV_OFFSET 2 +#if defined(CONFIG_MAC_SERIAL) +#define SERIAL_DEV_OFFSET ((_machine == _MACH_prep) ? 0 : 2) #else #define SERIAL_DEV_OFFSET 0 #endif @@ -5226,6 +5226,7 @@ #endif serial_driver.major = TTY_MAJOR; serial_driver.minor_start = 64 + SERIAL_DEV_OFFSET; + serial_driver.name_base = SERIAL_DEV_OFFSET; serial_driver.num = NR_PORTS; serial_driver.type = TTY_DRIVER_TYPE_SERIAL; serial_driver.subtype = SERIAL_TYPE_NORMAL; diff -Nru a/drivers/char/tty_io.c b/drivers/char/tty_io.c --- a/drivers/char/tty_io.c Sat Jun 16 06:00:15 2001 +++ b/drivers/char/tty_io.c Sat Jun 16 06:00:15 2001 @@ -148,6 +148,7 @@ extern long serial167_console_init(void); extern void console_8xx_init(void); extern int rs_8xx_init(void); +extern void mac_scc_console_init(void); extern void hwc_console_init(void); extern void hwc_tty_init(void); extern void con3215_init(void); @@ -2184,6 +2185,14 @@ #ifdef CONFIG_SERIAL_CONSOLE #if (defined(CONFIG_8xx) || defined(CONFIG_8260)) console_8xx_init(); +#elif defined(CONFIG_MAC_SERIAL) && defined(CONFIG_SERIAL) + if (_machine == _MACH_prep){ + serial_console_init(); + } else { + mac_scc_console_init(); + } +#elif defined(CONFIG_MAC_SERIAL) + mac_scc_console_init(); #elif defined(CONFIG_SERIAL) serial_console_init(); #endif /* CONFIG_8xx */ @@ -2306,9 +2315,6 @@ #endif #ifdef CONFIG_COMPUTONE ip2_init(); -#endif -#ifdef CONFIG_MAC_SERIAL - macserial_init(); #endif #ifdef CONFIG_ROCKETPORT rp_init(); diff -Nru a/drivers/i2c/Config.in b/drivers/i2c/Config.in --- a/drivers/i2c/Config.in Sat Jun 16 06:00:18 2001 +++ b/drivers/i2c/Config.in Sat Jun 16 06:00:18 2001 @@ -20,6 +20,13 @@ dep_tristate ' Elektor ISA card' CONFIG_I2C_ELEKTOR $CONFIG_I2C_ALGOPCF fi + if [ "$CONFIG_8xx" = "y" ]; then + dep_tristate 'MPC8xx CPM I2C interface' CONFIG_I2C_ALGO8XX $CONFIG_I2C + if [ "$CONFIG_RPXLITE" = "y" -o "$CONFIG_RPXCLASSIC" = "y" ]; then + dep_tristate ' Embedded Planet RPX Lite/Classic suppoort' CONFIG_I2C_RPXLITE $CONFIG_I2C_ALGO8XX + fi + fi + # This is needed for automatic patch generation: sensors code starts here # This is needed for automatic patch generation: sensors code ends here diff -Nru a/drivers/i2c/Makefile b/drivers/i2c/Makefile --- a/drivers/i2c/Makefile Sat Jun 16 06:00:25 2001 +++ b/drivers/i2c/Makefile Sat Jun 16 06:00:25 2001 @@ -14,6 +14,8 @@ obj-$(CONFIG_I2C_VELLEMAN) += i2c-velleman.o obj-$(CONFIG_I2C_ALGOPCF) += i2c-algo-pcf.o obj-$(CONFIG_I2C_ELEKTOR) += i2c-elektor.o +obj-$(CONFIG_I2C_ALGO8XX) += i2c-algo-8xx.o +obj-$(CONFIG_I2C_RPXLITE) += i2c-rpx.o # This is needed for automatic patch generation: sensors code starts here # This is needed for automatic patch generation: sensors code ends here diff -Nru a/drivers/i2c/i2c-algo-8xx.c b/drivers/i2c/i2c-algo-8xx.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/i2c/i2c-algo-8xx.c Sat Jun 16 06:00:32 2001 @@ -0,0 +1,565 @@ +/* + * i2c-algo-8xx.c i2x driver algorithms for MPC8XX CPM + * Copyright (c) 1999 Dan Malek (dmalek@jlc.net). + * + * moved into proper i2c interface; separated out platform specific + * parts into i2c-rpx.c + * Brad Parker (brad@heeltoe.com) + */ + +// XXX todo +// timeout sleep? + +/* $Id$ */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../../arch/ppc/8xx_io/commproc.h" + +#include +#include + +#define CPM_MAX_READ 513 + +static wait_queue_head_t iic_wait; +static ushort r_tbase, r_rbase; + +int cpm_scan = 0; +int cpm_debug = 1; + +static void +cpm_iic_interrupt(void *dev_id) +{ + volatile i2c8xx_t *i2c = (i2c8xx_t *)dev_id; + + if (cpm_debug > 1) + printk("cpm_iic_interrupt(dev_id=%p)\n", dev_id); + + /* Chip errata, clear enable. + */ + i2c->i2c_i2mod = 0; + + /* Clear interrupt. + */ + i2c->i2c_i2cer = 0xff; + + /* Get 'me going again. + */ + wake_up_interruptible(&iic_wait); +} + +static void +cpm_iic_init(struct i2c_algo_8xx_data *cpm_adap) +{ + volatile iic_t *iip = cpm_adap->iip; + volatile i2c8xx_t *i2c = cpm_adap->i2c; + + if (cpm_debug) printk("cpm_iic_init()\n"); + + /* Initialize the parameter ram. + * We need to make sure many things are initialized to zero, + * especially in the case of a microcode patch. + */ + iip->iic_rstate = 0; + iip->iic_rdp = 0; + iip->iic_rbptr = 0; + iip->iic_rbc = 0; + iip->iic_rxtmp = 0; + iip->iic_tstate = 0; + iip->iic_tdp = 0; + iip->iic_tbptr = 0; + iip->iic_tbc = 0; + iip->iic_txtmp = 0; + + /* Set up the IIC parameters in the parameter ram. + */ + iip->iic_tbase = r_tbase = cpm_adap->dp_addr; + iip->iic_rbase = r_rbase = cpm_adap->dp_addr + sizeof(cbd_t)*2; + + iip->iic_tfcr = SMC_EB; + iip->iic_rfcr = SMC_EB; + + /* Set maximum receive size. + */ + iip->iic_mrblr = CPM_MAX_READ; + + /* Initialize Tx/Rx parameters. + */ + if (cpm_adap->reloc == 0) { + volatile cpm8xx_t *cp = cpm_adap->cp; + + cp->cp_cpcr = + mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_INIT_TRX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + } + + /* Select an arbitrary address. Just make sure it is unique. + */ + i2c->i2c_i2add = 0x34; + + /* Make clock run maximum slow. + */ + i2c->i2c_i2brg = 7; + + /* Disable interrupts. + */ + i2c->i2c_i2cmr = 0; + i2c->i2c_i2cer = 0xff; + + init_waitqueue_head(&iic_wait); + + /* Install interrupt handler. + */ + (*cpm_adap->setisr)(CPMVEC_I2C, cpm_iic_interrupt, (void *)i2c); +} + + +static int +cpm_iic_shutdown(struct i2c_algo_8xx_data *cpm_adap) +{ + volatile i2c8xx_t *i2c = cpm_adap->i2c; + + /* Shut down IIC. + */ + i2c->i2c_i2mod = 0; + i2c->i2c_i2cmr = 0; + i2c->i2c_i2cer = 0xff; + + return(0); +} + +static void +cpm_reset_iic_params(volatile iic_t *iip) +{ + iip->iic_tbase = r_tbase; + iip->iic_rbase = r_rbase; + + iip->iic_tfcr = SMC_EB; + iip->iic_rfcr = SMC_EB; + + iip->iic_mrblr = CPM_MAX_READ; + + iip->iic_rstate = 0; + iip->iic_rdp = 0; + iip->iic_rbptr = 0; + iip->iic_rbc = 0; + iip->iic_rxtmp = 0; + iip->iic_tstate = 0; + iip->iic_tdp = 0; + iip->iic_tbptr = 0; + iip->iic_tbc = 0; + iip->iic_txtmp = 0; +} + +#define BD_SC_NAK ((ushort)0x0004) /* NAK - did not respond */ +#define CPM_CR_CLOSE_RXBD ((ushort)0x0007) + +static void force_close(struct i2c_algo_8xx_data *cpm) +{ + if (cpm->reloc == 0) { + volatile cpm8xx_t *cp = cpm->cp; + + if (cpm_debug) printk("force_close()\n"); + cp->cp_cpcr = + mk_cr_cmd(CPM_CR_CH_I2C, CPM_CR_CLOSE_RXBD) | + CPM_CR_FLG; + + while (cp->cp_cpcr & CPM_CR_FLG); + } +} + + +/* Read from IIC... + * abyte = address byte, with r/w flag already set + */ +static int +cpm_iic_read(struct i2c_algo_8xx_data *cpm, u_char abyte, char *buf, int count) +{ + volatile iic_t *iip = cpm->iip; + volatile i2c8xx_t *i2c = cpm->i2c; + volatile cpm8xx_t *cp = cpm->cp; + volatile cbd_t *tbdf, *rbdf; + u_char *tb; + unsigned long flags; + + if (count >= CPM_MAX_READ) + return -EINVAL; + + /* check for and use a microcode relocation patch */ + if (cpm->reloc) { + cpm_reset_iic_params(iip); + } + + tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; + rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase]; + + /* To read, we need an empty buffer of the proper length. + * All that is used is the first byte for address, the remainder + * is just used for timing (and doesn't really have to exist). + */ + if (cpm->reloc) { + cpm_reset_iic_params(iip); + } + tb = cpm->temp; + tb = (u_char *)(((uint)tb + 15) & ~15); + tb[0] = abyte; /* Device address byte w/rw flag */ + + flush_dcache_range(tb, tb+1); + + if (cpm_debug) printk("cpm_iic_read(abyte=0x%x)\n", abyte); + + tbdf->cbd_bufaddr = __pa(tb); + tbdf->cbd_datlen = count + 1; + tbdf->cbd_sc = + BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | + BD_SC_WRAP | BD_IIC_START; + + rbdf->cbd_datlen = 0; + rbdf->cbd_bufaddr = __pa(buf); + rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; + + /* Chip bug, set enable here */ + save_flags(flags); cli(); + i2c->i2c_i2cmr = 0x13; /* Enable some interupts */ + i2c->i2c_i2cer = 0xff; + i2c->i2c_i2mod = 1; /* Enable */ + i2c->i2c_i2com = 0x81; /* Start master */ + + /* Wait for IIC transfer */ + interruptible_sleep_on(&iic_wait); + restore_flags(flags); + if (signal_pending(current)) + return -EIO; + + if (cpm_debug) { + printk("tx sc %04x, rx sc %04x\n", + tbdf->cbd_sc, rbdf->cbd_sc); + } + + if (tbdf->cbd_sc & BD_SC_NAK) { + printk("IIC read; no ack\n"); + return 0; + } + + if (rbdf->cbd_sc & BD_SC_EMPTY) { + printk("IIC read; complete but rbuf empty\n"); + force_close(cpm); + printk("tx sc %04x, rx sc %04x\n", + tbdf->cbd_sc, rbdf->cbd_sc); + } + + if (cpm_debug) printk("read %d bytes\n", rbdf->cbd_datlen); + + if (rbdf->cbd_datlen < count) { + printk("IIC read; short, wanted %d got %d\n", + count, rbdf->cbd_datlen); + return 0; + } + + + invalidate_dcache_range(buf, buf+count); + + return count; +} + +/* Write to IIC... + * addr = address byte, with r/w flag already set + */ +static int +cpm_iic_write(struct i2c_algo_8xx_data *cpm, u_char abyte, char *buf,int count) +{ + volatile iic_t *iip = cpm->iip; + volatile i2c8xx_t *i2c = cpm->i2c; + volatile cpm8xx_t *cp = cpm->cp; + volatile cbd_t *tbdf; + u_char *tb; + unsigned long flags; + + /* check for and use a microcode relocation patch */ + if (cpm->reloc) { + cpm_reset_iic_params(iip); + } + tb = cpm->temp; + tb = (u_char *)(((uint)tb + 15) & ~15); + *tb = abyte; /* Device address byte w/rw flag */ + + flush_dcache_range(tb, tb+1); + flush_dcache_range(buf, buf+count); + + if (cpm_debug) printk("cpm_iic_write(abyte=0x%x)\n", abyte); + + /* set up 2 descriptors */ + tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; + + tbdf[0].cbd_bufaddr = __pa(tb); + tbdf[0].cbd_datlen = 1; + tbdf[0].cbd_sc = BD_SC_READY | BD_IIC_START; + + tbdf[1].cbd_bufaddr = __pa(buf); + tbdf[1].cbd_datlen = count; + tbdf[1].cbd_sc = BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | BD_SC_WRAP; + + /* Chip bug, set enable here */ + save_flags(flags); cli(); + i2c->i2c_i2cmr = 0x13; /* Enable some interupts */ + i2c->i2c_i2cer = 0xff; + i2c->i2c_i2mod = 1; /* Enable */ + i2c->i2c_i2com = 0x81; /* Start master */ + + /* Wait for IIC transfer */ + interruptible_sleep_on(&iic_wait); + restore_flags(flags); + if (signal_pending(current)) + return -EIO; + + if (cpm_debug) { + printk("tx0 sc %04x, tx1 sc %04x\n", + tbdf[0].cbd_sc, tbdf[1].cbd_sc); + } + + if (tbdf->cbd_sc & BD_SC_NAK) { + printk("IIC write; no ack\n"); + return 0; + } + + if (tbdf->cbd_sc & BD_SC_READY) { + printk("IIC write; complete but tbuf ready\n"); + return 0; + } + + return count; +} + +/* See if an IIC address exists.. + * addr = 7 bit address, unshifted + */ +static int +cpm_iic_tryaddress(struct i2c_algo_8xx_data *cpm, int addr) +{ + volatile iic_t *iip = cpm->iip; + volatile i2c8xx_t *i2c = cpm->i2c; + volatile cpm8xx_t *cp = cpm->cp; + volatile cbd_t *tbdf, *rbdf; + u_char *tb; + unsigned long flags, len; + + if (cpm_debug > 1) + printk("cpm_iic_tryaddress(cpm=%p,addr=%d)\n", cpm, addr); + + /* check for and use a microcode relocation patch */ + if (cpm->reloc) { + cpm_reset_iic_params(iip); + } + + if (cpm_debug && addr == 0) { + printk("iip %p, dp_addr 0x%x\n", cpm->iip, cpm->dp_addr); + printk("iic_tbase %d, r_tbase %d\n", iip->iic_tbase, r_tbase); + } + + tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; + rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase]; + + tb = cpm->temp; + tb = (u_char *)(((uint)tb + 15) & ~15); + + /* do a simple read */ + tb[0] = (addr << 1) | 1; /* device address (+ read) */ + len = 2; + + flush_dcache_range(tb, tb+1); + + tbdf->cbd_bufaddr = __pa(tb); + tbdf->cbd_datlen = len; + tbdf->cbd_sc = + BD_SC_READY | BD_SC_INTRPT | BD_SC_LAST | + BD_SC_WRAP | BD_IIC_START; + + rbdf->cbd_datlen = 0; + rbdf->cbd_bufaddr = __pa(tb+2); + rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; + + save_flags(flags); cli(); + i2c->i2c_i2cmr = 0x13; /* Enable some interupts */ + i2c->i2c_i2cer = 0xff; + i2c->i2c_i2mod = 1; /* Enable */ + i2c->i2c_i2com = 0x81; /* Start master */ + + if (cpm_debug > 1) printk("about to sleep\n"); + + /* wait for IIC transfer */ + interruptible_sleep_on(&iic_wait); + restore_flags(flags); + if (signal_pending(current)) + return -EIO; + + if (cpm_debug > 1) printk("back from sleep\n"); + + if (tbdf->cbd_sc & BD_SC_NAK) { + if (cpm_debug > 1) printk("IIC try; no ack\n"); + return 0; + } + + if (tbdf->cbd_sc & BD_SC_READY) { + printk("IIC try; complete but tbuf ready\n"); + } + + return 1; +} + +static int cpm_xfer(struct i2c_adapter *i2c_adap, + struct i2c_msg msgs[], + int num) +{ + struct i2c_algo_8xx_data *adap = i2c_adap->algo_data; + struct i2c_msg *pmsg; + int i, ret; + u_char addr; + + for (i = 0; i < num; i++) { + pmsg = &msgs[i]; + + if (cpm_debug) + printk("i2c-algo-8xx.o: " + "#%d addr=0x%x flags=0x%x len=%d\n", + i, pmsg->addr, pmsg->flags, pmsg->len); + + addr = pmsg->addr << 1; + if (pmsg->flags & I2C_M_RD ) + addr |= 1; + if (pmsg->flags & I2C_M_REV_DIR_ADDR ) + addr ^= 1; + + if (!(pmsg->flags & I2C_M_NOSTART)) { + } + if (pmsg->flags & I2C_M_RD ) { + /* read bytes into buffer*/ + ret = cpm_iic_read(adap, addr, pmsg->buf, pmsg->len); + if (cpm_debug) + printk("i2c-algo-8xx.o: read %d bytes\n", ret); + if (ret < pmsg->len ) { + return (ret<0)? ret : -EREMOTEIO; + } + } else { + /* write bytes from buffer */ + ret = cpm_iic_write(adap, addr, pmsg->buf, pmsg->len); + if (cpm_debug) + printk("i2c-algo-8xx.o: wrote %d\n", ret); + if (ret < pmsg->len ) { + return (ret<0) ? ret : -EREMOTEIO; + } + } + } + return (num); +} + +static int algo_control(struct i2c_adapter *adapter, + unsigned int cmd, unsigned long arg) +{ + return 0; +} + +static u32 cpm_func(struct i2c_adapter *adap) +{ + return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | + I2C_FUNC_PROTOCOL_MANGLING; +} + +/* -----exported algorithm data: ------------------------------------- */ + +static struct i2c_algorithm cpm_algo = { + "MPX8XX CPM algorithm", + I2C_ALGO_MPC8XX, + cpm_xfer, + NULL, + NULL, /* slave_xmit */ + NULL, /* slave_recv */ + algo_control, /* ioctl */ + cpm_func, /* functionality */ +}; + +/* + * registering functions to load algorithms at runtime + */ +int i2c_8xx_add_bus(struct i2c_adapter *adap) +{ + int i; + struct i2c_algo_8xx_data *cpm_adap = adap->algo_data; + + if (cpm_debug) + printk("i2c-algo-8xx.o: hw routines for %s registered.\n", + adap->name); + + /* register new adapter to i2c module... */ + + adap->id |= cpm_algo.id; + adap->algo = &cpm_algo; + + MOD_INC_USE_COUNT; + + i2c_add_adapter(adap); + cpm_iic_init(cpm_adap); + + /* scan bus */ + if (cpm_scan) { + printk(KERN_INFO " i2c-algo-8xx.o: scanning bus %s...\n", + adap->name); + for (i = 0; i < 128; i++) { + if (cpm_iic_tryaddress(cpm_adap, i)) { + printk("(%02x)",i<<1); + } + } + printk("\n"); + } + return 0; +} + + +int i2c_8xx_del_bus(struct i2c_adapter *adap) +{ + int res; + struct i2c_algo_8xx_data *cpm_adap = adap->algo_data; + + cpm_iic_shutdown(cpm_adap); + + if ((res = i2c_del_adapter(adap)) < 0) + return res; + + printk("i2c-algo-8xx.o: adapter unregistered: %s\n",adap->name); + MOD_DEC_USE_COUNT; + + return 0; +} + +EXPORT_SYMBOL(i2c_8xx_add_bus); +EXPORT_SYMBOL(i2c_8xx_del_bus); + +int __init i2c_algo_8xx_init (void) +{ + printk("i2c-algo-8xx.o: i2c mpc8xx algorithm module\n"); + return 0; +} + + +#ifdef MODULE +MODULE_AUTHOR("Brad Parker "); +MODULE_DESCRIPTION("I2C-Bus MPC8XX algorithm"); + +int init_module(void) +{ + return i2c_algo_8xx_init(); +} + +void cleanup_module(void) +{ +} +#endif diff -Nru a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c --- a/drivers/i2c/i2c-core.c Sat Jun 16 06:00:30 2001 +++ b/drivers/i2c/i2c-core.c Sat Jun 16 06:00:30 2001 @@ -1285,6 +1285,8 @@ extern int i2c_bitvia_init(void); extern int i2c_algo_pcf_init(void); extern int i2c_pcfisa_init(void); + extern int i2c_algo_8xx_init(void); + extern int i2c_rpx_init(void); /* This is needed for automatic patch generation: sensors code starts here */ /* This is needed for automatic patch generation: sensors code ends here */ @@ -1318,6 +1320,15 @@ #ifdef CONFIG_I2C_ELEKTOR i2c_pcfisa_init(); #endif + + /* --------------------- 8xx -------- */ +#ifdef CONFIG_I2C_ALGO8XX + i2c_algo_8xx_init(); +#endif +#ifdef CONFIG_I2C_RPXLITE + i2c_rpx_init(); +#endif + /* This is needed for automatic patch generation: sensors code starts here */ /* This is needed for automatic patch generation: sensors code ends here */ diff -Nru a/drivers/i2c/i2c-rpx.c b/drivers/i2c/i2c-rpx.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/i2c/i2c-rpx.c Sat Jun 16 06:00:30 2001 @@ -0,0 +1,133 @@ +/* + * Embedded Planet RPX Lite MPC8xx CPM I2C interface. + * Copyright (c) 1999 Dan Malek (dmalek@jlc.net). + * + * moved into proper i2c interface; + * Brad Parker (brad@heeltoe.com) + * + * RPX lite specific parts of the i2c interface + */ + +#include +#include +#include +#include +#include +#include + +#include +#include "../../arch/ppc/8xx_io/commproc.h" + +#include +#include + +static void +rpx_iic_init(struct i2c_algo_8xx_data *data) +{ + volatile cpm8xx_t *cp; + volatile immap_t *immap; + + cp = cpmp; /* Get pointer to Communication Processor */ + immap = (immap_t *)IMAP_ADDR; /* and to internal registers */ + + data->iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; + + /* Check for and use a microcode relocation patch. + */ + if ((data->reloc = data->iip->iic_rpbase)) + data->iip = (iic_t *)&cp->cp_dpmem[data->iip->iic_rpbase]; + + data->i2c = (i2c8xx_t *)&(immap->im_i2c); + data->cp = cp; + + /* Initialize Port B IIC pins. + */ + cp->cp_pbpar |= 0x00000030; + cp->cp_pbdir |= 0x00000030; + cp->cp_pbodr |= 0x00000030; + + /* Allocate space for two transmit and two receive buffer + * descriptors in the DP ram. + */ + data->dp_addr = m8xx_cpm_dpalloc(sizeof(cbd_t) * 4); + + /* ptr to i2c area */ + data->i2c = (i2c8xx_t *)&(((immap_t *)IMAP_ADDR)->im_i2c); +} + +static int rpx_install_isr(int irq, void (*func)(void *), void *data) +{ + /* install interrupt handler */ + cpm_install_handler(irq, func, data); + + return 0; +} + +static int rpx_reg(struct i2c_client *client) +{ + return 0; +} + +static int rpx_unreg(struct i2c_client *client) +{ + return 0; +} + +static void rpx_inc_use(struct i2c_adapter *adap) +{ +#ifdef MODULE + MOD_INC_USE_COUNT; +#endif +} + +static void rpx_dec_use(struct i2c_adapter *adap) +{ +#ifdef MODULE + MOD_DEC_USE_COUNT; +#endif +} + +static struct i2c_algo_8xx_data rpx_data = { + setisr: rpx_install_isr +}; + + +static struct i2c_adapter rpx_ops = { + "rpx", + I2C_HW_MPC8XX_EPON, + NULL, + &rpx_data, + rpx_inc_use, + rpx_dec_use, + rpx_reg, + rpx_unreg, +}; + +int __init i2c_rpx_init(void) +{ + printk("i2c-rpx.o: i2c RPX Lite module\n"); + + /* reset hardware to sane state */ + rpx_iic_init(&rpx_data); + + if (i2c_8xx_add_bus(&rpx_ops) < 0) { + printk("i2c-rpx: Unable to register with I2C\n"); + return -ENODEV; + } + + return 0; +} + +void __exit i2c_rpx_exit(void) +{ + i2c_8xx_del_bus(&rpx_ops); +} + +#ifdef MODULE +MODULE_AUTHOR("Dan Malek "); +MODULE_DESCRIPTION("I2C-Bus adapter routines for EP RPX Lite"); + +module_init(i2c_rpx_init); +module_exit(i2c_rpx_exit); +#endif + diff -Nru a/drivers/ide/ide-features.c b/drivers/ide/ide-features.c --- a/drivers/ide/ide-features.c Sat Jun 16 06:00:15 2001 +++ b/drivers/ide/ide-features.c Sat Jun 16 06:00:15 2001 @@ -287,7 +287,11 @@ #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) byte unit = (drive->select.b.unit & 0x01); - outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); + /* Some interfaces would like to use this routine, but don"t have this + * kind of DMA engine. --BenH. + */ + if (hwif->dma_base) + outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); #endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ /* @@ -356,10 +360,15 @@ drive->id->dma_1word &= ~0x0F00; #if defined(CONFIG_BLK_DEV_IDEDMA) && !defined(CONFIG_DMA_NONPCI) - if (speed > XFER_PIO_4) { - outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2); - } else { - outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); + /* Some interfaces would like to use this routine, but don"t have this + * kind of DMA engine. --BenH. + */ + if (hwif->dma_base) { + if (speed > XFER_PIO_4) { + outb(inb(hwif->dma_base+2)|(1<<(5+unit)), hwif->dma_base+2); + } else { + outb(inb(hwif->dma_base+2) & ~(1<<(5+unit)), hwif->dma_base+2); + } } #endif /* (CONFIG_BLK_DEV_IDEDMA) && !(CONFIG_DMA_NONPCI) */ diff -Nru a/drivers/ide/sl82c105.c b/drivers/ide/sl82c105.c --- a/drivers/ide/sl82c105.c Sat Jun 16 06:00:16 2001 +++ b/drivers/ide/sl82c105.c Sat Jun 16 06:00:16 2001 @@ -129,10 +129,10 @@ pci_read_config_dword(dev, 0x44, &t32); printk("IDE timing: %08x, resetting to PIO0 timing\n",t32); pci_write_config_dword(dev, 0x44, 0x03e4); -#ifndef CONFIG_MBX +#ifndef __powerpc__ /* what arch actually needs this?? */ pci_read_config_dword(dev, 0x40, &t32); printk("IDE control/status register: %08x\n",t32); pci_write_config_dword(dev, 0x40, 0x10ff08a1); -#endif /* CONFIG_MBX */ +#endif /* __powerpc__ */ #endif } diff -Nru a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c --- a/drivers/macintosh/mac_hid.c Sat Jun 16 06:00:15 2001 +++ b/drivers/macintosh/mac_hid.c Sat Jun 16 06:00:15 2001 @@ -15,6 +15,7 @@ #include #include #include +#include #ifdef CONFIG_MAC_ADBKEYCODES #include @@ -401,6 +402,8 @@ return keyboard_sends_linux_keycodes; } +EXPORT_SYMBOL(mac_hid_keyboard_sends_linux_keycodes); + static int __init mac_hid_setup(char *str) { int ints[2]; @@ -448,6 +451,8 @@ return 0; } +EXPORT_SYMBOL(mac_hid_mouse_emulate_buttons); + static void emumousebtn_input_register(void) { emumousebtn.name = "Macintosh mouse button emulation"; @@ -473,9 +478,19 @@ #ifdef CONFIG_MAC_ADBKEYCODES memcpy(pc_key_maps_save, key_maps, sizeof(key_maps)); - if (!keyboard_sends_linux_keycodes) + if (!keyboard_sends_linux_keycodes) { +#ifdef CONFIG_MAGIC_SYSRQ + ppc_md.ppc_kbd_sysrq_xlate = mac_hid_kbd_sysrq_xlate; + SYSRQ_KEY = 0x69; +#endif memcpy(key_maps, mac_key_maps_save, sizeof(key_maps)); + } else { +#ifdef CONFIG_MAGIC_SYSRQ + ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate; + SYSRQ_KEY = 0x54; #endif + } +#endif /* CONFIG_MAC_ADBKEYCODES */ #ifdef CONFIG_MAC_EMUMOUSEBTN emumousebtn_input_register(); diff -Nru a/drivers/macintosh/mac_keyb.c b/drivers/macintosh/mac_keyb.c --- a/drivers/macintosh/mac_keyb.c Sat Jun 16 06:00:19 2001 +++ b/drivers/macintosh/mac_keyb.c Sat Jun 16 06:00:19 2001 @@ -305,7 +305,7 @@ return 1; } -int mackbd_unexpected_up(unsigned char keycode) +char mackbd_unexpected_up(unsigned char keycode) { return 0x80; } diff -Nru a/drivers/macintosh/macserial.c b/drivers/macintosh/macserial.c --- a/drivers/macintosh/macserial.c Sat Jun 16 06:00:23 2001 +++ b/drivers/macintosh/macserial.c Sat Jun 16 06:00:23 2001 @@ -448,7 +448,7 @@ goto out; info->tx_active = 0; - if (info->x_char) { + if (info->x_char && !info->power_wait) { /* Send next char */ write_zsdata(info->zs_channel, info->x_char); info->x_char = 0; @@ -456,7 +456,8 @@ goto out; } - if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tx_stopped) { + if ((info->xmit_cnt <= 0) || info->tty->stopped || info->tx_stopped + || info->power_wait) { write_zsreg(info->zs_channel, 0, RES_Tx_P); goto out; } @@ -474,6 +475,14 @@ restore_flags(flags); } +static void powerup_done(unsigned long data) +{ + struct mac_serial *info = (struct mac_serial *) data; + + info->power_wait = 0; + transmit_chars(info); +} + static _INLINE_ void status_handle(struct mac_serial *info) { unsigned char status; @@ -730,7 +739,7 @@ } } -static int startup(struct mac_serial * info, int can_sleep) +static int startup(struct mac_serial * info) { int delay; @@ -753,6 +762,18 @@ setup_scc(info); + if (delay) { + unsigned long flags; + + /* delay is in ms */ + save_flags(flags); + cli(); + info->power_wait = 1; + mod_timer(&info->powerup_timer, + jiffies + (delay * HZ + 999) / 1000); + restore_flags(flags); + } + OPNDBG("enabling IRQ on ttyS%d (irq %d)...\n", info->line, info->irq); info->flags |= ZILOG_INITIALIZED; @@ -761,15 +782,6 @@ enable_irq(info->rx_dma_irq); } - if (delay) { - if (can_sleep) { - /* we need to wait a bit before using the port */ - current->state = TASK_INTERRUPTIBLE; - schedule_timeout(delay * HZ / 1000); - } else - mdelay(delay); - } - return 0; } @@ -863,7 +875,7 @@ queue_task(&tty->flip.tqueue, &tq_timer); } -static void poll_rxdma(void *private_) +static void poll_rxdma(unsigned long private_) { struct mac_serial *info = (struct mac_serial *) private_; unsigned long flags; @@ -2325,7 +2337,7 @@ * Start up serial port */ - retval = startup(info, 1); + retval = startup(info); if (retval) return retval; @@ -2426,6 +2438,10 @@ zss->rx_dma_irq = ch->intrs[2].line; spin_lock_init(&zss->rx_dma_lock); } + + init_timer(&zss->powerup_timer); + zss->powerup_timer.function = powerup_done; + zss->powerup_timer.data = (unsigned long) zss; } /* Ask the PROM how many Z8530s we have and initialize their zs_channels */ @@ -2680,14 +2696,7 @@ return 0; } -#ifdef MODULE -int init_module(void) -{ - macserial_init(); - return 0; -} - -void cleanup_module(void) +void macserial_cleanup(void) { int i; unsigned long flags; @@ -2717,7 +2726,9 @@ pmu_unregister_sleep_notifier(&serial_sleep_notifier); #endif /* CONFIG_PMAC_PBOOK */ } -#endif /* MODULE */ + +module_init(macserial_init); +module_exit(macserial_cleanup); #if 0 /* @@ -3119,7 +3130,7 @@ struct mac_serial *info = &zs_soft[i]; if (info->flags & ZILOG_SLEEPING) { info->flags &= ~ZILOG_SLEEPING; - startup(info, 0); + startup(info); } } break; diff -Nru a/drivers/macintosh/macserial.h b/drivers/macintosh/macserial.h --- a/drivers/macintosh/macserial.h Sat Jun 16 06:00:30 2001 +++ b/drivers/macintosh/macserial.h Sat Jun 16 06:00:30 2001 @@ -115,6 +115,7 @@ char is_irda; /* is connected to an IrDA codec */ unsigned char tx_active; /* character is being xmitted */ unsigned char tx_stopped; /* output is suspended */ + unsigned char power_wait; /* waiting for power-up delay to expire */ /* We need to know the current clock divisor * to read the bps rate the chip has currently @@ -186,6 +187,8 @@ void *dma_priv; struct timer_list poll_dma_timer; #define RX_DMA_TIMER (jiffies + 10*HZ/1000) + + struct timer_list powerup_timer; }; diff -Nru a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c --- a/drivers/macintosh/via-pmu.c Sat Jun 16 06:00:18 2001 +++ b/drivers/macintosh/via-pmu.c Sat Jun 16 06:00:18 2001 @@ -1431,7 +1431,7 @@ _set_L2CR(save_l2cr); /* Restore userland MMU context */ - set_context(current->mm->context, current->mm->pgd); + set_context(current->mm->context); /* Re-enable DEC interrupts and kick DEC */ asm volatile("mtdec %0" : : "r" (0x7fffffff)); @@ -1560,7 +1560,7 @@ feature_wake_up(); pbook_pci_restore(); - set_context(current->mm->context, current->mm->pgd); + set_context(current->mm->context); /* Restore L2 cache */ if (save_l2cr) diff -Nru a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c --- a/drivers/net/ne2k-pci.c Sat Jun 16 06:00:18 2001 +++ b/drivers/net/ne2k-pci.c Sat Jun 16 06:00:18 2001 @@ -62,8 +62,6 @@ #if defined(__powerpc__) #define inl_le(addr) le32_to_cpu(inl(addr)) #define inw_le(addr) le16_to_cpu(inw(addr)) -#define insl insl_ns -#define outsl outsl_ns #endif MODULE_AUTHOR("Donald Becker / Paul Gortmaker"); diff -Nru a/drivers/pci/Makefile b/drivers/pci/Makefile --- a/drivers/pci/Makefile Sat Jun 16 06:00:24 2001 +++ b/drivers/pci/Makefile Sat Jun 16 06:00:24 2001 @@ -26,7 +26,7 @@ obj-$(CONFIG_ALPHA) += setup-bus.o setup-irq.o obj-$(CONFIG_ARM) += setup-bus.o setup-irq.o obj-$(CONFIG_SUPERH) += setup-bus.o setup-irq.o -obj-$(CONFIG_ALL_PPC) += setup-bus.o +obj-$(CONFIG_PPC) += setup-bus.o setup-irq.o ifndef CONFIG_X86 obj-y += syscall.o diff -Nru a/drivers/scsi/sym53c8xx_defs.h b/drivers/scsi/sym53c8xx_defs.h --- a/drivers/scsi/sym53c8xx_defs.h Sat Jun 16 06:00:23 2001 +++ b/drivers/scsi/sym53c8xx_defs.h Sat Jun 16 06:00:23 2001 @@ -168,16 +168,12 @@ #endif /* - * Use normal IO if configured. Forced for alpha and powerpc. - * Powerpc fails copying to on-chip RAM using memcpy_toio(). + * Use normal IO if configured. Forced for alpha. */ #if defined(CONFIG_SCSI_NCR53C8XX_IOMAPPED) #define SCSI_NCR_IOMAPPED #elif defined(__alpha__) #define SCSI_NCR_IOMAPPED -#elif defined(__powerpc__) -#define SCSI_NCR_IOMAPPED -#define SCSI_NCR_PCI_MEM_NOT_SUPPORTED #elif defined(__sparc__) #undef SCSI_NCR_IOMAPPED #endif diff -Nru a/drivers/sgi/char/linux_logo.h b/drivers/sgi/char/linux_logo.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/drivers/sgi/char/linux_logo.h Sat Jun 16 06:00:31 2001 @@ -0,0 +1,909 @@ +/* This is a linux logo to be displayed on boot. + * + * You can put anything here, but: + * LINUX_LOGO_COLORS has to be less than 224 + * image size has to be 80x80 + * values have to start from0x20 + * (i.e. RGB(linux_logo_red[0], + * linux_logo_green[0], + * linux_logo_blue[0]) is color0x20) + */ + +#define LINUX_LOGO_COLORS 221 + +unsigned char linux_logo_red[] = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, + 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xE5, + 0xF1, 0xED, 0xEE, 0xE6, 0xC6, 0xDA, 0xDD, 0xE5, + 0xD9, 0xC6, 0xE3, 0xD0, 0xC6, 0xBA, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xB0, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x9D, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x0D, 0x03, + 0x66, 0x44, 0x24, 0x08, 0xD6, 0xE6, 0xE9, 0xE6, + 0xE7, 0xCA, 0xDC, 0xDB, 0xD5, 0xD0, 0xC9, 0xE2, + 0xD5, 0xC6, 0xC4, 0xB3, 0xB2, 0xB9, 0xA9, 0x9A, + 0xB2, 0x9D, 0xE8, 0xEC, 0xF5, 0xF5, 0xF4, 0xF4, + 0xEC, 0xEE, 0xF0, 0xF5, 0xE0, 0xD6, 0xC5, 0xC2, + 0xD9, 0xD5, 0xD8, 0xD6, 0xF6, 0xF4, 0xED, 0xEC, + 0xEB, 0xF1, 0xF6, 0xF5, 0xF5, 0xEE, 0xEF, 0xEC, + 0xE7, 0xE3, 0xE6, 0xD6, 0xDD, 0xC3, 0xD6, 0xD7, + 0xCD, 0xCA, 0xC3, 0xAC, 0x95, 0x99, 0xB7, 0xA3, + 0x8B, 0x88, 0x95, 0x8A, 0x94, 0xD2, 0xCC, 0xC4, + 0xA8, 0x8E, 0x8F, 0xAE, 0xB8, 0xAC, 0xB6, 0xB4, + 0xAD, 0xA5, 0xA0, 0x9B, 0x8B, 0xA3, 0x94, 0x87, + 0x85, 0x89, 0x53, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x0F, 0x75, 0x78, 0x7D, 0x72, 0x5F, 0x6E, + 0x7A, 0x75, 0x6A, 0x58, 0x48, 0x4F, 0x00, 0x2B, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x3B, 0x11, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo_green[] = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xE7, 0xE5, 0xE3, + 0xCA, 0xD4, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xD3, + 0xDA, 0xD4, 0xD7, 0xCC, 0xC1, 0xCC, 0xCB, 0xC9, + 0xC5, 0xBC, 0xBC, 0xBB, 0xB7, 0xA5, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xAD, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA0, 0x95, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x99, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0x08, 0x02, + 0x53, 0x2E, 0x19, 0x06, 0xC6, 0xC8, 0xCF, 0xBD, + 0xB3, 0xB6, 0xB4, 0xAB, 0xA5, 0xA3, 0x9B, 0xB6, + 0xA7, 0x99, 0x92, 0xA4, 0x9E, 0x9D, 0x98, 0x8C, + 0x8A, 0x86, 0xCD, 0xCC, 0xC9, 0xD7, 0xCA, 0xC4, + 0xCA, 0xC3, 0xC7, 0xC3, 0xC8, 0xB4, 0x91, 0x8E, + 0x8A, 0x82, 0x87, 0x85, 0xBD, 0xBF, 0xB6, 0xBC, + 0xAE, 0xB7, 0xBC, 0xB8, 0xBF, 0xB6, 0xBC, 0xB5, + 0xAB, 0xA6, 0xAD, 0xB2, 0xA5, 0x87, 0x9C, 0x96, + 0x95, 0x8E, 0x87, 0x8F, 0x86, 0x86, 0x8E, 0x80, + 0x7A, 0x70, 0x7B, 0x78, 0x78, 0x7F, 0x77, 0x6F, + 0x70, 0x76, 0x59, 0x77, 0x68, 0x64, 0x7B, 0x7C, + 0x75, 0x6D, 0x77, 0x69, 0x65, 0x5F, 0x5B, 0x54, + 0x4F, 0x5B, 0x39, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x67, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x53, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x0B, 0x69, 0x66, 0x64, 0x57, 0x4A, 0x4E, + 0x55, 0x4B, 0x46, 0x3B, 0x30, 0x33, 0x00, 0x2B, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x29, 0x0D, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo_blue[] = { + 0xF3, 0xF6, 0xF8, 0xF7, 0xEF, 0xEE, 0xE5, 0xDE, + 0xD7, 0xD3, 0xDD, 0xC8, 0xC7, 0xC4, 0xC2, 0xB5, + 0xB0, 0xA6, 0xAC, 0x9B, 0xB5, 0xB5, 0xAE, 0x84, + 0x90, 0xA9, 0x81, 0x8D, 0x96, 0x86, 0xB0, 0xB6, + 0xBB, 0xBE, 0xB9, 0xB8, 0xB3, 0xB2, 0xA7, 0xAD, + 0xAC, 0xA9, 0xA8, 0xA6, 0xA4, 0xA1, 0xA5, 0x87, + 0xA0, 0x9F, 0x9E, 0x9C, 0x9B, 0x9A, 0x9A, 0x99, + 0x98, 0x95, 0x96, 0x94, 0x93, 0x92, 0x8F, 0x8D, + 0x8C, 0x8A, 0x87, 0x86, 0x83, 0x81, 0xC8, 0xD7, + 0x9B, 0x8E, 0x8C, 0xB2, 0x77, 0x77, 0x4E, 0x77, + 0x69, 0x71, 0x78, 0x6B, 0x65, 0x66, 0x64, 0x59, + 0x5C, 0x5A, 0x48, 0x72, 0x7B, 0x6B, 0x67, 0x6E, + 0x42, 0x5B, 0x29, 0x36, 0x25, 0x10, 0x17, 0x14, + 0x19, 0x16, 0x13, 0x0E, 0x08, 0x2E, 0x2E, 0x3D, + 0x24, 0x24, 0x24, 0x24, 0x13, 0x12, 0x14, 0x14, + 0x0E, 0x08, 0x0D, 0x0F, 0x08, 0x0D, 0x0E, 0x08, + 0x08, 0x0C, 0x06, 0x06, 0x07, 0x16, 0x07, 0x0E, + 0x08, 0x0A, 0x07, 0x0D, 0x2D, 0x3E, 0x09, 0x4E, + 0x68, 0x52, 0x56, 0x58, 0x4B, 0x22, 0x20, 0x20, + 0x27, 0x39, 0x28, 0x19, 0x1E, 0x1E, 0x08, 0x06, + 0x07, 0x09, 0x08, 0x08, 0x05, 0x1D, 0x1F, 0x17, + 0x18, 0x06, 0x79, 0x80, 0x7D, 0x7C, 0x7A, 0x78, + 0x76, 0x71, 0x73, 0x6E, 0x6B, 0x68, 0x65, 0x62, + 0x4B, 0x5B, 0x5F, 0x55, 0x56, 0x52, 0x4F, 0x46, + 0x42, 0x5A, 0x14, 0x23, 0x3D, 0x2B, 0x21, 0x14, + 0x06, 0x04, 0x03, 0x07, 0x09, 0x13, 0x2A, 0x3A, + 0x37, 0x3E, 0x32, 0x33, 0x25, 0x2C, 0x07, 0x09, + 0x1D, 0x14, 0x06, 0x02, 0x00 +}; + +unsigned char linux_logo[] = { + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, + 0x58, 0x58, 0x59, 0x5C, 0x5D, 0x5F, 0x60, 0x61, + 0x62, 0x61, 0x61, 0x62, 0x62, 0x62, 0x63, 0x63, + 0x61, 0x61, 0x61, 0x61, 0x61, 0x60, 0x5E, 0x5E, + 0x5E, 0x5D, 0x5D, 0x5C, 0x5D, 0x5B, 0x58, 0x58, + 0x58, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x57, + 0x54, 0x56, 0x57, 0x67, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x67, 0x4C, + 0x4A, 0x49, 0x4A, 0x49, 0x4A, 0x49, 0x49, 0x4A, + 0x4A, 0x4B, 0x4B, 0x4B, 0x4C, 0x50, 0x51, 0x52, + 0x54, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x58, 0x56, 0x56, 0x53, + 0x52, 0x53, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, + 0x4B, 0x4B, 0x4B, 0x4A, 0x49, 0x4A, 0x4A, 0x49, + 0x49, 0x49, 0x48, 0x49, 0x49, 0x4A, 0x4A, 0x4B, + 0x4C, 0x4D, 0x52, 0x54, 0x56, 0x55, 0x57, 0x58, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x55, 0x54, 0x53, 0x52, 0x51, 0x50, + 0x50, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xF4, 0xFB, + 0xFC, 0x67, 0x53, 0x50, 0x4D, 0x4C, 0x4C, 0x4C, + 0x4B, 0x4A, 0x4A, 0x48, 0x49, 0x48, 0x48, 0x49, + 0x49, 0x49, 0x4B, 0x4C, 0x50, 0x52, 0x53, 0x56, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x55, 0x54, 0x53, 0x51, 0x51, 0x50, 0x4C, 0x4D, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xD2, 0xD7, 0xF5, + 0xFC, 0xFC, 0x5D, 0x5D, 0x5C, 0x5C, 0x59, 0x58, + 0x58, 0x56, 0x52, 0x4C, 0x4B, 0x4A, 0x4A, 0x48, + 0x48, 0x48, 0x48, 0x48, 0x49, 0x4B, 0x4D, 0x51, + 0x54, 0x56, 0x58, 0x57, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x57, 0x55, 0x54, + 0x53, 0x52, 0x51, 0x4D, 0x4D, 0x4D, 0x50, 0x50, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0x64, 0xD9, 0xF5, + 0xF9, 0xFC, 0xFC, 0x64, 0x63, 0x62, 0x61, 0x61, + 0x61, 0x60, 0x5E, 0x5B, 0x5A, 0x54, 0x52, 0x4C, + 0x4B, 0x49, 0x49, 0x47, 0x47, 0x48, 0x49, 0x4B, + 0x4C, 0x51, 0x53, 0x56, 0x57, 0x58, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x57, 0x57, 0x55, 0x53, 0x53, + 0x51, 0x50, 0x50, 0x50, 0x50, 0x50, 0x53, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF4, 0xF5, 0xF9, 0xFC, + 0xFC, 0xFC, 0xFC, 0x64, 0x64, 0x64, 0x64, 0x64, + 0x64, 0x64, 0x64, 0x63, 0x61, 0x61, 0x5E, 0x59, + 0x55, 0x52, 0x4C, 0x4A, 0x49, 0x47, 0x48, 0x48, + 0x49, 0x4B, 0x4D, 0x51, 0x54, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x58, 0x55, 0x54, 0x54, 0x52, 0x51, + 0x51, 0x51, 0x51, 0x51, 0x53, 0x54, 0x59, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0x60, 0x60, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x64, 0x65, 0x65, 0x64, 0x63, + 0x61, 0x5E, 0x59, 0x56, 0x4D, 0x4B, 0x48, 0x48, + 0x48, 0x48, 0x49, 0x4B, 0x50, 0x53, 0x56, 0x56, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x56, 0x54, 0x53, 0x52, 0x51, 0x51, + 0x51, 0x52, 0x53, 0x55, 0x59, 0x5D, 0x5E, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0x4C, 0x4E, 0x51, 0x52, + 0x57, 0x5A, 0x5E, 0x60, 0x61, 0x63, 0x65, 0xCB, + 0x64, 0x64, 0x63, 0x60, 0x5C, 0x57, 0x50, 0x4B, + 0x48, 0x47, 0x47, 0x47, 0x4A, 0x4C, 0x52, 0x53, + 0x54, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x55, 0x54, 0x53, 0x53, 0x51, 0x52, 0x52, 0x53, + 0x53, 0x57, 0x5A, 0x5D, 0x5E, 0x5E, 0x60, 0xFC, + 0xFC, 0xFC, 0xFB, 0xF9, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFA, 0xF9, 0xF5, 0xFB, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x45, 0x3F, 0x3F, + 0x45, 0x48, 0x4B, 0x4D, 0x54, 0x5A, 0x5E, 0x61, + 0x63, 0xCB, 0xCB, 0x65, 0x64, 0x62, 0x5E, 0x57, + 0x50, 0x4B, 0x48, 0x47, 0x47, 0x48, 0x4B, 0x4D, + 0x51, 0x56, 0x56, 0x57, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, + 0x54, 0x54, 0x53, 0x53, 0x52, 0x53, 0x54, 0x57, + 0x59, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x5E, 0xFC, + 0xFC, 0xFA, 0xFC, 0xFA, 0xE0, 0xFC, 0xFC, 0xFC, + 0xFB, 0xFB, 0xFB, 0xDF, 0xD8, 0xF9, 0xE0, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0x4C, 0x4A, 0x48, + 0x48, 0x3E, 0x44, 0x43, 0x3F, 0x47, 0x4B, 0x52, + 0x5A, 0x5E, 0x62, 0x64, 0xCB, 0xCB, 0x64, 0x61, + 0x5E, 0x57, 0x4D, 0x49, 0x47, 0x47, 0x48, 0x4A, + 0x4C, 0x52, 0x54, 0x56, 0x57, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, + 0x54, 0x53, 0x53, 0x54, 0x54, 0x55, 0x58, 0x5B, + 0x5C, 0x5D, 0x5E, 0x5D, 0x5D, 0x5B, 0x58, 0xFC, + 0xFC, 0xD8, 0x4C, 0x60, 0xFC, 0xF5, 0xFC, 0xFC, + 0xFC, 0xF7, 0x5F, 0x48, 0x48, 0x2C, 0xF8, 0xF9, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x4A, 0x49, + 0x49, 0x49, 0x49, 0x47, 0x3E, 0x44, 0x42, 0x3F, + 0x3E, 0x4B, 0x54, 0x5C, 0x61, 0x64, 0xCB, 0xCB, + 0x64, 0x61, 0x5D, 0x53, 0x4B, 0x49, 0x47, 0x47, + 0x49, 0x4B, 0x50, 0x53, 0x56, 0x57, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x55, 0x54, + 0x53, 0x53, 0x54, 0x56, 0x58, 0x5A, 0x5B, 0x5D, + 0x5D, 0x5D, 0x5C, 0x5A, 0x54, 0x52, 0x4C, 0xFC, + 0xF7, 0x4E, 0x2D, 0x29, 0x4E, 0xFC, 0xFC, 0xFC, + 0xFB, 0x5F, 0x26, 0x24, 0x20, 0x2E, 0x65, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x45, 0x3F, 0x45, + 0x3E, 0x47, 0x47, 0x47, 0x47, 0x47, 0x3E, 0x44, + 0x43, 0x40, 0x44, 0x49, 0x51, 0x5C, 0x62, 0x64, + 0xCB, 0xCB, 0x63, 0x60, 0x58, 0x50, 0x49, 0x48, + 0x48, 0x48, 0x4A, 0x4D, 0x53, 0x54, 0x57, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, + 0x54, 0x54, 0x55, 0x57, 0x59, 0x5B, 0x5C, 0x5D, + 0x5C, 0x5A, 0x54, 0x51, 0x4C, 0x4C, 0x54, 0xFC, + 0xF9, 0x23, 0xDB, 0x2D, 0x23, 0xFA, 0xFB, 0xFA, + 0xF5, 0x27, 0x21, 0xD9, 0xF8, 0x20, 0x21, 0xFB, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0x5D, 0x58, 0x55, + 0x50, 0x48, 0x45, 0x43, 0x44, 0x44, 0x45, 0x45, + 0x3E, 0x3F, 0x43, 0x41, 0x3F, 0x48, 0x52, 0x5D, + 0x63, 0x65, 0xCB, 0x65, 0x61, 0x5D, 0x52, 0x4B, + 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, 0x57, + 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, 0x54, + 0x54, 0x58, 0x5A, 0x59, 0x5B, 0x5B, 0x5B, 0x5A, + 0x55, 0x52, 0x4D, 0x4D, 0x55, 0x5B, 0x5D, 0xFC, + 0xF1, 0xF9, 0xFC, 0xD4, 0x21, 0xCC, 0xF7, 0xF8, + 0xF2, 0x21, 0xD9, 0xFC, 0xF2, 0xFB, 0x21, 0x45, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFB, 0xD1, 0xD0, 0xCD, + 0xCC, 0x63, 0x5E, 0x58, 0x50, 0x47, 0x43, 0x3F, + 0x3F, 0x3F, 0x3F, 0x3F, 0x40, 0x41, 0x3F, 0x4A, + 0x56, 0x5E, 0x64, 0xCB, 0x65, 0x63, 0x5E, 0x56, + 0x4C, 0x48, 0x47, 0x47, 0x49, 0x4C, 0x51, 0x54, + 0x58, 0x57, 0x57, 0x57, 0x57, 0x55, 0x54, 0x54, + 0x57, 0x5A, 0x5A, 0x5C, 0x5B, 0x5A, 0x58, 0x54, + 0x51, 0x4C, 0x55, 0x5D, 0x5D, 0x5B, 0x54, 0xFC, + 0xF0, 0xF9, 0xFC, 0x65, 0x45, 0xCD, 0xFB, 0xFB, + 0xF8, 0x26, 0xFB, 0xFC, 0xFC, 0xFC, 0x21, 0x27, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFB, 0xD7, 0x35, 0x34, + 0x2F, 0x35, 0x36, 0x2F, 0x2F, 0x36, 0x2F, 0x2F, + 0x36, 0x36, 0x35, 0x35, 0x43, 0x42, 0x41, 0x2E, + 0x45, 0x4C, 0x5B, 0x62, 0x65, 0xCC, 0x64, 0x60, + 0x58, 0x4D, 0x49, 0x47, 0x47, 0x49, 0x4C, 0x51, + 0x58, 0x57, 0x57, 0x57, 0x57, 0x57, 0x55, 0x57, + 0x58, 0x5A, 0x5A, 0x5B, 0x5A, 0x55, 0x54, 0x51, + 0x53, 0x5C, 0x5D, 0x5D, 0x54, 0x4B, 0x4D, 0xFC, + 0xFC, 0x44, 0xFC, 0xFB, 0x7B, 0xAB, 0xA8, 0xAE, + 0xAB, 0x7F, 0xFC, 0xFC, 0xFB, 0xFB, 0x22, 0x2A, + 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x2F, 0x30, 0x30, + 0x32, 0x30, 0x32, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x2F, 0x2F, 0x40, 0x41, + 0x2E, 0x40, 0x48, 0x56, 0x5F, 0x64, 0xCC, 0x65, + 0x61, 0x59, 0x50, 0x49, 0x47, 0x47, 0x49, 0x4C, + 0x5A, 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, + 0x5A, 0x5A, 0x5A, 0x58, 0x55, 0x52, 0x51, 0x5A, + 0x5D, 0x5D, 0x57, 0x4C, 0x51, 0x54, 0x5D, 0xFC, + 0xFC, 0x2A, 0xFC, 0xC9, 0xAA, 0x8B, 0x8A, 0x8C, + 0xAB, 0x8C, 0x8C, 0xFB, 0xFB, 0x23, 0x20, 0xF1, + 0xFC, 0xFC, 0xFC, 0x3B, 0x33, 0x33, 0x32, 0x32, + 0x31, 0x32, 0x30, 0x32, 0x32, 0x32, 0x32, 0x30, + 0x31, 0x31, 0x31, 0x32, 0x33, 0x33, 0x3C, 0x41, + 0x41, 0x2E, 0x2D, 0x45, 0x4D, 0x5D, 0x63, 0xCC, + 0x65, 0x62, 0x5D, 0x51, 0x49, 0x47, 0x47, 0x4A, + 0x59, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, + 0x5A, 0x5A, 0x58, 0x55, 0x53, 0x53, 0x5C, 0x5E, + 0x59, 0x51, 0x4E, 0x54, 0x59, 0x5E, 0x62, 0xFC, + 0xFC, 0xDB, 0xAA, 0xA1, 0x95, 0x9C, 0x8C, 0x88, + 0x82, 0x83, 0x83, 0x8C, 0x88, 0xAE, 0xB9, 0xFB, + 0xFC, 0xFC, 0xFC, 0x3C, 0x3B, 0x72, 0x38, 0x33, + 0x33, 0x33, 0x31, 0x33, 0x31, 0x31, 0x31, 0x31, + 0x33, 0x33, 0x38, 0x33, 0x72, 0x3B, 0x44, 0x2E, + 0x41, 0x2E, 0x2E, 0x2D, 0x43, 0x4B, 0x5B, 0x63, + 0xCB, 0xCC, 0x63, 0x5D, 0x51, 0x49, 0x47, 0x49, + 0x5C, 0x58, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, + 0x58, 0x58, 0x57, 0x53, 0x58, 0x5D, 0x5E, 0x55, + 0x51, 0x53, 0x58, 0x5E, 0x60, 0x63, 0x64, 0xFC, + 0xFC, 0xC0, 0xA6, 0x9D, 0x8B, 0x9C, 0x8C, 0x8C, + 0x6E, 0x83, 0x88, 0x8C, 0x8C, 0x8C, 0x83, 0xE8, + 0xFB, 0xFC, 0xFC, 0xFC, 0x33, 0x70, 0x70, 0x6F, + 0x6F, 0x6F, 0x6F, 0x3A, 0x6F, 0x6D, 0x6F, 0x6F, + 0x70, 0x6F, 0x6F, 0x70, 0x6F, 0x32, 0x5A, 0x48, + 0x41, 0x2D, 0x2D, 0x2D, 0x2C, 0x41, 0x49, 0x5A, + 0x62, 0xCB, 0xCB, 0x63, 0x5D, 0x50, 0x49, 0x4A, + 0x5C, 0x58, 0x58, 0x57, 0x55, 0x57, 0x57, 0x57, + 0x57, 0x55, 0x56, 0x59, 0x5E, 0x5C, 0x52, 0x53, + 0x55, 0x5B, 0x5E, 0x61, 0x63, 0x64, 0x63, 0xFC, + 0xE8, 0xBF, 0xA4, 0x99, 0x9C, 0x8C, 0x88, 0x88, + 0x6E, 0x88, 0x8C, 0x8C, 0x8C, 0xC2, 0xA6, 0xC4, + 0xFC, 0xFC, 0xFC, 0xFC, 0x36, 0x3A, 0x6F, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, + 0x70, 0x70, 0x70, 0x70, 0x37, 0x32, 0xCD, 0x5E, + 0x4C, 0x43, 0x2C, 0x2D, 0x2D, 0x2C, 0x2E, 0x47, + 0x57, 0x61, 0x65, 0xCC, 0x63, 0x5C, 0x50, 0x4D, + 0x5C, 0x5A, 0x57, 0x55, 0x55, 0x55, 0x58, 0x58, + 0x55, 0x54, 0x5B, 0x5E, 0x5D, 0x53, 0x53, 0x55, + 0x5D, 0x5E, 0x61, 0x61, 0x61, 0x61, 0x5E, 0xFC, + 0xEA, 0xBE, 0xA4, 0x9B, 0x8B, 0x85, 0x8C, 0x6E, + 0x8C, 0x8C, 0x8C, 0xA3, 0xAA, 0xA4, 0xA4, 0xE9, + 0xFB, 0xFC, 0xFC, 0xFC, 0x36, 0x6D, 0x70, 0x73, + 0x70, 0x70, 0x70, 0x73, 0x73, 0x73, 0x73, 0x70, + 0x70, 0x70, 0x73, 0x70, 0x37, 0x38, 0xD1, 0xCF, + 0x61, 0x4D, 0x44, 0x2C, 0x2D, 0x2E, 0x2C, 0x2E, + 0x3E, 0x56, 0x61, 0xCB, 0xCC, 0x62, 0x5B, 0x57, + 0x59, 0x58, 0x55, 0x54, 0x54, 0x55, 0x58, 0x58, + 0x58, 0x5B, 0x5E, 0x5B, 0x53, 0x55, 0x55, 0x5C, + 0x5E, 0x61, 0x61, 0x60, 0x5D, 0x5A, 0x4E, 0xFC, + 0xFC, 0xEA, 0xAA, 0x9C, 0x8A, 0x85, 0x82, 0x8C, + 0x8C, 0xA8, 0xEB, 0xA8, 0xA4, 0xA4, 0xAA, 0xFC, + 0xFC, 0xFC, 0x64, 0xFB, 0x39, 0x31, 0x72, 0x78, + 0x73, 0x78, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, + 0x78, 0x70, 0x73, 0x73, 0x33, 0xCC, 0xD2, 0xD1, + 0xCE, 0x62, 0x53, 0x3F, 0x2D, 0x2D, 0x41, 0x2C, + 0x2E, 0x3E, 0x56, 0x62, 0xCB, 0xCB, 0x61, 0x5D, + 0x54, 0x54, 0x54, 0x54, 0x56, 0x58, 0x58, 0x58, + 0x5C, 0x5E, 0x5A, 0x55, 0x58, 0x58, 0x5B, 0x5E, + 0x61, 0x5E, 0x5D, 0x5A, 0x52, 0x55, 0xCD, 0xFC, + 0xFC, 0x34, 0xC9, 0xE8, 0xA8, 0xAE, 0xC2, 0xE8, + 0xC3, 0xA6, 0xA7, 0xA6, 0xAA, 0x78, 0x2E, 0x42, + 0xFC, 0xFC, 0xD2, 0x64, 0xF8, 0x31, 0x72, 0x73, + 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x73, + 0x73, 0x73, 0x73, 0x72, 0x33, 0x5C, 0x64, 0xD2, + 0xD1, 0xCF, 0x63, 0x54, 0x3F, 0x2C, 0x41, 0x41, + 0x2C, 0x2E, 0x47, 0x58, 0x63, 0xCB, 0xCB, 0x62, + 0x52, 0x53, 0x53, 0x56, 0x58, 0x58, 0x5A, 0x5B, + 0x5E, 0x5A, 0x57, 0x58, 0x58, 0x58, 0x60, 0x60, + 0x5D, 0x5A, 0x55, 0x4E, 0x64, 0xD2, 0xD1, 0xFC, + 0xFC, 0x41, 0x3E, 0xC1, 0xC0, 0xA3, 0xA6, 0xA7, + 0xA7, 0xA9, 0xAA, 0xB8, 0x2E, 0x3F, 0x2C, 0x41, + 0xFC, 0xFC, 0xF7, 0xCE, 0xCD, 0x36, 0x72, 0x73, + 0x74, 0x75, 0x78, 0x75, 0x75, 0x75, 0x74, 0x74, + 0x74, 0x74, 0x78, 0x72, 0x6D, 0x49, 0x59, 0xCB, + 0xD1, 0xD1, 0xD2, 0xCB, 0x56, 0x3F, 0x2C, 0x41, + 0x40, 0x2D, 0x2E, 0x49, 0x5B, 0x64, 0xCC, 0x64, + 0x51, 0x53, 0x53, 0x55, 0x58, 0x59, 0x5B, 0x5E, + 0x59, 0x58, 0x58, 0x58, 0x55, 0x60, 0x60, 0x5C, + 0x5A, 0x53, 0x5B, 0xD0, 0xD3, 0xD3, 0xD3, 0xFB, + 0xFC, 0x40, 0x41, 0x45, 0xC4, 0xC0, 0xBE, 0xBE, + 0xC1, 0xC0, 0x3C, 0x47, 0x2E, 0x21, 0x22, 0x20, + 0x65, 0xFC, 0xFC, 0xFC, 0xFC, 0x6D, 0x72, 0x75, + 0x78, 0x76, 0x75, 0x79, 0x76, 0x76, 0x76, 0x76, + 0x75, 0x75, 0x75, 0x72, 0x6D, 0x2E, 0x48, 0x5D, + 0xCE, 0xD1, 0xD4, 0xD3, 0xCB, 0x56, 0x43, 0x2C, + 0x42, 0x43, 0x2E, 0x2E, 0x4A, 0x5D, 0x64, 0x64, + 0x50, 0x52, 0x56, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, + 0x5A, 0x58, 0x58, 0x55, 0x61, 0x60, 0x58, 0x58, + 0x4E, 0x61, 0xD1, 0xD4, 0xD4, 0xD1, 0xEE, 0xFC, + 0xFC, 0x2B, 0x29, 0x2E, 0x3F, 0xB0, 0xAD, 0x81, + 0x46, 0x2D, 0x46, 0x2C, 0x24, 0x22, 0x22, 0x23, + 0x25, 0xFC, 0xFC, 0xFC, 0xFC, 0x6E, 0x73, 0x76, + 0x76, 0x79, 0x79, 0x79, 0x76, 0x76, 0x79, 0x76, + 0x79, 0x79, 0x79, 0x74, 0x3F, 0x41, 0x2C, 0x48, + 0x5F, 0xCF, 0xD5, 0xD7, 0xD6, 0xCD, 0x57, 0x40, + 0x2E, 0x3F, 0x44, 0x2E, 0x41, 0x4C, 0x60, 0x61, + 0x51, 0x53, 0x58, 0x5C, 0x5D, 0x5E, 0x5D, 0x5C, + 0x58, 0x57, 0x54, 0x5F, 0x5E, 0x55, 0x55, 0x52, + 0x64, 0xD4, 0xD5, 0xD4, 0xD1, 0x5D, 0xFA, 0xFB, + 0xF4, 0x21, 0x24, 0x41, 0x40, 0x44, 0x2E, 0x2E, + 0x42, 0x41, 0x2A, 0x24, 0x22, 0x22, 0x22, 0x22, + 0x23, 0xD9, 0xFC, 0xFC, 0xFC, 0xFC, 0xE5, 0xB8, + 0x8F, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, 0x7A, 0x8F, + 0x8F, 0x8F, 0xB8, 0xE5, 0x3F, 0x3E, 0x43, 0x2C, + 0x48, 0x61, 0xD1, 0xD7, 0xD9, 0xD7, 0xD0, 0x57, + 0x41, 0x2E, 0x3E, 0x44, 0x2D, 0x40, 0x52, 0x5D, + 0x53, 0x55, 0x59, 0x5D, 0x5E, 0x5E, 0x5D, 0x5A, + 0x57, 0x53, 0x5E, 0x5E, 0x54, 0x53, 0x54, 0x65, + 0xD5, 0xD6, 0xD4, 0xCE, 0x53, 0xFB, 0xF9, 0xFC, + 0x24, 0x22, 0x23, 0x23, 0x41, 0x42, 0x2E, 0x40, + 0x2B, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x23, 0x23, 0xFC, 0xFC, 0xFC, 0xFC, 0xE7, 0xBD, + 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0x93, 0xB5, 0xC6, 0xEB, 0x2D, 0x47, 0x4A, 0x47, + 0x2C, 0x3E, 0x61, 0xD4, 0xDC, 0xDC, 0xDA, 0xCF, + 0x54, 0x41, 0x41, 0x3E, 0x45, 0x2C, 0x3F, 0x4A, + 0x58, 0x5A, 0x5C, 0x5F, 0x60, 0x5E, 0x5D, 0x57, + 0x51, 0x5D, 0x5D, 0x51, 0x53, 0x53, 0xCB, 0xD5, + 0xD6, 0xD5, 0x63, 0x55, 0xFC, 0xFC, 0xFC, 0x2C, + 0x23, 0x22, 0x23, 0x22, 0x20, 0x2D, 0x2C, 0x26, + 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x21, 0xF0, 0xFC, 0xFC, 0xFC, 0xE2, 0xC6, + 0xB5, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, + 0x93, 0x93, 0xC7, 0xE3, 0x3E, 0x2E, 0x49, 0x52, + 0x4C, 0x41, 0x44, 0x62, 0xD6, 0xDE, 0xDE, 0xD9, + 0xD0, 0x51, 0x2E, 0x40, 0x47, 0x44, 0x2C, 0x42, + 0x5D, 0x5D, 0x5F, 0x60, 0x60, 0x5D, 0x57, 0x51, + 0x58, 0x5D, 0x4E, 0x52, 0x55, 0x64, 0xD5, 0xD6, + 0xD4, 0x61, 0x59, 0x6B, 0xFC, 0xFC, 0xFC, 0x21, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x21, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x21, 0x24, 0xFC, 0xFC, 0xFC, 0xE2, 0xC7, + 0xB5, 0x90, 0x93, 0x93, 0x93, 0x90, 0x93, 0x93, + 0x90, 0xB5, 0xC8, 0xE4, 0x5F, 0x45, 0x2E, 0x4D, + 0x57, 0x57, 0x44, 0x43, 0x63, 0xDA, 0xDF, 0xDF, + 0xD9, 0xCE, 0x4C, 0x2C, 0x3F, 0x3E, 0x40, 0x40, + 0x60, 0x5E, 0x61, 0x61, 0x5E, 0x5B, 0x53, 0x52, + 0x5C, 0x52, 0x52, 0x55, 0x61, 0xD4, 0xD5, 0xD1, + 0x5E, 0x5B, 0x5C, 0xFB, 0xFC, 0xFC, 0x2A, 0x21, + 0x23, 0x22, 0x23, 0x22, 0x22, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0xFB, 0xFC, 0xFC, 0xB3, 0xC8, + 0xB5, 0x90, 0x92, 0xB5, 0x93, 0x93, 0xB5, 0x93, + 0x92, 0xB5, 0xC8, 0xB9, 0xD0, 0x5E, 0x44, 0x40, + 0x52, 0x58, 0x57, 0x48, 0x40, 0x63, 0xD9, 0xE0, + 0xE0, 0xD9, 0xCB, 0x49, 0x2D, 0x3F, 0x45, 0x3F, + 0x63, 0x61, 0x62, 0x60, 0x5E, 0x55, 0x4D, 0x59, + 0x53, 0x4E, 0x54, 0x5D, 0xD2, 0xD4, 0xD2, 0x5E, + 0x5C, 0x5D, 0xFC, 0xFC, 0xFC, 0xF8, 0x29, 0x23, + 0x23, 0x23, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x23, 0x22, 0x22, 0x23, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x22, 0x22, 0xF0, 0xFC, 0xFC, 0xB3, 0xC7, + 0xB5, 0x93, 0xB5, 0x93, 0x93, 0x91, 0x93, 0x93, + 0x91, 0xB5, 0xC7, 0xAD, 0xD6, 0xD2, 0x5E, 0x3F, + 0x3F, 0x57, 0x57, 0x58, 0x4A, 0x41, 0x64, 0xDC, + 0xF1, 0xDF, 0xDA, 0x61, 0x45, 0x2E, 0x43, 0x47, + 0xCB, 0x63, 0x62, 0x5F, 0x58, 0x51, 0x53, 0x54, + 0x4C, 0x52, 0x5C, 0xCD, 0xD3, 0xD2, 0x60, 0x5D, + 0x5D, 0xFB, 0xFC, 0xFC, 0xFC, 0xDB, 0x49, 0x24, + 0x21, 0x23, 0x23, 0x22, 0x26, 0x26, 0x2A, 0x24, + 0x22, 0x23, 0x22, 0x21, 0x24, 0x26, 0x26, 0x2A, + 0x29, 0x2B, 0x24, 0x25, 0xFC, 0xFC, 0xB3, 0xC5, + 0x91, 0x91, 0x92, 0x91, 0x92, 0x92, 0x93, 0x93, + 0x91, 0x93, 0xC6, 0xAD, 0xDC, 0xD9, 0xD4, 0x60, + 0x43, 0x45, 0x58, 0x58, 0x57, 0x4B, 0x43, 0xCC, + 0xDD, 0xF1, 0xD8, 0xD5, 0x5D, 0x43, 0x41, 0x47, + 0xCD, 0x63, 0x62, 0x5D, 0x54, 0x4C, 0x55, 0x4B, + 0x51, 0x58, 0x62, 0xD0, 0xD0, 0x62, 0x5D, 0x5D, + 0x67, 0xFC, 0xFC, 0xFC, 0xFC, 0x58, 0x4E, 0x28, + 0x2A, 0x20, 0x23, 0x22, 0x23, 0x2A, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x23, 0x25, 0x2A, 0x2E, 0x2D, + 0x2E, 0x2E, 0x2E, 0x23, 0xFA, 0xFC, 0xB2, 0xBD, + 0xB5, 0x90, 0x91, 0x93, 0x92, 0x90, 0x91, 0x93, + 0x92, 0x91, 0xBD, 0xAD, 0xDE, 0xE0, 0xD8, 0xD7, + 0x61, 0x40, 0x48, 0x58, 0x58, 0x58, 0x48, 0x44, + 0xCF, 0xDE, 0xE0, 0xDD, 0xD0, 0x52, 0x41, 0x45, + 0xCD, 0x63, 0x61, 0x58, 0x4D, 0x51, 0x4C, 0x4B, + 0x54, 0x5D, 0xCC, 0xCE, 0x63, 0x61, 0x5D, 0x5D, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0x4B, 0x27, 0x21, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x24, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x20, + 0x27, 0x2B, 0x41, 0x2B, 0x23, 0xFC, 0xB2, 0xB6, + 0x93, 0x90, 0x92, 0xB5, 0x92, 0x90, 0xB5, 0x90, + 0x92, 0x93, 0xBC, 0xAD, 0xDC, 0xF1, 0xF3, 0xF0, + 0xD9, 0x61, 0x41, 0x4A, 0x58, 0x57, 0x57, 0x44, + 0x49, 0xD2, 0xDD, 0xD8, 0xDA, 0x63, 0x4A, 0x45, + 0xCC, 0x63, 0x5E, 0x52, 0x4B, 0x4C, 0x49, 0x51, + 0x5C, 0x61, 0xCD, 0x65, 0x63, 0x5E, 0x4E, 0xCF, + 0xFB, 0xFB, 0xF0, 0xFC, 0xD2, 0x2A, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x26, 0x41, 0x27, 0xF9, 0x81, 0xB7, + 0xB5, 0x91, 0x92, 0xB5, 0x91, 0xB5, 0x93, 0xB5, + 0x93, 0xB6, 0xB7, 0xB9, 0xCB, 0xD8, 0xF3, 0xF2, + 0xF2, 0xDB, 0x61, 0x2D, 0x51, 0x58, 0x57, 0x58, + 0x41, 0x51, 0xD4, 0xDB, 0xDC, 0xD1, 0x5B, 0x4C, + 0xCB, 0x62, 0x59, 0x4C, 0x4A, 0x49, 0x4B, 0x55, + 0x60, 0x64, 0xCC, 0x64, 0x5E, 0x55, 0x60, 0xE1, + 0xFB, 0xF8, 0xFC, 0xFC, 0x21, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x21, 0x24, 0x2D, 0x21, 0xB4, 0xBB, + 0xB6, 0xB5, 0xB6, 0xB7, 0xB7, 0xB7, 0xB7, 0xB6, + 0xB6, 0xB6, 0xBB, 0xB9, 0x45, 0xCB, 0xDF, 0xF3, + 0xF3, 0xF3, 0xDB, 0x5E, 0x2C, 0x51, 0x58, 0x58, + 0x52, 0x2D, 0x5C, 0xD4, 0xD9, 0xD5, 0x63, 0x58, + 0x64, 0x60, 0x53, 0x49, 0x4A, 0x49, 0x52, 0x5C, + 0x63, 0xCD, 0xCD, 0x63, 0x5C, 0x4E, 0x65, 0xFC, + 0xFC, 0xF5, 0xFC, 0xD2, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x22, 0x22, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x21, 0x22, 0x25, 0x29, 0xB3, 0xC7, + 0xB5, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, 0xB6, + 0xB6, 0xB5, 0xC7, 0xAD, 0x57, 0x3F, 0xCB, 0xF0, + 0xF3, 0xF3, 0xF2, 0xD9, 0x58, 0x41, 0x4C, 0x58, + 0x57, 0x47, 0x42, 0x62, 0xD4, 0xD4, 0xCC, 0x60, + 0x63, 0x5D, 0x50, 0x47, 0x48, 0x4B, 0x58, 0x60, + 0xCC, 0xCE, 0xCD, 0x60, 0x53, 0x5C, 0x62, 0xFB, + 0xF9, 0xFC, 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x23, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0x81, 0xC7, + 0xB7, 0xB7, 0xBC, 0xB7, 0xBC, 0xBC, 0xBC, 0xB7, + 0xB7, 0xB7, 0xC8, 0x80, 0x58, 0x57, 0x40, 0xCE, + 0xF3, 0xF2, 0xF2, 0xF0, 0xD5, 0x4C, 0x3F, 0x4B, + 0x52, 0x50, 0x2D, 0x4B, 0x64, 0xD2, 0xCC, 0x61, + 0x60, 0x58, 0x4A, 0x47, 0x47, 0x4C, 0x59, 0x64, + 0xD0, 0xD0, 0x64, 0x59, 0x49, 0x5D, 0xFB, 0xFC, + 0xD9, 0xFC, 0xD6, 0x23, 0x22, 0x22, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, 0xB4, 0xC8, + 0xBD, 0xB7, 0xBD, 0xBC, 0xBD, 0xC5, 0xBC, 0xC5, + 0xBC, 0xBD, 0xC7, 0xAC, 0x58, 0x57, 0x58, 0x2C, + 0xD1, 0xF0, 0xF3, 0xF3, 0xE0, 0xCD, 0x45, 0x3E, + 0x48, 0x4B, 0x3F, 0x41, 0x56, 0x64, 0x65, 0x62, + 0x5D, 0x52, 0x47, 0x48, 0x48, 0x53, 0x60, 0xCC, + 0xD2, 0xD0, 0x63, 0x52, 0x4E, 0x53, 0xFB, 0xFB, + 0xFC, 0xFC, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x23, 0x20, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, 0xB4, 0xC7, + 0xC5, 0xBC, 0xC5, 0xBD, 0xC5, 0xC5, 0xBD, 0xC5, + 0xBC, 0xC6, 0xC7, 0xB9, 0x58, 0x57, 0x58, 0x57, + 0x2D, 0xD4, 0xF1, 0xF2, 0xF0, 0xD9, 0x5D, 0x47, + 0x48, 0x3F, 0x42, 0x2C, 0x48, 0x5C, 0x5F, 0x60, + 0x58, 0x50, 0x47, 0x4A, 0x49, 0x55, 0x63, 0xD0, + 0xD2, 0xCD, 0x5D, 0x49, 0x4E, 0xE1, 0xFC, 0xF0, + 0xFC, 0xF8, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x20, 0x21, 0x21, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, 0xC4, 0xC8, + 0xBD, 0xBD, 0xC6, 0xBD, 0xC6, 0xC6, 0xC5, 0xC6, + 0xBD, 0xC6, 0xC7, 0xE4, 0x54, 0x57, 0x58, 0x57, + 0x57, 0x43, 0xD7, 0xE0, 0xF1, 0xD8, 0xCD, 0x4B, + 0x4A, 0x47, 0x42, 0x2C, 0x3F, 0x4D, 0x58, 0x5C, + 0x52, 0x4B, 0x48, 0x4B, 0x4A, 0x58, 0xCB, 0xD3, + 0xD2, 0xCD, 0x58, 0x47, 0x4A, 0xFC, 0xFC, 0xFB, + 0xFC, 0x2B, 0x22, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x26, 0x21, 0x21, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0xE5, 0xC8, + 0xBA, 0xC5, 0xC6, 0xC6, 0xC6, 0xC7, 0xC6, 0xC7, + 0xC5, 0xC6, 0xC8, 0xE5, 0x2E, 0x54, 0x58, 0x57, + 0x57, 0x4C, 0x4D, 0xDA, 0xD8, 0xD8, 0xD4, 0x5C, + 0x4B, 0x4B, 0x3F, 0x42, 0x44, 0x4A, 0x51, 0x58, + 0x4B, 0x48, 0x4B, 0x51, 0x4D, 0x5F, 0xD0, 0xD1, + 0xD0, 0x64, 0x51, 0x44, 0x6B, 0xFC, 0xFB, 0xFC, + 0xFC, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x23, 0x26, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0xE5, 0xED, + 0xE7, 0xBA, 0xC8, 0xC6, 0xC6, 0xC6, 0xC6, 0xC7, + 0xC7, 0xE5, 0xED, 0xE6, 0x61, 0x41, 0x52, 0x58, + 0x58, 0x57, 0x45, 0x5E, 0xD7, 0xDD, 0xD5, 0x60, + 0x4B, 0x4C, 0x48, 0x4D, 0x4D, 0x50, 0x4D, 0x56, + 0x4A, 0x3E, 0x53, 0x53, 0x52, 0x63, 0xD3, 0xD0, + 0xCE, 0x60, 0x4A, 0x45, 0xFC, 0xFC, 0xF7, 0xFC, + 0xFC, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x21, 0x2A, 0x20, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0x23, 0xEB, 0xF6, + 0xF6, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, + 0xF6, 0xF6, 0xF6, 0xE6, 0xDB, 0x58, 0x45, 0x4B, + 0x58, 0x57, 0x4D, 0x4B, 0x64, 0xD4, 0xD0, 0x5C, + 0x48, 0x51, 0x4C, 0x5D, 0x5E, 0x5C, 0x56, 0x59, + 0x3E, 0x4A, 0x58, 0x54, 0x52, 0x65, 0xD3, 0xD0, + 0xCF, 0x5D, 0x48, 0xFC, 0xFC, 0xFC, 0xFA, 0xFC, + 0xFC, 0x21, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x21, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0x4F, 0xE6, 0xC6, + 0xC6, 0xBD, 0xC6, 0xBD, 0xBD, 0xBD, 0xBD, 0xC6, + 0xC5, 0xBA, 0xC7, 0xE6, 0xF2, 0xD4, 0x49, 0x4B, + 0x3E, 0x4D, 0x52, 0x3E, 0x52, 0x63, 0x64, 0x56, + 0x48, 0x54, 0x4D, 0x61, 0xCC, 0xCC, 0x60, 0x60, + 0x47, 0x4D, 0x5C, 0x53, 0x58, 0xCF, 0xD1, 0xCF, + 0xD0, 0x59, 0x45, 0xFC, 0xFC, 0xFC, 0xEF, 0xF9, + 0xFC, 0x21, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x23, 0x4F, 0xE4, 0xB9, + 0xAF, 0x80, 0x80, 0x8E, 0x8E, 0x8E, 0x8E, 0x8F, + 0x80, 0xB4, 0xB9, 0xE4, 0x7F, 0xDE, 0x61, 0x52, + 0x54, 0x48, 0x3F, 0x43, 0x4D, 0x56, 0x59, 0x4B, + 0x3E, 0x58, 0x53, 0x61, 0xD3, 0xD4, 0xCF, 0xCD, + 0x4C, 0x58, 0x5F, 0x53, 0x5E, 0xD3, 0xD0, 0xCE, + 0xCE, 0x52, 0x3F, 0xFC, 0xFC, 0xFC, 0xF7, 0x65, + 0xFA, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x21, 0x2A, 0x23, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x23, 0x22, 0x23, 0x22, 0x21, 0xB1, 0xE4, 0xE6, + 0x7C, 0xB1, 0x7C, 0xB1, 0xB2, 0xB2, 0xB3, 0x3D, + 0xB3, 0x3C, 0xE5, 0xB3, 0xB0, 0xF1, 0xD0, 0x58, + 0x5D, 0x4D, 0x40, 0x41, 0x48, 0x51, 0x4C, 0x3F, + 0x3F, 0x4D, 0x5A, 0x5A, 0xD5, 0xD9, 0xD7, 0xD4, + 0x57, 0x5E, 0x61, 0x4C, 0x63, 0xD4, 0xCF, 0xCE, + 0xCB, 0x4D, 0x4A, 0xFC, 0xFC, 0xFC, 0xFC, 0xF0, + 0xFB, 0x22, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x23, 0x22, 0x23, 0x23, 0xB1, 0x81, 0x7D, + 0x39, 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x7C, 0xB2, 0xB0, 0xDF, 0xD2, 0x57, + 0x60, 0x59, 0x5B, 0x59, 0x52, 0x4C, 0x4A, 0x40, + 0x42, 0x4A, 0x53, 0x4D, 0xD2, 0xDE, 0xDE, 0xD9, + 0x5E, 0x5E, 0x60, 0x4A, 0xCD, 0xD1, 0xCF, 0xCE, + 0x63, 0x49, 0x5C, 0xFB, 0xE8, 0x89, 0x9F, 0xFC, + 0xD6, 0x21, 0x21, 0x23, 0x22, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x21, 0x2A, 0x22, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x7F, 0xB9, + 0x71, 0x6C, 0x38, 0x38, 0x33, 0x33, 0x33, 0x38, + 0x38, 0x71, 0xAD, 0xE4, 0xD3, 0xDA, 0xCC, 0x52, + 0x63, 0x60, 0xCE, 0xD4, 0xCF, 0x60, 0x4C, 0x40, + 0x3F, 0x45, 0x4B, 0x5A, 0xCB, 0xD8, 0xDE, 0xDC, + 0x5E, 0x5E, 0x5F, 0x4C, 0xD2, 0xD2, 0xCF, 0xCF, + 0x61, 0x45, 0x5E, 0xA7, 0x9D, 0x95, 0x8B, 0x99, + 0xFC, 0x41, 0x21, 0x23, 0x23, 0x22, 0x23, 0x22, + 0x23, 0x22, 0x23, 0x2A, 0x23, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x77, 0x77, 0xF6, + 0xFC, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, + 0x7D, 0xFC, 0x47, 0x64, 0xD0, 0xD0, 0x5D, 0x4B, + 0x62, 0xCC, 0xD1, 0xDE, 0xDE, 0xD4, 0x5E, 0x43, + 0x3F, 0x3E, 0x48, 0x53, 0x58, 0xDB, 0xD8, 0xDC, + 0x5E, 0x5E, 0x5E, 0x53, 0xD4, 0xD2, 0xD0, 0xD0, + 0x5E, 0x49, 0xA7, 0xA6, 0x89, 0x95, 0x8B, 0x9C, + 0x9C, 0xFB, 0xD4, 0x22, 0x22, 0x22, 0x22, 0x23, + 0x22, 0x23, 0x23, 0x2A, 0x22, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x23, 0x22, 0x23, 0x23, 0x98, 0x8C, 0x8C, 0x88, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF8, + 0xE9, 0x9C, 0x48, 0x5C, 0xD0, 0xCB, 0x48, 0x49, + 0x5B, 0xCB, 0xCD, 0xE0, 0xF1, 0xDD, 0xD0, 0x4A, + 0x41, 0x47, 0x45, 0x4C, 0x48, 0xD7, 0xDE, 0xDC, + 0x5E, 0x5E, 0x5A, 0x58, 0xD1, 0xD0, 0xD0, 0xD2, + 0x5C, 0x55, 0xA7, 0xA6, 0x87, 0x86, 0x89, 0x94, + 0x9C, 0xA9, 0xFC, 0xF4, 0x22, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x2A, 0x21, 0x23, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x23, 0x22, 0x23, 0xA4, 0x89, 0x8C, 0xAA, + 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xF7, + 0x85, 0x88, 0x8D, 0x59, 0x64, 0x63, 0x47, 0x3E, + 0x4C, 0x60, 0x61, 0xE0, 0xF0, 0xDF, 0xD9, 0x5D, + 0x2E, 0x3E, 0x3E, 0x47, 0x4D, 0xCD, 0xDE, 0xDC, + 0x5D, 0x5C, 0x51, 0x5D, 0xD1, 0xD2, 0xD2, 0xD4, + 0x5A, 0xBE, 0xA7, 0x98, 0x8A, 0x8A, 0xA0, 0x8B, + 0x86, 0x86, 0xF7, 0xFC, 0xF7, 0x26, 0x23, 0x23, + 0x22, 0x22, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x21, 0x21, 0x21, 0xA1, 0x98, 0x9F, 0xBF, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xA7, + 0x8C, 0x86, 0x8D, 0x59, 0x5E, 0x5D, 0x3F, 0x3E, + 0x47, 0x53, 0x63, 0xD9, 0xF0, 0xF1, 0xDE, 0xD0, + 0x43, 0x3E, 0x47, 0x45, 0x4A, 0x5B, 0xDC, 0xDA, + 0x5D, 0x59, 0x49, 0x5F, 0xD1, 0xD2, 0xD3, 0xB9, + 0xA5, 0xA7, 0x98, 0x9B, 0x96, 0x9D, 0x89, 0x89, + 0x8B, 0x9C, 0x9D, 0xFC, 0xFC, 0xFC, 0x26, 0x22, + 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x22, 0x22, 0x29, 0x2D, 0x99, 0x99, 0xA2, 0xAA, + 0xC4, 0xFB, 0xFC, 0xFC, 0xFC, 0xF6, 0xBF, 0xA2, + 0x9C, 0x9C, 0x8E, 0xDC, 0xCD, 0x51, 0x41, 0x3E, + 0x45, 0x49, 0x58, 0xCD, 0xE0, 0xE0, 0xD8, 0xDA, + 0x4C, 0x4A, 0x45, 0x45, 0x48, 0x47, 0xDA, 0xDA, + 0x5C, 0x58, 0x44, 0x69, 0xA9, 0x98, 0xA4, 0xA6, + 0xA1, 0xA4, 0x99, 0x9E, 0x9D, 0x8B, 0x8A, 0x97, + 0x87, 0x9A, 0x8A, 0xC2, 0xFC, 0xFC, 0xFC, 0x4D, + 0x21, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x22, + 0x21, 0x22, 0x2D, 0x34, 0xA4, 0xA2, 0xA2, 0xA9, + 0xBF, 0xC0, 0xC3, 0xC1, 0xC0, 0xBE, 0xA6, 0x9D, + 0x99, 0x87, 0xA2, 0xF1, 0xDC, 0x64, 0x42, 0x45, + 0x47, 0x3E, 0x49, 0x4C, 0xDD, 0xDF, 0xD8, 0xDB, + 0x5E, 0x4C, 0x48, 0x45, 0x45, 0x41, 0xD1, 0xD6, + 0x5A, 0x55, 0x3F, 0xA7, 0xA1, 0x98, 0x9F, 0x99, + 0x9F, 0x9D, 0x9A, 0x95, 0x8B, 0x97, 0x89, 0x8A, + 0x88, 0x94, 0x9C, 0x8C, 0xFC, 0xFC, 0xFC, 0xFC, + 0xF4, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x22, 0x23, + 0x23, 0x23, 0x2C, 0x2C, 0xA8, 0xA2, 0xA4, 0xA4, + 0xA9, 0xAA, 0xAA, 0xAA, 0xA9, 0xA6, 0x98, 0x9C, + 0x8B, 0x88, 0x98, 0x8D, 0xD8, 0xD6, 0x4E, 0x47, + 0x47, 0x49, 0x47, 0x3F, 0xDA, 0xDD, 0xDE, 0xDD, + 0xCC, 0x4A, 0x4B, 0x3E, 0x45, 0x43, 0x61, 0xD4, + 0x56, 0x51, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0x9A, + 0xA0, 0xA2, 0x98, 0x98, 0x8B, 0x8B, 0x98, 0x98, + 0x84, 0x8B, 0x94, 0x8A, 0xA4, 0xFC, 0xFC, 0xFC, + 0xFC, 0xF2, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x23, 0x22, 0x23, 0x23, 0x23, 0x23, + 0x23, 0x22, 0x2C, 0x2D, 0xC0, 0xA4, 0xA2, 0xA4, + 0xA4, 0xA6, 0xA6, 0xA6, 0xA4, 0xA2, 0x9F, 0x89, + 0x8B, 0x9C, 0x9C, 0x8B, 0x68, 0xDB, 0x5F, 0x4B, + 0x3E, 0x49, 0x4B, 0x3E, 0xCC, 0xDA, 0xDC, 0xDD, + 0xD3, 0x49, 0x52, 0x48, 0x45, 0x45, 0x53, 0xD0, + 0x51, 0x4A, 0x44, 0xA4, 0x9B, 0x8B, 0x9C, 0xA0, + 0x9B, 0x86, 0x89, 0x98, 0x89, 0x8A, 0x96, 0x8A, + 0x9C, 0x89, 0x89, 0x9C, 0x8C, 0xF6, 0xFC, 0xFC, + 0xFC, 0xFC, 0x21, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, + 0x22, 0x21, 0x2B, 0x34, 0xC0, 0xA8, 0xA4, 0xA2, + 0xA2, 0x98, 0xA1, 0xA0, 0x98, 0x9F, 0x95, 0x8A, + 0x94, 0xA1, 0x8A, 0x84, 0x9B, 0x68, 0xCC, 0x49, + 0x4A, 0x47, 0x4C, 0x4B, 0x51, 0xD3, 0xDA, 0xDC, + 0xD5, 0x56, 0x56, 0x4A, 0x3E, 0x45, 0x48, 0x63, + 0x4A, 0x47, 0x3E, 0xA7, 0x98, 0x9D, 0x9E, 0x8B, + 0x95, 0x9B, 0x89, 0x86, 0x9B, 0x8B, 0x89, 0x84, + 0x9A, 0xA1, 0x95, 0x9A, 0x8C, 0xA4, 0xFC, 0xFC, + 0xFC, 0xFA, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x23, + 0x21, 0x23, 0x2C, 0xF6, 0xBF, 0xA9, 0xA2, 0x99, + 0x9D, 0x9D, 0x9D, 0x9D, 0x9D, 0x9B, 0x87, 0x8B, + 0x9C, 0x86, 0x9C, 0x8A, 0x87, 0x87, 0x89, 0x51, + 0x54, 0x47, 0x4B, 0x50, 0x4B, 0xCF, 0xD6, 0xDC, + 0xD5, 0x60, 0x54, 0x52, 0x48, 0x45, 0x40, 0x5A, + 0x45, 0x43, 0x47, 0xA7, 0x98, 0x9B, 0x95, 0x95, + 0x9A, 0x87, 0x98, 0x98, 0x8A, 0x86, 0x87, 0x9E, + 0x9B, 0x95, 0x9D, 0x9D, 0x99, 0x85, 0xA6, 0xFA, + 0xF2, 0x21, 0x23, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x22, 0x22, + 0x21, 0x24, 0xFB, 0xF7, 0xBF, 0xA6, 0xA2, 0x99, + 0x97, 0x89, 0x86, 0x89, 0x9C, 0x96, 0x9E, 0x94, + 0x89, 0x99, 0x98, 0x89, 0x9E, 0x9B, 0x89, 0x8B, + 0x58, 0x4B, 0x4A, 0x52, 0x48, 0xCC, 0xD3, 0xDA, + 0xD3, 0x65, 0x4C, 0x58, 0x49, 0x3E, 0x2E, 0x4D, + 0x40, 0x41, 0x45, 0xA9, 0xA1, 0x9B, 0x9E, 0x9C, + 0x95, 0x8A, 0x94, 0x89, 0x96, 0x87, 0x9C, 0x9A, + 0x84, 0x9D, 0x9C, 0x9E, 0x9A, 0x9C, 0x9D, 0xBB, + 0x23, 0x23, 0x22, 0x22, 0x21, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x23, 0x22, 0x21, 0x23, 0x23, + 0x24, 0xFC, 0xFC, 0xF6, 0xBF, 0xA6, 0x9F, 0x99, + 0x89, 0x95, 0x87, 0x94, 0x9D, 0x9E, 0x97, 0x9E, + 0x95, 0x9B, 0x89, 0x95, 0x95, 0x9B, 0x89, 0x87, + 0x5D, 0x56, 0x3E, 0x51, 0x3E, 0x60, 0xCF, 0xD3, + 0xD2, 0xCD, 0x5C, 0x49, 0x4B, 0x3E, 0x2C, 0x48, + 0x3E, 0x43, 0x3E, 0xA9, 0xA1, 0x9B, 0x97, 0x94, + 0x95, 0x9A, 0x9C, 0x87, 0x87, 0x9B, 0x9C, 0x95, + 0x9D, 0x89, 0x9A, 0x89, 0x9E, 0x9E, 0x8C, 0xA6, + 0x20, 0x23, 0x23, 0x22, 0x23, 0x22, 0x23, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x21, 0x21, 0x20, 0x40, + 0xFC, 0xFC, 0xFC, 0xEC, 0xBE, 0xA4, 0x9F, 0x99, + 0x95, 0x9F, 0xA0, 0x88, 0x9D, 0x8B, 0x97, 0x95, + 0x87, 0x95, 0x96, 0x95, 0x97, 0x94, 0x94, 0x98, + 0xD3, 0x4C, 0x47, 0x4D, 0x42, 0x4C, 0x60, 0xCC, + 0xCE, 0xD0, 0x65, 0x4B, 0x47, 0x44, 0x2B, 0x45, + 0x4B, 0x47, 0x49, 0xA7, 0xA1, 0x9A, 0x97, 0x89, + 0x95, 0x97, 0x97, 0x9E, 0x89, 0x95, 0x89, 0x9C, + 0x87, 0x95, 0x97, 0x99, 0x95, 0x99, 0x9F, 0xA4, + 0xC4, 0x21, 0x21, 0x23, 0x21, 0x23, 0x23, 0x23, + 0x23, 0x23, 0x23, 0x23, 0x21, 0x20, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEA, 0xAA, 0xA6, 0xA2, 0x99, + 0x8B, 0x9A, 0x95, 0x9E, 0x9E, 0x9A, 0x94, 0x87, + 0x94, 0x94, 0x89, 0x94, 0x9B, 0x9B, 0xA7, 0xDC, + 0xDB, 0x65, 0x2E, 0x3E, 0x43, 0x44, 0x49, 0x58, + 0x63, 0xD3, 0xD3, 0x5E, 0x42, 0x42, 0x2D, 0x40, + 0x54, 0x4C, 0x4A, 0xA7, 0xA0, 0x99, 0x9B, 0x94, + 0xA0, 0x8A, 0x9B, 0x9D, 0x87, 0x95, 0x94, 0x8B, + 0x8A, 0x98, 0x9C, 0x8A, 0x9B, 0x99, 0xA2, 0xA6, + 0xBF, 0xEC, 0x2A, 0x20, 0x21, 0x23, 0x21, 0x20, + 0x20, 0x20, 0x20, 0x4C, 0xF9, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEB, 0xAA, 0xA4, 0x9F, 0x9C, + 0x8B, 0x9B, 0x88, 0x84, 0x9E, 0x9D, 0x96, 0x94, + 0x94, 0x9A, 0x9B, 0x9B, 0xA4, 0xD5, 0xCD, 0xDE, + 0xF1, 0xDA, 0x4C, 0x2D, 0x41, 0x2B, 0x42, 0x4C, + 0x5E, 0xD4, 0xD7, 0xCD, 0x49, 0x2E, 0x2E, 0x41, + 0x5E, 0x57, 0xA7, 0xA6, 0xA7, 0xA4, 0xA2, 0x98, + 0x9D, 0x9C, 0xA1, 0x99, 0x9D, 0x88, 0x8B, 0x9C, + 0x8A, 0x9C, 0x9C, 0x94, 0x9C, 0x89, 0xA0, 0xA6, + 0xAA, 0xEB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFB, 0xE9, 0xAA, 0xA6, 0xA2, 0x8B, + 0x8B, 0x8A, 0x86, 0x9B, 0x9C, 0x98, 0xA0, 0x9B, + 0x9B, 0x84, 0xA7, 0xB4, 0x61, 0xD1, 0xD2, 0xE0, + 0xF1, 0xDC, 0x61, 0x2D, 0x2E, 0x3F, 0x56, 0x62, + 0x5D, 0xD4, 0xD9, 0xD3, 0x54, 0x41, 0x41, 0x44, + 0xCB, 0x60, 0x52, 0xA9, 0xA9, 0xA9, 0xA7, 0xA6, + 0xA6, 0xA4, 0xA4, 0xA2, 0xA2, 0x9D, 0x95, 0x89, + 0x9C, 0x8A, 0x9E, 0x9C, 0x8A, 0x9E, 0xA0, 0xA8, + 0xC0, 0xE9, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xE9, 0xAA, 0xA6, 0xA0, 0x99, + 0x9C, 0x8B, 0x9A, 0x84, 0x9B, 0x9B, 0x98, 0x98, + 0xA9, 0xB9, 0x49, 0x57, 0xCB, 0xD4, 0xD3, 0xF1, + 0xD8, 0xDA, 0xCE, 0x3F, 0x41, 0x4B, 0x5D, 0xCB, + 0x5E, 0xD6, 0xDB, 0xD6, 0x5D, 0x43, 0x3F, 0x49, + 0xD1, 0xCC, 0x4F, 0xDD, 0xC3, 0xBB, 0xBF, 0xAA, + 0xAA, 0xA9, 0xAA, 0xA8, 0xA8, 0xA6, 0xA6, 0xA2, + 0x9C, 0x9F, 0x9B, 0x9A, 0x9D, 0xA2, 0xA8, 0xAA, + 0xC1, 0xEA, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEA, 0xC0, 0xAA, 0xA6, 0xA2, + 0xA2, 0x99, 0xA0, 0xA0, 0xA4, 0xA7, 0xA9, 0xC0, + 0x67, 0x49, 0x54, 0x60, 0xD0, 0xD4, 0xCC, 0xDF, + 0xD9, 0xD5, 0xD2, 0x3E, 0x47, 0x56, 0x60, 0xCD, + 0x5D, 0xD9, 0xD9, 0xD6, 0x61, 0x3F, 0x47, 0x52, + 0xD6, 0xD3, 0x62, 0x4D, 0x40, 0x4A, 0x57, 0xCA, + 0xC3, 0xC1, 0xC1, 0xC0, 0xBF, 0xBF, 0xAA, 0xAA, + 0xA6, 0xA4, 0xA4, 0xA4, 0xA6, 0xA8, 0xBE, 0xC1, + 0xC9, 0xEB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, + 0xFC, 0xFC, 0xFC, 0xEB, 0xC3, 0xC0, 0xAA, 0xA8, + 0xA6, 0xA6, 0xA6, 0xA9, 0xAA, 0xC0, 0xE8, 0xD0, + 0xD2, 0x4C, 0x5E, 0x64, 0xD0, 0xD1, 0x5F, 0xD9, + 0xD5, 0xD1, 0xD0, 0x48, 0x52, 0x5C, 0x64, 0xCD, + 0x5C, 0xDC, 0xD7, 0xD5, 0x62, 0x3F, 0x4C, 0x53, + 0xDA, 0xD7, 0xCE, 0x56, 0x40, 0x4B, 0x52, 0x56, + 0xCE, 0xDF, 0x6A, 0xEB, 0xE9, 0xC9, 0xC3, 0xC0, + 0xC0, 0xBF, 0xBE, 0xAA, 0xBF, 0xC0, 0xC3, 0xC9, + 0xEA, 0xF6, 0xEE, 0x58, 0x57, 0x5E, 0xD6, 0xD0, + 0xD2, 0x61, 0xCB, 0xD6, 0xD6, 0xD4, 0xDF, 0xF3, + 0xF2, 0xDD, 0xD7, 0xEB, 0xC9, 0xC1, 0xC0, 0xBF, + 0xAA, 0xAA, 0xAA, 0xBE, 0xC3, 0xF0, 0xD2, 0xD2, + 0xD2, 0x51, 0x62, 0xCC, 0xD0, 0xCC, 0x61, 0xD3, + 0xCF, 0xCE, 0xD2, 0x48, 0x5A, 0x61, 0xCC, 0xCE, + 0x5F, 0xD9, 0xD5, 0xD1, 0x63, 0x44, 0x56, 0x56, + 0xDC, 0xD9, 0xD4, 0x5E, 0x42, 0x4A, 0x4C, 0x57, + 0x5D, 0xD8, 0xE0, 0xD8, 0xDC, 0xCB, 0x66, 0xEC, + 0xE8, 0xC3, 0xC3, 0xC3, 0xC3, 0xC9, 0xE8, 0xEA, + 0xF6, 0x50, 0x3E, 0x58, 0x57, 0x5A, 0xD6, 0xD4, + 0xCC, 0x4B, 0x53, 0x5C, 0x64, 0xD1, 0xDF, 0xF3, + 0xF1, 0xDE, 0xD9, 0xF6, 0xEB, 0xC9, 0xC1, 0xC1, + 0xC0, 0xC0, 0xC1, 0xC9, 0xF0, 0xD6, 0xCD, 0xD6, + 0xD3, 0x53, 0xCB, 0xCF, 0xCD, 0x5F, 0x5F, 0xCE, + 0xCF, 0xCD, 0xD0, 0x47, 0x5F, 0xCB, 0xCE, 0xCD, + 0x63, 0xD6, 0xD3, 0xD1, 0x63, 0x3F, 0x58, 0x58, + 0xDB, 0xDC, 0xDA, 0x65, 0x3E, 0x49, 0x49, 0x4D, + 0x49, 0xDC, 0xDF, 0xE0, 0xDE, 0xD5, 0x47, 0x47, + 0x46, 0x6B, 0xEB, 0xEA, 0xE9, 0xEA, 0xEB, 0xF6, + 0xD0, 0x57, 0x57, 0x47, 0x47, 0x5B, 0xD4, 0xD4, + 0xCD, 0x44, 0x3E, 0x4B, 0x50, 0x4B, 0x51, 0xD5, + 0xDB, 0xD8, 0xDE, 0x4B, 0xF6, 0xF6, 0xEA, 0xE9, + 0xE8, 0xEA, 0xEB, 0x67, 0x5E, 0xCC, 0xD6, 0xDC, + 0xD5, 0x58, 0xCE, 0xCE, 0x62, 0x50, 0xCC, 0xD3, + 0xD2, 0xCD, 0xCD, 0x4B, 0x64, 0xCE, 0xCE, 0x64, + 0xCC, 0xD3, 0xD2, 0xD2, 0x61, 0x47, 0x5D, 0x5C, + 0xDD, 0xDD, 0xD9, 0xD1, 0x4C, 0x47, 0x49, 0x4A, + 0x4B, 0xD1, 0xD8, 0xE0, 0xDF, 0xDD, 0x5D, 0x4A, + 0x48, 0x52, 0x51, 0x3F, 0xF6, 0xEC, 0xE0, 0xE0, + 0xD3, 0x5E, 0x5F, 0x50, 0x4B, 0x50, 0xCB, 0xCE, + 0x64, 0x45, 0x4C, 0x57, 0x57, 0x58, 0x52, 0xD6, + 0xD3, 0xDE, 0xDF, 0xD1, 0x3E, 0x4B, 0xF6, 0xF6, + 0xEC, 0x66, 0x53, 0x43, 0x56, 0xD1, 0xD9, 0xDE, + 0xD4, 0x5E, 0xCE, 0xCC, 0x5B, 0x2C, 0xD4, 0xD5, + 0xD2, 0xD0, 0x63, 0x5D, 0xCD, 0xD0, 0xCD, 0x5E, + 0xD0, 0xCF, 0xCE, 0xD2, 0x5E, 0x50, 0x60, 0x5D, + 0xDE, 0xDD, 0xDC, 0xD7, 0x5D, 0x45, 0x47, 0x3E, + 0x4B, 0x5E, 0xDE, 0xDF, 0xE0, 0xD8, 0xCF, 0x3E, + 0x45, 0x51, 0x58, 0x42, 0xCB, 0xDA, 0xDE, 0xD8, + 0xD2, 0x61, 0xCC, 0xCF, 0xD6, 0xDA, 0xDA, 0xD5, + 0xD0, 0x50, 0x44, 0x57, 0x57, 0x58, 0x45, 0xD1, + 0xD1, 0xD7, 0xDF, 0xDF, 0xD7, 0xCF, 0x64, 0x60, + 0xCE, 0xCE, 0xCE, 0x63, 0xCF, 0xDA, 0xDE, 0xD9, + 0xCF, 0x63, 0xCD, 0x63, 0x4D, 0x4B, 0xD6, 0xD5, + 0xCE, 0xD3, 0x60, 0xCB, 0xD0, 0xD0, 0x65, 0x47, + 0xD0, 0xCC, 0xCC, 0xD1, 0x59, 0x5D, 0x63, 0x5E, + 0xDD, 0xDD, 0xDE, 0xDC, 0xCB, 0x40, 0x48, 0x45, + 0x3E, 0x3E, 0xD9, 0xDF, 0xE0, 0xDF, 0xDA, 0x51, + 0x4C, 0x48, 0x56, 0x4C, 0x5B, 0xD2, 0xDA, 0xDB, + 0xCB, 0x5F, 0xD0, 0xCC, 0xDC, 0xF0, 0xF3, 0xE0, + 0xDD, 0xCC, 0x41, 0x50, 0x57, 0x57, 0x4B, 0x5D, + 0xD3, 0xD1, 0xDE, 0xDF, 0xDE, 0xD7, 0xD0, 0xD0, + 0xD5, 0xD6, 0xD6, 0xCE, 0xD7, 0xDC, 0xDA, 0xD5, + 0x60, 0x63, 0x64, 0x5E, 0x47, 0x61, 0xD5, 0xD2, + 0xCF, 0xD0, 0x59, 0xCD, 0xD1, 0xCF, 0x61, 0x4D, + 0xCC, 0xCE, 0xCD, 0xD0, 0x52, 0x61, 0x64, 0x60, + 0xDA, 0xDE, 0xDE, 0xDD, 0xD1, 0x4B, 0x4A, 0x45, + 0x3E, 0x41, 0xCD, 0xDE, 0xE0, 0xF1, 0xDE, 0x63, + 0x4A, 0x4A, 0x4A, 0x4B, 0x50, 0xCB, 0xD4, 0xD7, + 0x5E, 0x54, 0x62, 0xD3, 0xD4, 0xF0, 0xF3, 0xF3, + 0xF2, 0xDE, 0x61, 0x40, 0x49, 0x56, 0x4D, 0x3E, + 0x4B, 0xCE, 0xD9, 0xD8, 0xD9, 0xD5, 0xCF, 0xD2, + 0xD6, 0xD6, 0xD1, 0xD1, 0xD7, 0xD5, 0xCF, 0xD0, + 0x54, 0x64, 0x63, 0x56, 0x2C, 0xCB, 0xD1, 0xCC, + 0xD3, 0xCD, 0x54, 0xCF, 0xD1, 0xCE, 0x5E, 0x5C, + 0xCE, 0xCE, 0xCE, 0xCB, 0x4B, 0x63, 0xCC, 0x61, + 0xD4, 0xDC, 0xDE, 0xDE, 0xDA, 0x5D, 0x45, 0x45, + 0x48, 0x3F, 0x52, 0xD9, 0xD8, 0xDF, 0xDF, 0xD2, + 0x52, 0x4B, 0x3E, 0x2E, 0x47, 0x60, 0xCF, 0xD3, + 0x59, 0x48, 0x50, 0x5E, 0xCC, 0xDE, 0xF2, 0xF2, + 0xF3, 0xF3, 0xDD, 0x5D, 0x3E, 0x48, 0x47, 0x47, + 0x58, 0xD1, 0xDA, 0xDA, 0xD5, 0xD1, 0xCD, 0xD2, + 0xD3, 0xCF, 0xD3, 0xD1, 0xCD, 0xD3, 0xD2, 0x5E, + 0x52, 0x64, 0x60, 0x4B, 0x45, 0x61, 0xCD, 0xD3, + 0xD3, 0x64, 0x61, 0xD0, 0xD0, 0x64, 0x45, 0x63, + 0xD0, 0xCE, 0xD0, 0x60, 0x56, 0xCB, 0xCC, 0x62, + 0xCE, 0xDA, 0xDE, 0xD8, 0xDD, 0xCC, 0x45, 0x49, + 0x3E, 0x47, 0x42, 0xD1, 0xDC, 0xD8, 0xD8, 0xD3, + 0x5D, 0x4C, 0x49, 0x3F, 0x47, 0x59, 0xCD, 0xCF, + 0x59, 0x2E, 0x48, 0x47, 0x52, 0x63, 0xF0, 0xF2, + 0xF3, 0xF3, 0xF2, 0xDA, 0x52, 0x4B, 0x52, 0x58, + 0x5E, 0x63, 0xD0, 0xD0, 0xD0, 0xCF, 0xCE, 0xCE, + 0xCF, 0x65, 0x61, 0xD6, 0xD6, 0xD6, 0xCB, 0x4B, + 0x61, 0x62, 0x5D, 0x43, 0x4B, 0x61, 0xD0, 0xD4, + 0xD1, 0x61, 0xCE, 0xD2, 0xCD, 0x5E, 0x4A, 0xCE, + 0xD0, 0xCC, 0xD0, 0x59, 0x61, 0xCC, 0xCC, 0x62, + 0xD1, 0xD5, 0xDE, 0xD8, 0xDD, 0xCF, 0x4B, 0x4A, + 0x45, 0x3E, 0x2D, 0xCB, 0xDC, 0xDE, 0xD8, 0xD5, + 0x60, 0x54, 0x51, 0x4C, 0x4D, 0x5C, 0xCC, 0xCE, + 0x5A, 0x2C, 0x50, 0x53, 0x3E, 0x59, 0xD8, 0xF3, + 0xF2, 0xF3, 0xF3, 0xE0, 0x5E, 0x4A, 0x4C, 0x53, + 0x5E, 0x63, 0xCC, 0xCC, 0xCC, 0xCD, 0xCF, 0xD3, + 0x62, 0x53, 0xD6, 0xD6, 0xD6, 0xD6, 0x5B, 0x48, + 0x64, 0x63, 0x59, 0x44, 0x57, 0x63, 0xD2, 0xD3, + 0xD0, 0x5E, 0xD0, 0xD1, 0xCB, 0x58, 0x4C, 0xCF, + 0xCF, 0xCE, 0xCE, 0x57, 0x63, 0xCC, 0xCD, 0x57, +}; + diff -Nru a/drivers/sound/dmasound/Makefile b/drivers/sound/dmasound/Makefile --- a/drivers/sound/dmasound/Makefile Sat Jun 16 06:00:26 2001 +++ b/drivers/sound/dmasound/Makefile Sat Jun 16 06:00:26 2001 @@ -7,15 +7,21 @@ # # Note 2! The CFLAGS definitions are now in the main makefile... +O_TARGET = dmasound.o + export-objs := dmasound_core.o -obj-$(CONFIG_DMASOUND_ATARI) += dmasound_core.o dmasound_atari.o -obj-$(CONFIG_DMASOUND_AWACS) += dmasound_core.o dmasound_awacs.o -obj-$(CONFIG_DMASOUND_PAULA) += dmasound_core.o dmasound_paula.o -obj-$(CONFIG_DMASOUND_Q40) += dmasound_core.o dmasound_q40.o - -ifeq ($(CONFIG_DMASOUND),y) - O_TARGET = dmasound.o -endif +list-multi := dmasound_pmac.o + +dmasound_pmac-objs := dmasound_awacs.o + +obj-$(CONFIG_DMASOUND) += dmasound_core.o +obj-$(CONFIG_DMASOUND_ATARI) += dmasound_atari.o +obj-$(CONFIG_DMASOUND_AWACS) += dmasound_pmac.o +obj-$(CONFIG_DMASOUND_PAULA) += dmasound_paula.o +obj-$(CONFIG_DMASOUND_Q40) += dmasound_q40.o include $(TOPDIR)/Rules.make + +dmasound_pmac.o: $(dmasound_pmac-objs) + $(LD) $(EXTRA_LDFLAGS) -r -o $@ $(dmasound_pmac-objs) diff -Nru a/drivers/sound/dmasound/dmasound.h b/drivers/sound/dmasound/dmasound.h --- a/drivers/sound/dmasound/dmasound.h Sat Jun 16 06:00:22 2001 +++ b/drivers/sound/dmasound/dmasound.h Sat Jun 16 06:00:22 2001 @@ -29,6 +29,9 @@ #define SND_DEV_SNDPROC 9 /* /dev/sndproc for programmable devices */ #define SND_DEV_PSS SND_DEV_SNDPROC +#define DMASOUND_CORE_REVISION 1 +#define DMASOUND_CORE_EDITION 1 + #define DSP_DEFAULT_SPEED 8000 #define ON 1 @@ -121,12 +124,13 @@ void (*record)(void); /* optional */ void (*mixer_init)(void); /* optional */ int (*mixer_ioctl)(u_int, u_long); /* optional */ - void (*write_sq_setup)(void); /* optional */ - void (*read_sq_setup)(void); /* optional */ + int (*write_sq_setup)(void); /* optional */ + int (*read_sq_setup)(void); /* optional */ void (*sq_open)(void); /* optional */ int (*state_info)(char *); /* optional */ void (*abort_read)(void); /* optional */ int min_dsp_speed; + int version; } MACHINE; diff -Nru a/drivers/sound/dmasound/dmasound_atari.c b/drivers/sound/dmasound/dmasound_atari.c --- a/drivers/sound/dmasound/dmasound_atari.c Sat Jun 16 06:00:16 2001 +++ b/drivers/sound/dmasound/dmasound_atari.c Sat Jun 16 06:00:16 2001 @@ -1438,9 +1438,10 @@ return AtaMixerIoctl(cmd, arg); } -static void AtaWriteSqSetup(void) +static int AtaWriteSqSetup(void) { write_sq_ignore_int = 0; + return 0; } static void AtaSqOpen(void) diff -Nru a/drivers/sound/dmasound/dmasound_awacs.c b/drivers/sound/dmasound/dmasound_awacs.c --- a/drivers/sound/dmasound/dmasound_awacs.c Sat Jun 16 06:00:25 2001 +++ b/drivers/sound/dmasound/dmasound_awacs.c Sat Jun 16 06:00:25 2001 @@ -4,7 +4,14 @@ * * PowerMac `AWACS' and `Burgundy' DMA Sound Driver * - * See linux/drivers/sound/dmasound/dmasound_core.c for copyright and credits + * See linux/drivers/sound/dmasound/dmasound_core.c for copyright and + * history prior to 2001/01/26. + * + * 26/01/2001 ed 0.1 Iain Sandoe + * - added version info. + * - moved dbdma command buffer allocation to PMacXXXSqSetup() + * - fixed up beep dbdma cmd buffers + * */ @@ -18,6 +25,7 @@ #include #include #include +#include #ifdef CONFIG_ADB_CUDA #include #endif @@ -36,6 +44,8 @@ #include "awacs_defs.h" #include "dmasound.h" +#define DMASOUND_AWACS_REVISION 0 +#define DMASOUND_AWACS_EDITION 1 /* * Interrupt numbers and addresses, obtained from the device tree. @@ -54,15 +64,18 @@ int awacs_device_id = 0; int awacs_has_iic = 0; #define AWACS_BURGUNDY 100 /* fake revision # for burgundy */ +#define AWACS_DACA 80 /* fake revision # for daca (ibook)? */ /* * Space for the DBDMA command blocks. */ static void *awacs_tx_cmd_space; static volatile struct dbdma_cmd *awacs_tx_cmds; +static int number_of_tx_cmd_buffers = 0; static void *awacs_rx_cmd_space; static volatile struct dbdma_cmd *awacs_rx_cmds; +static int number_of_rx_cmd_buffers = 0; /* * Cached values of AWACS registers (we can't read them). @@ -121,6 +134,7 @@ static int beep_playing = 0; static int awacs_beep_state = 0; static short *beep_buf; +static void *beep_dbdma_cmd_space; static volatile struct dbdma_cmd *beep_dbdma_cmd; static void (*orig_mksound)(unsigned int, unsigned int); static int is_pbook_3400; @@ -246,8 +260,8 @@ static int PMacMixerIoctl(u_int cmd, u_long arg); -static void PMacWriteSqSetup(void); -static void PMacReadSqSetup(void); +static int PMacWriteSqSetup(void); +static int PMacReadSqSetup(void); static void PMacAbortRead(void); @@ -850,12 +864,16 @@ free_irq(awacs_irq, 0); free_irq(awacs_tx_irq, 0); free_irq(awacs_rx_irq, 0); - kfree(awacs_tx_cmd_space); + if (awacs_tx_cmd_space) + kfree(awacs_tx_cmd_space); if (awacs_rx_cmd_space) kfree(awacs_rx_cmd_space); - if (beep_buf) + if (beep_dbdma_cmd_space) + kfree(beep_dbdma_cmd_space); + if (beep_buf) { kfree(beep_buf); - kd_mksound = orig_mksound; + kd_mksound = orig_mksound; + } #ifdef CONFIG_PMAC_PBOOK pmu_unregister_sleep_notifier(&awacs_sleep_notifier); #endif @@ -1017,6 +1035,8 @@ if (awacs_beep_state) { /* sound takes precedence over beeps */ out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + while (in_le32(&awacs_txdma->status) & RUN) + udelay(1); out_le32(&awacs->control, (in_le32(&awacs->control) & ~0x1f00) | (awacs_rate_index << 8)); @@ -1043,6 +1063,7 @@ out_le16(&cp->command, OUTPUT_MORE + INTR_ALWAYS); if (write_sq.active == 0) out_le32(&awacs_txdma->cmdptr, virt_to_bus(cp)); + (void)in_le32(&awacs_txdma->status); out_le32(&awacs_txdma->control, ((RUN|WAKE) << 16) + (RUN|WAKE)); ++write_sq.active; } @@ -1099,7 +1120,6 @@ static void pmac_awacs_rx_intr(int irq, void *devid, struct pt_regs *regs) { - /* For some reason on my PowerBook G3, I get one interrupt * when the interrupt vector is installed (like something is * pending). This happens before the dbdma is initialize by @@ -1167,7 +1187,7 @@ static void awacs_write(int val) { - if (awacs_revision >= AWACS_BURGUNDY) + if (awacs_revision >= AWACS_DACA) return; while (in_le32(&awacs->codec_ctrl) & MASK_NEWECMD) ; /* XXX should have timeout */ @@ -1182,6 +1202,8 @@ if (beep_playing) { st_le16(&beep_dbdma_cmd->command, DBDMA_STOP); out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + while (in_le32(&awacs_txdma->status) & RUN) + udelay(1); out_le32(&awacs->control, (in_le32(&awacs->control) & ~0x1f00) | (awacs_rate_index << 8)); @@ -1207,6 +1229,8 @@ static int beep_nsamples_cache; static int beep_volume_cache; + if (beep_buf == NULL) + return; for (i = 0; i < 8 && awacs_freqs[i] >= BEEP_SRATE; ++i) if (awacs_freqs_ok[i]) beep_speed = i; @@ -1264,11 +1288,14 @@ save_flags(flags); cli(); if (beep_playing) { /* i.e. haven't been terminated already */ out_le32(&awacs_txdma->control, (RUN|WAKE|FLUSH|PAUSE) << 16); + while (in_le32(&awacs_txdma->status) & RUN) + udelay(1); out_le32(&awacs->control, (in_le32(&awacs->control) & ~0x1f00) | (beep_speed << 8)); out_le32(&awacs->byteswap, 0); out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd)); + (void)in_le32(&awacs_txdma->status); out_le32(&awacs_txdma->control, RUN | (RUN << 16)); } restore_flags(flags); @@ -1558,13 +1585,13 @@ static void awacs_enable_amp(int spkr_vol) { +#ifdef CONFIG_ADB_CUDA struct adb_request req; awacs_spkr_vol = spkr_vol; if (sys_ctrler != SYS_CTRLER_CUDA) return; -#ifdef CONFIG_ADB_CUDA /* turn on headphones */ cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC, 0x8a, 4, 0); @@ -1871,11 +1898,53 @@ } -static void PMacWriteSqSetup(void) +/* Write/Read sq setup functions: + Check to see if we have enough (or any) dbdma cmd buffers for the + user's fragment settings. If not, allocate some. If this fails we will + point at the beep buffer - as an emergency provision - to stop dma tromping + on some random bit of memory (if someone lets it go anyway). + The command buffers are then set up to point to the fragment buffers + (allocated elsewhere). We need n+1 commands the last of which holds + a NOP + loop to start. +*/ + +static int PMacWriteSqSetup(void) { int i; volatile struct dbdma_cmd *cp; + /* stop the controller from doing any output - if it isn't already. + it _should_ be before this is called anyway */ + + out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + while (in_le32(&awacs_txdma->status) & RUN) + udelay(1); + + if ((write_sq.numBufs+1) > number_of_tx_cmd_buffers) { + if (awacs_tx_cmd_space) + kfree(awacs_tx_cmd_space); + number_of_tx_cmd_buffers = 0; + + /* we need nbufs + 1 (for the loop) and we should request + 1 again + because the DBDMA_ALIGN might pull the start up by up to + sizeof(struct dbdma_cmd) - 4 (assuming kmalloc aligns 32 bits). + */ + + awacs_tx_cmd_space = kmalloc + ((write_sq.numBufs + 1 + 1) * sizeof(struct dbdma_cmd), + GFP_KERNEL); + if (awacs_tx_cmd_space == NULL) { + /* don't leave it dangling - nasty but better than a random address */ + out_le32(&awacs_txdma->cmdptr, virt_to_bus(beep_dbdma_cmd)); + printk(KERN_ERR + "dmasound_pmac: can't allocate dbdma cmd buffers, driver disabled\n"); + return -ENOMEM; + } + awacs_tx_cmds = (volatile struct dbdma_cmd *) + DBDMA_ALIGN(awacs_tx_cmd_space); + number_of_tx_cmd_buffers = write_sq.numBufs + 1; + } + cp = awacs_tx_cmds; memset((void *)cp, 0, (write_sq.numBufs+1) * sizeof(struct dbdma_cmd)); for (i = 0; i < write_sq.numBufs; ++i, ++cp) { @@ -1883,15 +1952,47 @@ } st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS); st_le32(&cp->cmd_dep, virt_to_bus(awacs_tx_cmds)); - out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + /* point the controller at the command stack - ready to go */ out_le32(&awacs_txdma->cmdptr, virt_to_bus(awacs_tx_cmds)); + return 0; } -static void PMacReadSqSetup(void) +static int PMacReadSqSetup(void) { int i; volatile struct dbdma_cmd *cp; + /* stop the controller from doing any input - if it isn't already. + it _should_ be before this is called anyway */ + + out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + while (in_le32(&awacs_rxdma->status) & RUN) + udelay(1); + + if( (read_sq.numBufs+1) > number_of_rx_cmd_buffers ) { + if (awacs_rx_cmd_space) + kfree(awacs_rx_cmd_space); + number_of_rx_cmd_buffers = 0; + + /* we need nbufs + 1 (for the loop) and we should request + 1 again + because the DBDMA_ALIGN might pull the start up by up to + sizeof(struct dbdma_cmd) - 4 (assuming kmalloc aligns 32 bits). + */ + + awacs_rx_cmd_space = kmalloc + ((read_sq.numBufs + 1 + 1) * sizeof(struct dbdma_cmd), + GFP_KERNEL); + if (awacs_rx_cmd_space == NULL) { + /* don't leave it dangling - nasty but better than a random address */ + out_le32(&awacs_rxdma->cmdptr, virt_to_bus(beep_dbdma_cmd)); + printk(KERN_ERR + "dmasound_pmac: can't allocate dbdma cmd buffers, driver disabled\n"); + return -ENOMEM; + } + awacs_rx_cmds = (volatile struct dbdma_cmd *) + DBDMA_ALIGN(awacs_rx_cmd_space); + number_of_rx_cmd_buffers = read_sq.numBufs+1 ; + } cp = awacs_rx_cmds; memset((void *)cp, 0, (read_sq.numBufs+1) * sizeof(struct dbdma_cmd)); @@ -1907,14 +2008,9 @@ */ st_le16(&cp->command, DBDMA_NOP + BR_ALWAYS); st_le32(&cp->cmd_dep, virt_to_bus(awacs_rx_cmds)); - - /* Don't start until the first read is done. - * This will also abort any operations in progress if the DMA - * happens to be running (and it shouldn't). - */ - out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE) << 16); + /* point the controller at the command stack - ready to go */ out_le32(&awacs_rxdma->cmdptr, virt_to_bus(awacs_rx_cmds)); - + return 0; } static void PMacAbortRead(void) @@ -1937,7 +2033,7 @@ static MACHINE machPMac = { name: awacs_name, - name2: "AWACS", + name2: "Built-in Sound", open: PMacOpen, release: PMacRelease, dma_alloc: PMacAlloc, @@ -1956,7 +2052,8 @@ write_sq_setup: PMacWriteSqSetup, read_sq_setup: PMacReadSqSetup, abort_read: PMacAbortRead, - min_dsp_speed: 8000 + min_dsp_speed: 8000, + version: ((DMASOUND_AWACS_REVISION<<8) + DMASOUND_AWACS_EDITION) }; @@ -1966,6 +2063,7 @@ int __init dmasound_awacs_init(void) { struct device_node *np; + int vol; if (_machine != _MACH_Pmac) return -ENODEV; @@ -1974,203 +2072,218 @@ awacs_revision = 0; np = find_devices("awacs"); if (np == 0) { + unsigned int *prop, l, i; + /* * powermac G3 models have a node called "davbus" * with a child called "sound". */ struct device_node *sound; np = find_devices("davbus"); + /* + * if we didn't find a davbus device, try 'i2s-a' since + * this seems to be what iBooks have + */ + if (np == NULL) { + np = find_devices("i2s-a"); + } + if (np == NULL) + return -ENODEV; sound = find_devices("sound"); - if (sound != 0 && sound->parent == np) { - unsigned int *prop, l, i; - prop = (unsigned int *) - get_property(sound, "sub-frame", 0); - if (prop != 0 && *prop >= 0 && *prop < 16) - awacs_subframe = *prop; - if (device_is_compatible(sound, "burgundy")) - awacs_revision = AWACS_BURGUNDY; - /* This should be verified on older screamers */ - if (device_is_compatible(sound, "screamer")) - awacs_is_screamer = 1; - prop = (unsigned int *)get_property(sound, "device-id", 0); - if (prop != 0) - awacs_device_id = *prop; - awacs_has_iic = (find_devices("perch") != NULL); - - /* look for a property saying what sample rates - are available */ - for (i = 0; i < 8; ++i) - awacs_freqs_ok[i] = 0; + while (sound != 0 && sound->parent != np) + sound = sound->next; + if (sound == 0) + return -ENODEV; + prop = (unsigned int *) get_property(sound, "sub-frame", 0); + if (prop != 0 && *prop >= 0 && *prop < 16) + awacs_subframe = *prop; + if (device_is_compatible(sound, "burgundy")) + awacs_revision = AWACS_BURGUNDY; + if (device_is_compatible(sound, "daca")) + awacs_revision = AWACS_DACA; + /* This should be verified on older screamers */ + if (device_is_compatible(sound, "screamer")) + awacs_is_screamer = 1; + prop = (unsigned int *)get_property(sound, "device-id", 0); + if (prop != 0) + awacs_device_id = *prop; + awacs_has_iic = (find_devices("perch") != NULL); + + /* look for a property saying what sample rates + are available */ + for (i = 0; i < 8; ++i) + awacs_freqs_ok[i] = 0; + prop = (unsigned int *)get_property(sound, "sample-rates", &l); + if (prop == 0) prop = (unsigned int *) get_property - (sound, "sample-rates", &l); - if (prop == 0) - prop = (unsigned int *) get_property - (sound, "output-frame-rates", &l); - if (prop != 0) { - for (l /= sizeof(int); l > 0; --l) { - /* sometimes the rate is in the - high-order 16 bits (?) */ - unsigned int r = *prop++; - if (r >= 0x10000) - r >>= 16; - for (i = 0; i < 8; ++i) { - if (r == awacs_freqs[i]) { - awacs_freqs_ok[i] = 1; - break; - } + (sound, "output-frame-rates", &l); + if (prop != 0) { + for (l /= sizeof(int); l > 0; --l) { + /* sometimes the rate is in the + high-order 16 bits (?) */ + unsigned int r = *prop++; + if (r >= 0x10000) + r >>= 16; + for (i = 0; i < 8; ++i) { + if (r == awacs_freqs[i]) { + awacs_freqs_ok[i] = 1; + break; } } - } else { - /* assume just 44.1k is OK */ - awacs_freqs_ok[0] = 1; } + } else { + /* assume just 44.1k is OK */ + awacs_freqs_ok[0] = 1; } } - if (np != NULL && np->n_addrs >= 3 && np->n_intrs >= 3) { - int vol; - dmasound.mach = machPMac; - - awacs = (volatile struct awacs_regs *) - ioremap(np->addrs[0].address, 0x80); - awacs_txdma = (volatile struct dbdma_regs *) - ioremap(np->addrs[1].address, 0x100); - awacs_rxdma = (volatile struct dbdma_regs *) - ioremap(np->addrs[2].address, 0x100); - - awacs_irq = np->intrs[0].line; - awacs_tx_irq = np->intrs[1].line; - awacs_rx_irq = np->intrs[2].line; - - awacs_tx_cmd_space = kmalloc((write_sq.numBufs + 4) * sizeof(struct dbdma_cmd), - GFP_KERNEL); - if (awacs_tx_cmd_space == NULL) { - printk(KERN_ERR "DMA sound driver: Not enough buffer memory, driver disabled!\n"); - return -ENOMEM; - } - awacs_node = np; -#ifdef CONFIG_PMAC_PBOOK - if (machine_is_compatible("PowerBook1,1") - || machine_is_compatible("AAPL,PowerBook1998")) { - pmu_suspend(); - feature_set(np, FEATURE_Sound_CLK_enable); - feature_set(np, FEATURE_Sound_power); - /* Shorter delay will not work */ - mdelay(1000); - pmu_resume(); - } -#endif - awacs_tx_cmds = (volatile struct dbdma_cmd *) - DBDMA_ALIGN(awacs_tx_cmd_space); + if (np->n_addrs < 3 || np->n_intrs < 3) { + printk(KERN_ERR "AWACS: can't use %s (%d addrs, %d intrs)\n", + np->full_name, np->n_addrs, np->n_intrs); + return -ENODEV; + } + dmasound.mach = machPMac; - awacs_rx_cmd_space = kmalloc((read_sq.numBufs + 4) * sizeof(struct dbdma_cmd), - GFP_KERNEL); - if (awacs_rx_cmd_space == NULL) { - printk("DMA sound driver: No memory for input"); - } - awacs_rx_cmds = (volatile struct dbdma_cmd *) - DBDMA_ALIGN(awacs_rx_cmd_space); + awacs = (volatile struct awacs_regs *) + ioremap(np->addrs[0].address, 0x80); + awacs_txdma = (volatile struct dbdma_regs *) + ioremap(np->addrs[1].address, 0x100); + awacs_rxdma = (volatile struct dbdma_regs *) + ioremap(np->addrs[2].address, 0x100); + + awacs_irq = np->intrs[0].line; + awacs_tx_irq = np->intrs[1].line; + awacs_rx_irq = np->intrs[2].line; + awacs_node = np; +#ifdef CONFIG_PMAC_PBOOK + if (machine_is_compatible("PowerBook1,1") + || machine_is_compatible("AAPL,PowerBook1998")) { + feature_set(np, FEATURE_Sound_CLK_enable); + feature_set(np, FEATURE_Sound_power); + /* Shorter delay will not work */ + mdelay(1000); + } +#endif - awacs_reg[0] = MASK_MUX_CD; - /* FIXME: Only machines with external SRS module need MASK_PAROUT */ - awacs_reg[1] = MASK_LOOPTHRU; - if (awacs_has_iic || awacs_device_id == 0x5 || /*awacs_device_id == 0x8 - || */awacs_device_id == 0xb) - awacs_reg[1] |= MASK_PAROUT; - /* get default volume from nvram */ - vol = (~nvram_read_byte(0x1308) & 7) << 1; - awacs_reg[2] = vol + (vol << 6); - awacs_reg[4] = vol + (vol << 6); - awacs_reg[5] = 0; - awacs_reg[6] = 0; - awacs_reg[7] = 0; - out_le32(&awacs->control, 0x11); - awacs_write(awacs_reg[0] + MASK_ADDR0); - awacs_write(awacs_reg[1] + MASK_ADDR1); - awacs_write(awacs_reg[2] + MASK_ADDR2); - awacs_write(awacs_reg[4] + MASK_ADDR4); - if (awacs_is_screamer) { - awacs_write(awacs_reg[5] + MASK_ADDR5); - awacs_write(awacs_reg[6] + MASK_ADDR6); - awacs_write(awacs_reg[7] + MASK_ADDR7); + awacs_reg[0] = MASK_MUX_CD; + /* FIXME: Only machines with external SRS module need MASK_PAROUT */ + awacs_reg[1] = MASK_LOOPTHRU; + if (awacs_has_iic || awacs_device_id == 0x5 + || /*awacs_device_id == 0x8 ||*/ awacs_device_id == 0xb) + awacs_reg[1] |= MASK_PAROUT; + /* get default volume from nvram */ + vol = (~nvram_read_byte(0x1308) & 7) << 1; + awacs_reg[2] = vol + (vol << 6); + awacs_reg[4] = vol + (vol << 6); + awacs_reg[5] = 0; + awacs_reg[6] = 0; + awacs_reg[7] = 0; + out_le32(&awacs->control, 0x11); + awacs_write(awacs_reg[0] + MASK_ADDR0); + awacs_write(awacs_reg[1] + MASK_ADDR1); + awacs_write(awacs_reg[2] + MASK_ADDR2); + awacs_write(awacs_reg[4] + MASK_ADDR4); + if (awacs_is_screamer) { + awacs_write(awacs_reg[5] + MASK_ADDR5); + awacs_write(awacs_reg[6] + MASK_ADDR6); + awacs_write(awacs_reg[7] + MASK_ADDR7); + } + + /* Initialize recent versions of the awacs */ + if (awacs_revision == 0) { + awacs_revision = (in_le32(&awacs->codec_stat) >> 12) & 0xf; + if (awacs_revision == 3) { + mdelay(100); + awacs_write(0x6000); + mdelay(2); + awacs_write(awacs_reg[1] + MASK_ADDR1); + awacs_enable_amp(100 * 0x101); } + } + if (awacs_revision >= AWACS_BURGUNDY) + awacs_burgundy_init(); - /* Initialize recent versions of the awacs */ - if (awacs_revision == 0) { - awacs_revision = - (in_le32(&awacs->codec_stat) >> 12) & 0xf; - if (awacs_revision == 3) { - mdelay(100); - awacs_write(0x6000); - mdelay(2); - awacs_write(awacs_reg[1] + MASK_ADDR1); - awacs_enable_amp(100 * 0x101); - } - } - if (awacs_revision >= AWACS_BURGUNDY) - awacs_burgundy_init(); + /* Reset dbdma channels */ + out_le32(&awacs_txdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16); + while (in_le32(&awacs_txdma->status) & RUN) + udelay(1); + out_le32(&awacs_rxdma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16); + while (in_le32(&awacs_rxdma->status) & RUN) + udelay(1); + + /* Initialize beep stuff */ + /* need to ask for two buffers to cater for potential pull-up + by DBDMA_ALIGN + */ + beep_dbdma_cmd_space = kmalloc((1 + 1) * sizeof(struct dbdma_cmd), + GFP_KERNEL); + if (beep_dbdma_cmd_space == NULL) { + printk(KERN_ERR "dmasound_pmac: no beep dbdma cmd space\n") ; + return -ENOMEM; + } + beep_dbdma_cmd = (volatile struct dbdma_cmd *) + DBDMA_ALIGN(beep_dbdma_cmd_space); + beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL); + if (beep_buf == NULL) { + printk(KERN_ERR "dmasound_pmac: no memory for beep buffer\n"); + kfree(beep_dbdma_cmd_space); + return -ENOMEM; + } + /* OK, we should be safe to claim the mksound vector now */ + orig_mksound = kd_mksound; + kd_mksound = awacs_mksound; - /* Initialize beep stuff */ - beep_dbdma_cmd = awacs_tx_cmds + (write_sq.numBufs + 1); - orig_mksound = kd_mksound; - kd_mksound = awacs_mksound; - beep_buf = (short *) kmalloc(BEEP_BUFLEN * 4, GFP_KERNEL); - if (beep_buf == NULL) - printk(KERN_WARNING "dmasound: no memory for " - "beep buffer\n"); #ifdef CONFIG_PMAC_PBOOK - pmu_register_sleep_notifier(&awacs_sleep_notifier); + pmu_register_sleep_notifier(&awacs_sleep_notifier); #endif /* CONFIG_PMAC_PBOOK */ - /* Powerbooks have odd ways of enabling inputs such as - an expansion-bay CD or sound from an internal modem - or a PC-card modem. */ - if (machine_is_compatible("AAPL,3400/2400") - || machine_is_compatible("AAPL,3500")) { - is_pbook_3400 = 1; - /* - * Enable CD and PC-card sound inputs. - * This is done by reading from address - * f301a000, + 0x10 to enable the expansion-bay - * CD sound input, + 0x80 to enable the PC-card - * sound input. The 0x100 enables the SCSI bus - * terminator power. - */ - latch_base = (unsigned char *) ioremap - (0xf301a000, 0x1000); - in_8(latch_base + 0x190); - } else if (machine_is_compatible("PowerBook1,1") - || machine_is_compatible("AAPL,PowerBook1998")) { - struct device_node* mio; - macio_base = 0; - is_pbook_G3 = 1; - for (mio = np->parent; mio; mio = mio->parent) { - if (strcmp(mio->name, "mac-io") == 0 - && mio->n_addrs > 0) { - macio_base = (unsigned char *) ioremap - (mio->addrs[0].address, 0x40); - break; - } + /* Powerbooks have odd ways of enabling inputs such as + an expansion-bay CD or sound from an internal modem + or a PC-card modem. */ + if (machine_is_compatible("AAPL,3400/2400") + || machine_is_compatible("AAPL,3500")) { + is_pbook_3400 = 1; + /* + * Enable CD and PC-card sound inputs. + * This is done by reading from address + * f301a000, + 0x10 to enable the expansion-bay + * CD sound input, + 0x80 to enable the PC-card + * sound input. The 0x100 enables the SCSI bus + * terminator power. + */ + latch_base = (unsigned char *) ioremap (0xf301a000, 0x1000); + in_8(latch_base + 0x190); + + } else if (machine_is_compatible("PowerBook1,1") + || machine_is_compatible("AAPL,PowerBook1998")) { + struct device_node* mio; + macio_base = 0; + is_pbook_G3 = 1; + for (mio = np->parent; mio; mio = mio->parent) { + if (strcmp(mio->name, "mac-io") == 0 + && mio->n_addrs > 0) { + macio_base = (unsigned char *) ioremap + (mio->addrs[0].address, 0x40); + break; } - /* - * Enable CD sound input. - * The relevant bits for writing to this byte are 0x8f. - * I haven't found out what the 0x80 bit does. - * For the 0xf bits, writing 3 or 7 enables the CD - * input, any other value disables it. Values - * 1, 3, 5, 7 enable the microphone. Values 0, 2, - * 4, 6, 8 - f enable the input from the modem. - */ - if (macio_base) - out_8(macio_base + 0x37, 3); - } - sprintf(awacs_name, "PowerMac (AWACS rev %d) ", - awacs_revision); - return dmasound_init(); + } + /* + * Enable CD sound input. + * The relevant bits for writing to this byte are 0x8f. + * I haven't found out what the 0x80 bit does. + * For the 0xf bits, writing 3 or 7 enables the CD + * input, any other value disables it. Values + * 1, 3, 5, 7 enable the microphone. Values 0, 2, + * 4, 6, 8 - f enable the input from the modem. + * -- paulus. + */ + if (macio_base) + out_8(macio_base + 0x37, 3); } - return -ENODEV; + sprintf(awacs_name, "PowerMac (AWACS rev %d) ", awacs_revision); + return dmasound_init(); } static void __exit dmasound_awacs_cleanup(void) diff -Nru a/drivers/sound/dmasound/dmasound_core.c b/drivers/sound/dmasound/dmasound_core.c --- a/drivers/sound/dmasound/dmasound_core.c Sat Jun 16 06:00:26 2001 +++ b/drivers/sound/dmasound/dmasound_core.c Sat Jun 16 06:00:26 2001 @@ -103,6 +103,13 @@ * 2000/3/25 Geert Uytterhoeven: * - Integration of dmasound_q40 * - Small clean ups + * + * 2001/01/26 [rev 1.0] Iain Sandoe + * - make /dev/sndstat show revision & edition information. + * - since dmasound.mach.sq_setup() can fail on pmac its type + * has been changed to int and the returns are checked. + * [1.1] - stop missing translations from being called. + * */ @@ -117,7 +124,6 @@ #include "dmasound.h" - /* * Declarations */ @@ -480,7 +486,12 @@ default: return 0; } - return ct_func(userPtr, userCount, frame, frameUsed, frameLeft); + /* if the user has requested a non-existent translation don't try + to call it but just return 0 bytes moved + */ + if (ct_func) + return ct_func(userPtr, userCount, frame, frameUsed, frameLeft); + return 0; } @@ -606,10 +617,10 @@ } } -static void sq_setup(struct sound_queue *sq, int max_count, int max_active, - int block_size) +static int sq_setup(struct sound_queue *sq, int max_count, int max_active, + int block_size) { - void (*setup_func)(void); + int (*setup_func)(void); sq->max_count = max_count; sq->max_active = max_active; @@ -627,7 +638,8 @@ setup_func = dmasound.mach.read_sq_setup; } if (setup_func) - setup_func(); + return setup_func(); + return 0; } static inline void sq_play(void) @@ -817,7 +829,8 @@ return rc; } - sq_setup(sq, numbufs, numbufs, bufsize); + if ((rc = sq_setup(sq, numbufs, numbufs, bufsize))) + return rc; sq->open_mode = file->f_mode; } return rc; @@ -936,7 +949,7 @@ static int sq_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg) { - int val; + int val, result; u_long fmt; int data; int size, nbufs; @@ -1013,7 +1026,9 @@ size = write_sq.bufSize; } else size = write_sq.bufSize; - sq_setup(&write_sq, write_sq.numBufs, nbufs, size); + result = sq_setup(&write_sq, write_sq.numBufs, nbufs, size); + if (result) + return result; return IOCTL_OUT(arg,write_sq.bufSize | write_sq.numBufs << 16); case SNDCTL_DSP_GETOSPACE: info.fragments = write_sq.max_active - write_sq.count; @@ -1081,9 +1096,11 @@ * /dev/sndstat */ +#define STAT_BUFF_LEN 512 + static struct { int busy; - char buf[512]; /* state.buf should not overflow! */ + char buf[STAT_BUFF_LEN]; /* state.buf should not overflow! */ int len, ptr; } state; @@ -1099,7 +1116,13 @@ state.ptr = 0; state.busy = 1; - len += sprintf(buffer+len, "%sDMA sound driver:\n", dmasound.mach.name); + len += sprintf(buffer+len, "%sDMA sound driver rev %03d :\n", + dmasound.mach.name, (DMASOUND_CORE_REVISION<<4) + + ((dmasound.mach.version>>8) & 0x0f)); + len += sprintf(buffer+len, + "Core driver edition %02d.%02d : %s driver edition %02d.%02d\n", + DMASOUND_CORE_REVISION, DMASOUND_CORE_EDITION, dmasound.mach.name2, + (dmasound.mach.version >> 8), (dmasound.mach.version & 0xff)) ; len += sprintf(buffer+len, "\tsound.format = 0x%x", dmasound.soft.format); @@ -1145,6 +1168,9 @@ write_sq.count, write_sq.rear_size); len += sprintf(buffer+len, "\tsq.active = %d sq.syncing = %d\n", write_sq.active, write_sq.syncing); + if (len >= STAT_BUFF_LEN) + printk(KERN_ERR "dmasound_core: stat buffer overflowed!\n") +; state.len = len; return 0; } @@ -1237,6 +1263,7 @@ if (irq_installed) { sound_silence(); dmasound.mach.irqcleanup(); + irq_installed = 0; } write_sq_release_buffers(); diff -Nru a/drivers/video/aty128.h b/drivers/video/aty128.h --- a/drivers/video/aty128.h Sat Jun 16 06:00:18 2001 +++ b/drivers/video/aty128.h Sat Jun 16 06:00:18 2001 @@ -267,7 +267,6 @@ #define DAC_MASK 0xFF000000 #define DAC_BLANKING 0x00000004 #define DAC_RANGE_CNTL 0x00000003 -#define DAC_RANGE_CNTL 0x00000003 #define DAC_PALETTE_ACCESS_CNTL 0x00000020 #define DAC_PDWN 0x00008000 diff -Nru a/drivers/video/aty128fb.c b/drivers/video/aty128fb.c --- a/drivers/video/aty128fb.c Sat Jun 16 06:00:22 2001 +++ b/drivers/video/aty128fb.c Sat Jun 16 06:00:22 2001 @@ -67,6 +67,9 @@ #ifdef CONFIG_FB_COMPAT_XPMAC #include #endif +#ifdef CONFIG_BOOTX_TEXT +#include +#endif /* CONFIG_BOOTX_TEXT */ #include