# 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.5-pre3 -> 1.174 # arch/ppc/kernel/ppc4xx_pic.h 1.1 -> 1.5 # include/asm-ppc/system.h 1.1.1.2 -> 1.10 # arch/ppc/kernel/head_8xx.S 1.1.1.2 -> 1.11 # drivers/char/tty_io.c 1.1.1.4 -> 1.6 # arch/ppc/lib/locks.c 1.1.1.1 -> 1.8 # include/asm-ppc/ptrace.h 1.1 -> 1.5 # include/asm-ppc/unaligned.h 1.1 -> 1.5 # arch/ppc/chrpboot/main.c 1.1 -> 1.6 arch/ppc/boot/chrp/main.c (moved) # arch/ppc/math-emu/fsqrt.c 1.1 -> 1.6 # arch/ppc/math-emu/mtfsf.c 1.1 -> 1.6 # CREDITS 1.1.1.12 -> 1.16 # arch/sparc64/kernel/ioctl32.c 1.4.1.4 -> 1.9 # arch/ppc/kernel/pci.h 1.1.1.1 -> 1.7 # include/asm-ppc/traps.h 1.1 -> 1.5 # arch/ppc/coffboot/zlib.c 1.1 -> 1.6 arch/ppc/boot/lib/zlib.c (moved) # arch/ppc/kernel/chrp_pci.c 1.1.1.3 -> 1.16 # BitKeeper/etc/COPYING 1.1 -> (deleted) # include/asm-ppc/mc146818rtc.h 1.1 -> 1.5 # arch/ppc/kernel/i8259.h 1.1 -> 1.5 # arch/ppc/mbxboot/head_8260.S 1.1 -> 1.6 arch/ppc/boot/mbx/head_8260.S (moved) # arch/ppc/math-emu/fneg.c 1.1 -> 1.6 # drivers/ide/ide-features.c 1.1.1.1 -> 1.3 # drivers/video/controlfb.c 1.1.1.1 -> 1.3 # arch/ppc/kernel/sleep.S 1.1.1.1 -> 1.8 # arch/ppc/configs/mbx_defconfig 1.1.1.2 -> 1.7 # include/asm-ppc/dbdma.h 1.1 -> 1.5 # include/asm-ppc/bootinfo.h 1.1 -> 1.5 # include/asm-ppc/m48t35.h 1.1 -> 1.5 # arch/ppc/kernel/pmac_pic.h 1.1 -> 1.5 # arch/ppc/chrpboot/addnote.c 1.1 -> 1.6 arch/ppc/boot/utils/addnote.c (moved) # arch/ppc/xmon/subr_prf.c 1.1 -> 1.5 # arch/ppc/math-emu/fnmsub.c 1.1 -> 1.6 # arch/ppc/configs/apus_defconfig 1.1.1.2 -> 1.7 # include/asm-ppc/param.h 1.1 -> 1.5 # arch/ppc/amiga/config.c 1.1 -> 1.6 # include/asm-ppc/poll.h 1.1 -> 1.5 # include/asm-ppc/msgbuf.h 1.1 -> 1.5 # arch/ppc/xmon/nonstdio.h 1.1 -> 1.5 # include/asm-ppc/pgtable.h 1.1.1.2 -> 1.11 # arch/ppc/kernel/time.c 1.1.1.3 -> 1.15 # arch/ppc/xmon/xmon.c 1.1.1.2 -> 1.10 # include/asm-ppc/est8260.h 1.1 -> 1.5 # drivers/macintosh/mac_hid.c 1.1 -> 1.4 # arch/ppc/treeboot/ld.script 1.1 -> 1.2 arch/ppc/boot/tree/ld.script (moved) # arch/ppc/treeboot/mkevimg 1.1.1.1 -> 1.7 arch/ppc/boot/utils/mkevimg (moved) # drivers/char/keyboard.c 1.1 -> 1.2 # arch/ppc/configs/bseip_defconfig 1.1.1.2 -> 1.7 # include/asm-ppc/ioctls.h 1.1.1.1 -> 1.7 # drivers/net/3c515.c 1.3.1.3 -> 1.7 # arch/ppc/8260_io/enet.c 1.1.1.2 -> 1.6 # drivers/sound/dmasound/dmasound_atari.c 1.1 -> 1.2 # include/asm-ppc/machdep.h 1.1.1.2 -> 1.11 # include/asm-ppc/mmu_context.h 1.1.1.2 -> 1.10 # arch/ppc/kernel/mk_defs.c 1.1 -> 1.6 # arch/ppc/boot/misc.c 1.1 -> 1.7 arch/ppc/boot/prep/misc.c (moved) # drivers/ide/ide-pmac.c 1.1.1.1 -> 1.4 # include/asm-ppc/ohare.h 1.1 -> 1.5 # include/asm-ppc/raven.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/indirect_pci.c 1.1.1.1 -> 1.7 # include/asm-ppc/8xx_immap.h 1.1 -> 1.5 # include/asm-ppc/vc_ioctl.h 1.1 -> 1.5 # include/asm-ppc/immap_8260.h 1.1 -> 1.5 # arch/ppc/mm/mem_pieces.c 1.1 -> 1.5 # arch/ppc/math-emu/fmsub.c 1.1 -> 1.6 # arch/ppc/mm/init.c 1.1.2.5 -> 1.29 # arch/ppc/kernel/proc_rtas.c 1.1 -> (deleted) # include/asm-ppc/scatterlist.h 1.1 -> 1.5 # include/asm-ppc/div64.h 1.1 -> 1.5 # arch/ppc/boot/head.S 1.1 -> 1.6 arch/ppc/boot/prep/head.S (moved) # arch/ppc/coffboot/zlib.h 1.1 -> 1.6 arch/ppc/boot/include/zlib.h (moved) # arch/ppc/amiga/Makefile 1.1 -> 1.4 # include/asm-ppc/pgalloc.h 1.1.1.3 -> 1.9 # include/asm-ppc/termbits.h 1.1 -> 1.5 # drivers/sgi/char/linux_logo.h 1.1 -> (deleted) # arch/ppc/coffboot/nonstdio.h 1.1 -> 1.6 arch/ppc/boot/include/nonstdio.h (moved) # arch/ppc/math-emu/mcrfs.c 1.1 -> 1.6 # include/asm-ppc/heathrow.h 1.1.1.1 -> 1.7 # include/asm-ppc/vga.h 1.1 -> 1.5 # include/asm-ppc/hdreg.h 1.1 -> 1.5 # arch/ppc/math-emu/mtfsb1.c 1.1 -> 1.6 # include/asm-ppc/irq.h 1.1.1.2 -> 1.9 # arch/ppc/kernel/oak_setup.c 1.1 -> 1.5 # arch/ppc/amiga/bootinfo.c 1.1 -> 1.5 # include/asm-ppc/elf.h 1.1.1.2 -> 1.10 # arch/ppc/config.in 1.1.2.4 -> 1.32 # include/linux/blkdev.h 1.2.1.2 -> 1.5 # include/asm-ppc/timex.h 1.1 -> 1.5 # arch/ppc/kernel/align.c 1.1 -> 1.5 # arch/ppc/math-emu/fnmadd.c 1.1 -> 1.6 # arch/ppc/defconfig 1.1.1.4 -> 1.10 # include/linux/proc_fs.h 1.1.1.3 -> 1.5 # arch/ppc/8xx_io/fec.c 1.1.1.4 -> 1.11 # arch/ppc/kernel/prep_nvram.c 1.1.1.2 -> 1.9 # arch/ppc/chrpboot/start.c 1.1 -> 1.5 arch/ppc/boot/chrp/start.c (moved) # include/asm-ppc/mbx.h 1.1.1.1 -> 1.8 # include/asm-ppc/resource.h 1.1 -> 1.5 # include/asm-ppc/mk48t59.h 1.1 -> 1.5 # include/asm-ppc/serial.h 1.1.1.2 -> 1.16 # include/asm-ppc/rwsem.h 1.1 -> (deleted) # fs/dcache.c 1.5.1.4 -> 1.10 # arch/ppc/mbxboot/embed_config.c 1.1 -> 1.7 arch/ppc/boot/mbx/embed_config.c (moved) # arch/ppc/mbxboot/rdimage.c 1.1 -> 1.5 arch/ppc/boot/mbx/rdimage.c (moved) # include/asm-ppc/init.h 1.1 -> 1.5 # include/asm-ppc/amigayle.h 1.1 -> 1.5 # drivers/net/ncr885e.c 1.1 -> (deleted) # arch/ppc/boot/mkprep.c 1.1 -> 1.6 arch/ppc/boot/utils/mkprep.c (moved) # arch/ppc/kernel/chrp_time.c 1.1.1.1 -> 1.7 # include/asm-ppc/posix_types.h 1.1 -> 1.5 # include/asm-ppc/amigappc.h 1.1 -> 1.5 # arch/ppc/math-emu/fcmpo.c 1.1 -> 1.6 # arch/ppc/kernel/pmac_setup.c 1.1.1.5 -> 1.21 # include/asm-ppc/amipcmcia.h 1.1 -> 1.5 # arch/ppc/kernel/pmac_pic.c 1.1.1.3 -> 1.14 # arch/ppc/kernel/smp.c 1.1.2.3 -> 1.23 # arch/ppc/8xx_io/uart.c 1.2.1.2 -> 1.10 # include/linux/dcache.h 1.3.1.2 -> 1.6 # drivers/input/keybdev.c 1.1.1.4 -> 1.10 # arch/ppc/math-emu/Makefile 1.1 -> 1.3 # arch/ppc/xmon/start.c 1.1.1.2 -> 1.11 # include/asm-ppc/backlight.h 1.1 -> 1.5 # drivers/block/swim3.c 1.1 -> 1.3 # arch/ppc/boot/ns16550.c 1.1 -> 1.7 arch/ppc/boot/common/ns16550.c (moved) # drivers/ide/ide-pnp.c 1.1.1.1 -> 1.10 # fs/smbfs/cache.c 1.3.1.2 -> 1.6 # include/asm-ppc/linux_logo.h 1.1.1.1 -> 1.7 # arch/ppc/xmon/ppc-dis.c 1.1 -> 1.5 # arch/ppc/math-emu/stfiwx.c 1.1 -> 1.6 # include/asm-ppc/uninorth.h 1.1.1.1 -> 1.7 # arch/ppc/configs/gemini_defconfig 1.1 -> (deleted) # drivers/char/serial.c 1.1.1.5 -> 1.8 # arch/ppc/coffboot/mknote.c 1.1 -> (deleted) # include/asm-ppc/pci-bridge.h 1.1.1.2 -> 1.10 # include/asm-ppc/mpc8xx.h 1.1.1.2 -> 1.10 # include/asm-ppc/gg2.h 1.1 -> 1.5 # arch/ppc/kernel/apus_setup.c 1.1.1.2 -> 1.11 # arch/ppc/kernel/ppc8xx_pic.c 1.1.1.2 -> 1.10 # drivers/macintosh/via-pmu.c 1.1.1.2 -> 1.4 # drivers/video/aty128.h 1.1 -> 1.2 # arch/ppc/amiga/amiga_ksyms.c 1.1 -> 1.5 # arch/ppc/kernel/bitops.c 1.1.1.1 -> 1.7 # include/asm-ppc/prep_nvram.h 1.1.1.1 -> 1.7 # include/asm-ppc/page.h 1.1 -> 1.6 # include/asm-ppc/sembuf.h 1.1 -> 1.5 # arch/ppc/amiga/chipram.c 1.1 -> 1.6 # BitKeeper/etc/ignore 1.1 -> 1.7 # drivers/net/Config.in 1.1.1.10 -> 1.17 # arch/ppc/configs/SM850_defconfig 1.1.1.1 -> (deleted) # arch/ppc/kernel/i8259.c 1.1.1.1 -> 1.7 # arch/ppc/chrpboot/crt0.S 1.1 -> 1.10 arch/ppc/boot/common/crt0.S (moved) # Documentation/sysrq.txt 1.2 -> 1.3 # drivers/ide/Config.in 1.1.1.1 -> 1.3 # drivers/i2c/Config.in 1.1 -> 1.2 # arch/ppc/treeboot/main.c 1.1 -> 1.6 arch/ppc/boot/tree/main.c (moved) # drivers/scsi/aic7xxx/aicasm/Makefile 1.1.1.2 -> 1.5 # arch/ppc/mm/4xx_tlb.h 1.1 -> 1.5 # include/asm-ppc/feature.h 1.1.1.2 -> 1.9 # arch/ppc/math-emu/types.c 1.1 -> 1.5 # arch/ppc/boot/offset 1.1 -> 1.2 arch/ppc/boot/utils/offset (moved) # arch/ppc/kernel/error_log.h 1.1 -> (deleted) # include/asm-ppc/setup.h 1.1 -> 1.5 # arch/ppc/math-emu/fadds.c 1.1 -> 1.6 # arch/ppc/configs/rpxcllf_defconfig 1.1.1.2 -> 1.7 # include/video/macmodes.h 1.1 -> 1.2 # arch/ppc/kernel/pmac_backlight.c 1.1 -> 1.5 # arch/ppc/coffboot/misc.S 1.1 -> 1.5 arch/ppc/boot/pmac/misc.S (moved) # arch/ppc/coffboot/coffcrt0.S 1.1 -> (deleted) # arch/ppc/kernel/gemini_pci.c 1.1 -> (deleted) # arch/ppc/kernel/open_pic.h 1.1.1.2 -> 1.9 # include/asm-ppc/ipcbuf.h 1.1 -> 1.5 # include/asm-ppc/mpc8260.h 1.1 -> 1.6 # arch/ppc/mbxboot/size 1.1 -> (deleted) # arch/ppc/configs/common_defconfig 1.1.1.3 -> 1.8 # include/asm-ppc/siginfo.h 1.1 -> 1.5 # arch/ppc/amiga/time.c 1.1 -> 1.5 # drivers/net/bmac.c 1.1.1.2 -> 1.10 # arch/ppc/kernel/setup.c 1.1.2.4 -> 1.29 # drivers/net/ne2k-pci.c 1.1.1.3 -> 1.6 # drivers/video/chipsfb.c 1.1.1.1 -> 1.5 # MAINTAINERS 1.1.1.11 -> 1.15 # arch/ppc/coffboot/coffmain.c 1.1.1.1 -> 1.8 arch/ppc/boot/pmac/coffmain.c (moved) # include/asm-ppc/shmparam.h 1.1 -> 1.5 # arch/ppc/8xx_io/Makefile 1.1 -> 1.3 # arch/ppc/mbxboot/gzimage.c 1.1 -> 1.5 arch/ppc/boot/mbx/gzimage.c (moved) # arch/ppc/math-emu/fcmpu.c 1.1 -> 1.6 # arch/ppc/math-emu/fsubs.c 1.1 -> 1.6 # include/asm-ppc/atomic.h 1.1.1.1 -> 1.8 # include/asm-ppc/pci.h 1.1.1.3 -> 1.11 # include/asm-ppc/shmbuf.h 1.1 -> 1.5 # arch/ppc/kernel/oak_setup.h 1.1 -> 1.5 # arch/ppc/kernel/idle.c 1.1.1.3 -> 1.11 # arch/ppc/configs/rpxlite_defconfig 1.1.1.2 -> 1.7 # include/asm-ppc/smplock.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/walnut_setup.c 1.1 -> 1.5 # drivers/video/macmodes.c 1.2 -> 1.3 # include/asm-ppc/unistd.h 1.1.1.1 -> 1.7 # drivers/macintosh/mac_keyb.c 1.1 -> 1.2 # include/asm-ppc/processor.h 1.1.2.3 -> 1.26 # drivers/md/md.c 1.5.1.3 -> 1.9 # fs/nfsd/nfsproc.c 1.2.1.1 -> 1.4 # arch/ppc/kernel/signal.c 1.1.1.1 -> 1.7 # arch/ppc/kernel/pci-dma.c 1.1 -> 1.5 # arch/ppc/math-emu/fmuls.c 1.1 -> 1.6 # include/asm-ppc/ppc4xx.h 1.1 -> (deleted) # arch/ppc/8xx_io/commproc.c 1.1.1.1 -> 1.7 # scripts/mkdep.c 1.1.1.1 -> 1.4 # include/asm-ppc/mediabay.h 1.1 -> 1.5 # include/asm-ppc/gemini_serial.h 1.1 -> (deleted) # arch/ppc/configs/IVMS8_defconfig 1.1.1.1 -> (deleted) # include/asm-ppc/nvram.h 1.1 -> 1.5 # drivers/net/ncr885_debug.h 1.1 -> (deleted) # arch/ppc/math-emu/frsp.c 1.1 -> 1.6 # include/asm-ppc/checksum.h 1.1.1.1 -> 1.8 # include/asm-ppc/termios.h 1.1.1.2 -> 1.8 # arch/ppc/xmon/ppc-opc.c 1.1 -> 1.5 # arch/ppc/math-emu/fmul.c 1.1 -> 1.6 # arch/ppc/math-emu/lfd.c 1.1 -> 1.6 # arch/i386/kernel/pci-pc.c 1.3.1.4 -> 1.8 # include/asm-ppc/socket.h 1.2 -> 1.6 # include/asm-ppc/io.h 1.1.1.1 -> 1.7 # include/asm-ppc/smp.h 1.1.1.2 -> 1.9 # arch/ppc/kernel/process.c 1.1.1.3 -> 1.15 # Documentation/powerpc/00-INDEX 1.1 -> 1.3 # include/asm-ppc/ipc.h 1.1 -> 1.5 # arch/ppc/math-emu/op-common.h 1.1 -> 1.5 # include/asm-ppc/ide.h 1.1.1.2 -> 1.10 # arch/ppc/lib/Makefile 1.1.1.2 -> 1.7 # Documentation/powerpc/ppc_htab.txt 1.1.1.1 -> 1.3 # arch/ppc/treeboot/misc.S 1.1 -> 1.6 arch/ppc/boot/tree/misc.S (moved) # arch/ppc/amiga/cia.c 1.1 -> 1.6 # arch/ppc/kernel/open_pic_defs.h 1.1.1.1 -> (deleted) # include/asm-ppc/bootx.h 1.1 -> 1.5 # arch/ppc/boot/of1275.h 1.1 -> 1.5 arch/ppc/boot/prep/of1275.h (moved) # include/asm-ppc/amigahw.h 1.1 -> 1.5 # arch/ppc/chrpboot/no_initrd.c 1.1 -> 1.6 arch/ppc/boot/common/no_initrd.c (moved) # arch/ppc/math-emu/mtfsfi.c 1.1 -> 1.6 # include/asm-ppc/walnut.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/semaphore.c 1.1.1.2 -> 1.11 # arch/ppc/xmon/start_8xx.c 1.1.1.1 -> 1.7 # Documentation/Configure.help 1.1.2.9 -> 1.29 # fs/nfsd/vfs.c 1.2.1.1 -> 1.4 # arch/ppc/amiga/amiints.c 1.2 -> 1.7 # arch/ppc/mbxboot/misc.c 1.1 -> 1.7 arch/ppc/boot/mbx/misc.c (moved) # include/asm-ppc/time.h 1.1.1.2 -> 1.10 # arch/ppc/kernel/gemini_prom.S 1.1 -> (deleted) # fs/proc/root.c 1.1.1.1 -> 1.3 # arch/ppc/mbxboot/offset 1.1 -> (deleted) # drivers/net/gmac.c 1.1.1.2 -> 1.12 # include/asm-ppc/mmu.h 1.1.1.1 -> 1.8 # arch/ppc/chrpboot/piggyback.c 1.1 -> 1.6 arch/ppc/boot/utils/piggyback.c (moved) # include/asm-ppc/fads.h 1.1.1.1 -> 1.8 # arch/ppc/kernel/local_irq.h 1.1.1.1 -> 1.7 # arch/ppc/treeboot/Makefile 1.1 -> 1.5 arch/ppc/boot/tree/Makefile (moved) # arch/ppc/amiga/pcmcia.c 1.1 -> 1.5 # Makefile 1.19.1.17 -> 1.39 # arch/ppc/kernel/irq.c 1.1.1.4 -> 1.22 # arch/ppc/kernel/prep_time.c 1.1.1.1 -> 1.7 # arch/ppc/8xx_io/enet.c 1.1.1.3 -> 1.10 # include/asm-ppc/uaccess.h 1.1 -> 1.5 # arch/ppc/kernel/Makefile 1.1.2.3 -> 1.25 # arch/ppc/mm/fault.c 1.1.1.3 -> 1.11 # include/asm-ppc/kgdb.h 1.1 -> 1.5 # arch/ppc/8260_io/commproc.c 1.1 -> 1.5 # arch/ppc/mbxboot/head.S 1.1 -> 1.7 arch/ppc/boot/mbx/head.S (moved) # arch/ppc/math-emu/mffs.c 1.1 -> 1.6 # include/asm-ppc/semaphore.h 1.1.1.4 -> 1.15 # drivers/net/Makefile 1.1.1.7 -> 1.13 # arch/ppc/kernel/chrp_setup.c 1.1.1.6 -> 1.17 # arch/ppc/kernel/misc.S 1.1.1.2 -> 1.17 # arch/ppc/8260_io/Makefile 1.1 -> 1.3 # arch/ppc/math-emu/fnmadds.c 1.1 -> 1.6 # arch/ppc/kernel/entry.S 1.1.1.2 -> 1.11 # arch/ppc/kernel/prep_setup.c 1.1.1.5 -> 1.19 # drivers/net/3c509.c 1.3.1.3 -> 1.7 # drivers/sound/dmasound/dmasound.h 1.1 -> 1.2 # arch/ppc/kernel/xics.h 1.1 -> 1.5 # arch/ppc/boot/of1275.c 1.1 -> 1.5 arch/ppc/boot/prep/of1275.c (moved) # arch/ppc/mbxboot/Makefile 1.1 -> 1.5 arch/ppc/boot/mbx/Makefile (moved) # arch/ppc/math-emu/math.c 1.1 -> 1.6 # drivers/video/aty128fb.c 1.1.1.1 -> 1.6 # include/asm-ppc/stat.h 1.1 -> 1.5 # arch/ppc/mbxboot/pci.c 1.1 -> 1.5 arch/ppc/boot/mbx/pci.c (moved) # arch/ppc/math-emu/fdiv.c 1.1 -> 1.6 # arch/ppc/math-emu/fres.c 1.1 -> 1.6 # arch/ppc/xmon/ansidecl.h 1.1 -> 1.5 # arch/ppc/math-emu/op-1.h 1.1 -> 1.5 # arch/ppc/math-emu/fdivs.c 1.1 -> 1.6 # include/asm-ppc/keylargo.h 1.1.1.2 -> 1.9 # include/asm-ppc/prom.h 1.1.1.2 -> 1.10 # arch/ppc/math-emu/fmadd.c 1.1 -> 1.6 # include/asm-ppc/spd8xx.h 1.1 -> (deleted) # drivers/video/offb.c 1.1.1.1 -> 1.4 # arch/ppc/boot/vreset.c 1.1.1.1 -> 1.8 arch/ppc/boot/prep/vreset.c (moved) # arch/ppc/coffboot/crt0.S 1.1 -> (deleted) # arch/ppc/kernel/ppc_ksyms.c 1.1.1.4 -> 1.30 # include/asm-ppc/floppy.h 1.1 -> 1.5 # arch/ppc/boot/kbd.c 1.1 -> 1.6 arch/ppc/boot/prep/kbd.c (moved) # drivers/video/clgenfb.c 1.1.1.2 -> 1.5 # include/asm-ppc/fcntl.h 1.1 -> 1.5 # arch/ppc/coffboot/rs6000.h 1.1 -> 1.6 arch/ppc/boot/include/rs6000.h (moved) # arch/ppc/xmon/setjmp.c 1.1 -> 1.5 # include/asm-ppc/rpxhiox.h 1.1 -> (deleted) # drivers/video/atyfb.c 1.1.1.3 -> 1.5 # arch/ppc/mbxboot/m8260_tty.c 1.1 -> 1.7 arch/ppc/boot/mbx/m8260_tty.c (moved) # arch/ppc/kernel/open_pic.c 1.1.2.3 -> 1.21 # arch/ppc/kernel/error_log.c 1.1 -> (deleted) # arch/ppc/math-emu/fmsubs.c 1.1 -> 1.6 # arch/ppc/math-emu/soft-fp.h 1.1 -> 1.5 # arch/ppc/8xx_io/commproc.h 1.2.1.1 -> 1.8 # arch/ppc/treeboot/elf.pl 1.1 -> 1.4 arch/ppc/boot/utils/elf.pl (moved) # arch/ppc/math-emu/fctiw.c 1.1 -> 1.6 # include/asm-ppc/amigaints.h 1.1 -> 1.5 # include/asm-ppc/md.h 1.1 -> 1.5 # arch/ppc/kernel/find_name.c 1.1 -> 1.5 # arch/ppc/math-emu/mtfsb0.c 1.1 -> 1.6 # include/asm-ppc/bitops.h 1.1.1.1 -> 1.7 # arch/ppc/configs/TQM850L_defconfig 1.1.1.1 -> (deleted) # include/asm-ppc/sockios.h 1.1 -> 1.5 # arch/ppc/lib/string.S 1.1 -> 1.5 # arch/ppc/coffboot/ld.script 1.1 -> 1.2 arch/ppc/boot/pmac/ld.script (moved) # include/asm-ppc/hw_irq.h 1.1.1.2 -> 1.10 # arch/ppc/configs/TQM860L_defconfig 1.1.1.1 -> (deleted) # drivers/scsi/sym53c8xx_defs.h 1.2 -> 1.3 # include/asm-ppc/signal.h 1.1 -> 1.5 # arch/ppc/lib/strcase.c 1.1 -> 1.5 # arch/ppc/kernel/ppc8xx_pic.h 1.1.1.1 -> 1.7 # arch/ppc/coffboot/chrpmain.c 1.1.1.1 -> 1.8 arch/ppc/boot/pmac/chrpmain.c (moved) # drivers/usb/hid.c 1.1.1.2 -> 1.4 # arch/ppc/lib/checksum.S 1.1 -> 1.5 # arch/ppc/coffboot/hack-coff.c 1.1 -> 1.7 arch/ppc/boot/utils/hack-coff.c (moved) # arch/ppc/math-emu/sfp-machine.h 1.1 -> 1.5 # include/asm-ppc/board.h 1.1 -> 1.5 # arch/ppc/kernel/ptrace.c 1.1 -> 1.6 # arch/ppc/math-emu/fsqrts.c 1.1 -> 1.6 # arch/ppc/kernel/head.S 1.1.2.3 -> 1.18 # arch/ppc/configs/oak_defconfig 1.1.1.2 -> 1.6 # include/asm-ppc/hydra.h 1.1 -> 1.5 # arch/ppc/mbxboot/m8xx_tty.c 1.1 -> 1.7 arch/ppc/boot/mbx/m8xx_tty.c (moved) # fs/binfmt_elf.c 1.4 -> 1.6 # arch/ppc/kernel/pmac_time.c 1.1.1.1 -> 1.8 # arch/ppc/math-emu/fmadds.c 1.1 -> 1.6 # arch/ppc/kernel/hashtable.S 1.1.1.2 -> (deleted) # arch/ppc/kernel/prom.c 1.1.2.3 -> 1.18 # arch/ppc/math-emu/fnabs.c 1.1 -> 1.6 # arch/ppc/8260_io/uart.c 1.2 -> 1.6 # drivers/pci/pci.c 1.9 -> 1.10 # drivers/macintosh/macserial.c 1.1.1.1 -> 1.4 # arch/ppc/kernel/ppc4xx_pic.c 1.1 -> 1.5 # arch/ppc/coffboot/dummy.c 1.1 -> 1.5 arch/ppc/boot/pmac/dummy.c (moved) # include/asm-ppc/statfs.h 1.1 -> 1.5 # arch/ppc/chrpboot/mknote.c 1.1 -> 1.6 arch/ppc/boot/utils/mknote.c (moved) # arch/ppc/math-emu/fsub.c 1.1 -> 1.6 # include/asm-ppc/ppc4xx_serial.h 1.1 -> (deleted) # arch/ppc/math-emu/single.h 1.1 -> 1.5 # drivers/net/mace.c 1.1.1.4 -> 1.8 # drivers/net/gmac.h 1.1.1.1 -> 1.6 # drivers/scsi/sym53c8xx.c 1.1.1.5 -> 1.9 # drivers/pci/pci.ids 1.2.1.1 -> 1.4 # Documentation/powerpc/zImage_layout.txt 1.1.1.1 -> 1.4 # arch/ppc/math-emu/fmr.c 1.1 -> 1.6 # arch/ppc/boot/sisize 1.1 -> (deleted) # arch/ppc/chrpboot/Makefile 1.1.1.1 -> 1.8 arch/ppc/boot/chrp/Makefile (moved) # arch/ppc/kernel/checks.c 1.2 -> 1.6 # include/linux/pci_ids.h 1.1.1.5 -> 1.11 # arch/ppc/kernel/residual.c 1.2 -> 1.7 # arch/ppc/coffboot/Makefile 1.1.1.1 -> 1.7 arch/ppc/boot/pmac/Makefile (moved) # arch/ppc/amiga/amisound.c 1.1 -> 1.5 # arch/ppc/math-emu/stfs.c 1.1 -> 1.6 # BitKeeper/etc/logging_ok 1.1.1.7 -> 1.28 # net/sunrpc/svcsock.c 1.2.1.3 -> 1.6 # include/asm-ppc/tqm8xx.h 1.1.1.1 -> (deleted) # include/asm-ppc/bugs.h 1.1 -> 1.5 # arch/ppc/treeboot/irSect.h 1.1 -> 1.5 arch/ppc/boot/tree/irSect.h (moved) # include/asm-ppc/dma.h 1.1.2.1 -> 1.8 # include/asm-ppc/softirq.h 1.1 -> 1.5 # arch/ppc/coffboot/no_initrd.c 1.1 -> (deleted) # include/asm-ppc/gemini.h 1.1 -> (deleted) # drivers/Makefile 1.1.1.1 -> 1.3 # arch/ppc/kernel/m8260_setup.c 1.1.1.5 -> 1.16 # include/asm-ppc/kmap_types.h 1.1.1.1 -> 1.6 # include/asm-ppc/module.h 1.1 -> 1.5 # arch/ppc/kernel/gemini_setup.c 1.1 -> (deleted) # arch/ppc/configs/ibmchrp_defconfig 1.1.1.1 -> (deleted) # include/linux/rwsem.h 1.4.1.1 -> 1.6 # kernel/ptrace.c 1.1.1.1 -> 1.5 # arch/ppc/kernel/traps.c 1.1.1.3 -> 1.11 # Documentation/powerpc/sound.txt 1.1.1.1 -> 1.3 # include/asm-ppc/sigcontext.h 1.1 -> 1.5 # arch/ppc/configs/walnut_defconfig 1.1.1.2 -> 1.6 # arch/ppc/kernel/ppc-stub.c 1.1 -> 1.6 # arch/ppc/kernel/qspan_pci.c 1.1 -> 1.5 # drivers/block/ll_rw_blk.c 1.1.1.12 -> 1.15 # arch/ppc/8260_io/fcc_enet.c 1.1.1.3 -> 1.7 # include/asm-ppc/errno.h 1.1 -> 1.7 # include/asm-ppc/string.h 1.1 -> 1.5 # arch/ppc/math-emu/frsqrte.c 1.1 -> 1.6 # arch/ppc/xmon/Makefile 1.1 -> 1.3 # drivers/pci/Makefile 1.1.1.1 -> 1.4 # fs/ncpfs/dir.c 1.3.1.1 -> 1.5 # drivers/macintosh/Makefile 1.1.1.1 -> 1.4 # arch/ppc/math-emu/lfs.c 1.1 -> 1.6 # include/asm-ppc/bseip.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/feature.c 1.1.1.2 -> 1.10 # arch/ppc/kernel/ppc_asm.h 1.1.1.2 -> 1.10 # include/asm-ppc/parport.h 1.1 -> (deleted) # arch/ppc/kernel/ppc8260_pic.c 1.1 -> 1.5 # arch/ppc/math-emu/fsel.c 1.1 -> 1.6 # include/asm-ppc/segment.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/pmac_nvram.c 1.1 -> 1.5 # arch/ppc/xmon/ppc.h 1.1 -> 1.5 # arch/ppc/kernel/pci.c 1.1.1.4 -> 1.20 # include/asm-ppc/byteorder.h 1.1 -> 1.5 # include/asm-ppc/namei.h 1.1 -> 1.5 # include/asm-ppc/xor.h 1.1 -> 1.5 # drivers/i2c/Makefile 1.1 -> 1.2 # arch/ppc/treeboot/irSect.c 1.1 -> 1.5 arch/ppc/boot/tree/irSect.c (moved) # arch/ppc/math-emu/double.h 1.1 -> 1.5 # drivers/net/ncr885e.h 1.1 -> (deleted) # arch/ppc/math-emu/fnmsubs.c 1.1 -> 1.6 # arch/ppc/mm/mem_pieces.h 1.1 -> 1.5 # arch/ppc/boot/ns16550.h 1.1 -> (deleted) # arch/ppc/coffboot/string.S 1.1 -> 1.7 arch/ppc/boot/common/string.S (moved) # arch/ppc/treeboot/mkirimg 1.1 -> 1.5 arch/ppc/boot/utils/mkirimg (moved) # arch/ppc/configs/est8260_defconfig 1.1.1.2 -> 1.6 # drivers/sound/dmasound/dmasound_awacs.c 1.1.1.1 -> 1.6 # include/asm-ppc/hardirq.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/galaxy_pci.c 1.1.1.1 -> 1.7 # arch/ppc/coffboot/piggyback.c 1.1 -> (deleted) # arch/ppc/math-emu/stfd.c 1.1 -> 1.6 # arch/ppc/8xx_io/Config.in 1.1.1.2 -> 1.5 # arch/ppc/amiga/ints.c 1.1 -> 1.5 # arch/ppc/xmon/privinst.h 1.1 -> 1.5 # include/asm-ppc/cpm_8260.h 1.1.1.1 -> 1.7 # include/asm-ppc/mman.h 1.1.1.1 -> 1.7 # include/asm-ppc/keyboard.h 1.1 -> 1.5 # arch/ppc/mbxboot/qspan_pci.c 1.1 -> 1.5 arch/ppc/boot/mbx/qspan_pci.c (moved) # arch/ppc/mm/4xx_tlb.c 1.1 -> 1.5 # arch/ppc/boot/iso_font.h 1.1 -> 1.5 arch/ppc/boot/prep/iso_font.h (moved) # arch/ppc/Makefile 1.1.1.2 -> 1.15 # arch/ppc/boot/mksimage.c 1.1 -> (deleted) # drivers/net/pcnet32.c 1.1.1.6 -> 1.9 # arch/ppc/chrpboot/misc.S 1.1 -> 1.5 arch/ppc/boot/chrp/misc.S (moved) # include/asm-ppc/cache.h 1.1 -> 1.5 # drivers/sound/dmasound/Makefile 1.1 -> 1.2 # arch/ppc/math-emu/op-4.h 1.1 -> 1.5 # arch/ppc/boot/sioffset 1.1 -> (deleted) # drivers/scsi/sr.c 1.3.1.2 -> 1.6 # arch/ppc/kernel/ppc_htab.c 1.1.1.1 -> 1.10 # arch/ppc/math-emu/op-2.h 1.1 -> 1.5 # 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/ioctl.h 1.1 -> 1.5 # arch/ppc/mm/extable.c 1.1 -> 1.5 # arch/ppc/kernel/head_4xx.S 1.1 -> 1.5 # arch/ppc/treeboot/crt0.S 1.1 -> (deleted) # arch/ppc/kernel/prep_pci.c 1.1.1.4 -> 1.18 # include/asm-ppc/ivms8.h 1.1 -> (deleted) # include/asm-ppc/a.out.h 1.1 -> 1.5 # include/asm-ppc/pnp.h 1.1 -> 1.5 # arch/ppc/math-emu/fabs.c 1.1 -> 1.6 # include/asm-ppc/rpxlite.h 1.1.1.1 -> 1.8 # arch/ppc/kernel/ppc8260_pic.h 1.1.1.1 -> 1.7 # arch/ppc/configs/power3_defconfig 1.1.1.1 -> (deleted) # include/asm-ppc/residual.h 1.1 -> 1.5 # arch/ppc/boot/size 1.1 -> 1.2 arch/ppc/boot/utils/size (moved) # arch/ppc/math-emu/udivmodti4.c 1.1 -> 1.5 # arch/ppc/kernel/m8xx_setup.c 1.1.1.5 -> 1.16 # arch/ppc/kernel/pmac_pci.c 1.1.1.3 -> 1.14 # arch/ppc/configs/SPD823TS_defconfig 1.1.1.1 -> (deleted) # arch/ppc/configs/TQM823L_defconfig 1.1.1.1 -> (deleted) # include/asm-ppc/tlb.h 1.1 -> (deleted) # include/linux/highmem.h 1.2 -> 1.3 # include/asm-ppc/spinlock.h 1.1 -> 1.5 # arch/ppc/mm/Makefile 1.1 -> 1.4 # arch/ppc/math-emu/fadd.c 1.1 -> 1.6 # arch/ppc/math-emu/fctiwz.c 1.1 -> 1.6 # arch/ppc/boot/Makefile 1.1.2.2 -> 1.14 arch/ppc/boot/prep/Makefile (moved) # include/asm-ppc/current.h 1.1 -> 1.5 # arch/ppc/kernel/xics.c 1.1 -> 1.5 # arch/ppc/kernel/walnut_setup.h 1.1 -> 1.5 # arch/ppc/mbxboot/iic.c 1.1 -> 1.7 arch/ppc/boot/mbx/iic.c (moved) # arch/ppc/xmon/adb.c 1.1 -> 1.5 # include/linux/mmzone.h 1.1.1.1 -> 1.3 # include/asm-ppc/highmem.h 1.1.1.1 -> 1.8 # include/asm-ppc/user.h 1.1 -> 1.5 # include/asm-ppc/oak.h 1.1.1.1 -> 1.7 # arch/ppc/kernel/syscalls.c 1.2.1.1 -> 1.8 # arch/ppc/kernel/softemu8xx.c 1.1.1.2 -> 1.8 # drivers/i2c/i2c-core.c 1.2 -> 1.4 # include/asm-ppc/ucontext.h 1.1 -> 1.5 # include/asm-ppc/rpxclassic.h 1.1.1.1 -> 1.8 # arch/ppc/coffboot/start.c 1.1.1.1 -> 1.7 arch/ppc/boot/pmac/start.c (moved) # drivers/macintosh/macserial.h 1.1.1.1 -> 1.4 # include/asm-ppc/delay.h 1.1.1.1 -> 1.7 # include/asm-ppc/types.h 1.1 -> 1.5 # drivers/net/bmac.h 1.1 -> 1.3 # (new) -> 1.2 arch/ppc/boot/utils/sioffset # (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.1 arch/ppc/boot/images/Makefile # (new) -> 1.1 arch/ppc/configs/menf1_defconfig # (new) -> 1.2 arch/ppc/configs/gemini_defconfig # (new) -> 1.1 arch/ppc/boot/zx4500/head.S # (new) -> 1.1 arch/ppc/kernel/mvme5100_pci.c # (new) -> 1.1 arch/ppc/kernel/prpmc750_pci.c # (new) -> 1.1 arch/ppc/kernel/pcore_setup.c # (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/boot/utils/mkpmon.c # (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 arch/ppc/kernel/cpc700.h # (new) -> 1.3 arch/ppc/configs/SPD823TS_defconfig # (new) -> 1.1 arch/ppc/boot/menf1/Makefile # (new) -> 1.2 arch/ppc/boot/pp3/Makefile # (new) -> 1.1 arch/ppc/configs/k2_defconfig # (new) -> 1.1 arch/ppc/kernel/prpmc750_setup.c # (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.1 Documentation/powerpc/todc.txt # (new) -> 1.2 arch/ppc/boot/utils/sisize # (new) -> 1.5 BitKeeper/triggers/post-incoming # (new) -> 1.1 arch/ppc/configs/prpmc750_defconfig # (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.5 arch/ppc/kernel/gemini_prom.S # (new) -> 1.1 arch/ppc/configs/spruce_defconfig # (new) -> 1.1 include/asm-ppc/mvme5100_serial.h # (new) -> 1.3 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 arch/ppc/kernel/mpc10x_common.c # (new) -> 1.1 arch/ppc/boot/spruce/head.S # (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.2 arch/ppc/boot/common/misc-common.c # (new) -> 1.1 arch/ppc/kernel/temp.c # (new) -> 1.1 arch/ppc/kernel/m1543c.h # (new) -> 1.1 Documentation/powerpc/host_bridge.txt # (new) -> 1.1 arch/ppc/kernel/mpc10x.h # (new) -> 1.1 arch/ppc/kernel/zx4500_setup.c # (new) -> 1.1 arch/ppc/kernel/prpmc750.h # (new) -> 1.1 include/asm-ppc/zx4500_serial.h # (new) -> 1.1 arch/ppc/boot/menf1/head.S # (new) -> 1.1 arch/ppc/boot/pcore/Makefile # (new) -> 1.2 include/linux/i2c-algo-8xx.h # (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.3 arch/ppc/configs/SM850_defconfig # (new) -> 1.5 include/asm-ppc/gemini_serial.h # (new) -> 1.1 arch/ppc/kernel/spruce_pic.c # (new) -> 1.3 drivers/net/ncr885e.c # (new) -> 1.5 include/asm-ppc/parport.h # (new) -> 1.5 include/asm-ppc/gemini.h # (new) -> 1.1 arch/ppc/boot/sandpoint/head.S # (new) -> 1.1 arch/ppc/boot/lib/Makefile # (new) -> 1.5 arch/ppc/kernel/error_log.h # (new) -> 1.1 drivers/sgi/char/linux_logo.h # (new) -> 1.1 arch/ppc/boot/zx4500/Makefile # (new) -> 1.1 arch/ppc/boot/pcore/head.S # (new) -> 1.3 arch/ppc/configs/TQM823L_defconfig # (new) -> 1.1 arch/ppc/boot/spruce/misc.c # (new) -> 1.1 include/asm-ppc/spruce_serial.h # (new) -> 1.1 arch/ppc/configs/sandpoint_defconfig # (new) -> 1.3 arch/ppc/boot/utils/Makefile # (new) -> 1.1 arch/ppc/kernel/mvme5100.h # (new) -> 1.1 arch/ppc/kernel/menf1_setup.c # (new) -> 1.2 arch/ppc/configs/IVMS8_defconfig # (new) -> 1.5 arch/ppc/boot/utils/mksimage.c # (new) -> 1.3 drivers/net/ncr885_debug.h # (new) -> 1.2 arch/ppc/mm/hashtable.S # (new) -> 1.1 arch/ppc/kernel/ppc_stubs.c # (new) -> 1.6 arch/ppc/kernel/error_log.c # (new) -> 1.5 include/asm-ppc/ivms8.h # (new) -> 1.2 arch/ppc/boot/common/Makefile # (new) -> 1.10 arch/ppc/boot/Makefile # (new) -> 1.1 arch/ppc/kernel/mvme5100_setup.c # (new) -> 1.6 include/asm-ppc/rwsem.h # (new) -> 1.1 arch/ppc/configs/sbs8260_defconfig # (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.5 arch/ppc/kernel/gemini_pci.c # (new) -> 1.1 include/asm-ppc/sbs8260.h # (new) -> 1.1 arch/ppc/kernel/pplus.h # (new) -> 1.1 arch/ppc/kernel/k2.h # (new) -> 1.1 arch/ppc/kernel/k2_pci.c # (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 arch/ppc/kernel/todc.h # (new) -> 1.6 include/asm-ppc/tqm8xx.h # (new) -> 1.1 arch/ppc/kernel/pplus_common.c # (new) -> 1.3 include/asm-ppc/rpxhiox.h # (new) -> 1.1 arch/ppc/boot/pmon/head.S # (new) -> 1.2 arch/ppc/boot/common/misc-simple.c # (new) -> 1.8 arch/ppc/kernel/open_pic_defs.h # (new) -> 1.7 arch/ppc/kernel/gemini_setup.c # (new) -> 1.1 arch/ppc/kernel/sandpoint_setup.c # (new) -> 1.1 arch/ppc/kernel/zx4500_pci.c # (new) -> 1.4 drivers/i2c/i2c-algo-8xx.c # (new) -> 1.3 arch/ppc/configs/TQM850L_defconfig # (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.1 arch/ppc/kernel/pcore_pci.c # (new) -> 1.1 arch/ppc/kernel/k2_setup.c # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 01/05/16 cort@f50.fsmlabs.com 1.2.2.18 # bk-work-patch-patch-2.4.5-pre3.2929.new # -------------------------------------------- # 01/05/16 cort@f50.fsmlabs.com 1.123.1.17 # Merge to v2.4.5-pre3 # -------------------------------------------- # 01/05/16 cort@f50.fsmlabs.com 1.123.1.18 # Paul isn't sure these changes are necessary and Donald wants # nothing to do with it, so revert the ne2k PPC changes. # -------------------------------------------- # 01/05/16 cort@f50.fsmlabs.com 1.158 # Merge f50.fsmlabs.com:/sys/linuxppc_2_4 # into f50.fsmlabs.com:/sys/linuxppc_2_4_devel # -------------------------------------------- # 01/05/16 cort@ftsoj.fsmlabs.com 1.123.1.19 # Add bitkeeper keyword to this file as a test. # -------------------------------------------- # 01/05/16 cort@ftsoj.fsmlabs.com 1.123.1.20 # Merge in some APUS diffs from Roman Zippel # -------------------------------------------- # 01/05/16 cort@ftsoj.fsmlabs.com 1.159 # Merge ftsoj.fsmlabs.com:/sys/linuxppc_2_4 # into ftsoj.fsmlabs.com:/sys/linuxppc_2_4_devel # -------------------------------------------- # 01/05/16 cort@ftsoj.fsmlabs.com 1.123.1.21 # Revert defconfig back to the older version. Build AIC7xxx in # rather than build it as a module. This syncs common_defconfig and # defconfig. # -------------------------------------------- # 01/05/16 cort@ftsoj.fsmlabs.com 1.160 # Merge ftsoj.fsmlabs.com:/sys/linuxppc_2_4 # into ftsoj.fsmlabs.com:/sys/linuxppc_2_4_devel # -------------------------------------------- # 01/05/16 cort@ftsoj.fsmlabs.com 1.123.1.22 # Add BitKeeper keywords to the PPC files. Alan asked for this to # make it easier for him to merge our changes into his tree. # -------------------------------------------- # 01/05/17 paulus@tango.paulus.ozlabs.org 1.123.1.23 # Add support for mmap on /proc/bus/pci/xx/yy as outlined by # Dave Miller. DaveM did all the hard work, I just implemented # the arch-specific mmap and pci_controller_num routines. # -------------------------------------------- # 01/05/17 trini@opus.bloom.county 1.123.1.24 # Two last GCC warning fixes from Franz Sirl. # -------------------------------------------- # 01/05/17 cort@cort. 1.123.1.25 # Remove extra BitKeeper Id section in setup.c # -------------------------------------------- # 01/05/17 cort@cort. 1.123.1.26 # Revert mkdep.c since this hasn't gone to the main tree yet and isn't # necessary for PPC builds. # -------------------------------------------- # 01/05/17 cort@cort. 1.123.1.27 # Bring drivers/sgi/char/linux_logo.h back. # -------------------------------------------- # 01/05/17 trini@opus.bloom.county 1.123.3.1 # Minor 8xx compile fixes. # -------------------------------------------- # 01/05/17 cort@cort. 1.161 # 1-help.patch # -------------------------------------------- # 01/05/17 cort@cort. 1.162 # 2-mot_mcpn765.patch # -------------------------------------------- # 01/05/17 cort@cort. 1.163 # 3-misc-simple.patch # -------------------------------------------- # 01/05/17 cort@cort. 1.164 # 4-men_f1.patch # -------------------------------------------- # 01/05/17 cort@cort. 1.165 # 5-host_bridge.patch # -------------------------------------------- # 01/05/17 cort@cort. 1.166 # 6-force_pcore.patch # -------------------------------------------- # 01/05/17 cort@cort. 1.167 # 7-sbs_8260.patch # -------------------------------------------- # 01/05/17 cort@cort. 1.168 # 8-zx4500_sandpoint.patch # -------------------------------------------- # 01/05/17 cort@cort. 1.169 # 9-8xx_fixes.patch # -------------------------------------------- # 01/05/17 cort@cort. 1.123.1.28 # Remove the %K% keyword on the second line of the BK Id. It doesn't # expand unless EXPAND1 isn't set in the bk flags which is dangerous # I'm told. # -------------------------------------------- # 01/05/17 cort@cort. 1.123.1.29 # Merge hq:/home/bk/linuxppc_2_4 into cort.:/home/sys/linuxppc_2_4 # -------------------------------------------- # 01/05/17 cort@cort. 1.170 # Merge in 2.4.5-pre3 linuxppc_2_4 changes. # -------------------------------------------- # 01/05/18 cort@cort. 1.171 # Remove a leftover BK seperator pointed out by Michael Sokolov # -------------------------------------------- # 01/05/19 paulus@tango.paulus.ozlabs.org 1.172 # PPC MM rewrite, including cache flush avoidance. We now have a # _PAGE_HASHPTE bit in the linux pte that tells us whether we have # an HPTE in the hash table for this page - this means we never change # the VSIDs on a tlb flush, and we can use a bitmap for free contexts, # thus fixing the mmu_context_overflow problem. And performance is # improved as well. # -------------------------------------------- # 01/05/19 paulus@tango.paulus.ozlabs.org 1.173 # PPC MM rewrite. # -------------------------------------------- # 01/05/19 paulus@tango.paulus.ozlabs.org 1.174 # Restore BK tags. # -------------------------------------------- # diff -Nru a/BitKeeper/etc/gone b/BitKeeper/etc/gone --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/BitKeeper/etc/gone Mon May 21 17:07:05 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 Mon May 21 17:07:04 2001 +++ b/BitKeeper/etc/ignore Mon May 21 17:07:04 2001 @@ -1 +1,77 @@ -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 +PENDING/* +System.map +arch/ppc/boot/images/miboot.image +arch/ppc/boot/images/sImage +arch/ppc/boot/images/vmlinux.* +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/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 +BitKeeper/etc/level diff -Nru a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok --- a/BitKeeper/etc/logging_ok Mon May 21 17:07:04 2001 +++ b/BitKeeper/etc/logging_ok Mon May 21 17:07:04 2001 @@ -1,8 +1,25 @@ +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.of.borg +geert@tux.sonytel.be +hozer@narn.drgw.net +mporter@beef.az.mvista.com +paulus@argo.canberra.net.au +paulus@argo.linuxcare.com.au paulus@argo.ozlabs.ibm.com.au -cort@cort.fsmlabs.com -cort@f50.fsmlabs.com +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 Mon May 21 17:07:05 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 -r`cat BitKeeper/etc/csets-in` -v + 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 Mon May 21 17:07:03 2001 +++ b/CREDITS Mon May 21 17:07:03 2001 @@ -1126,13 +1126,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 @@ -1731,6 +1729,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 Mon May 21 17:07:04 2001 +++ b/Documentation/Configure.help Mon May 21 17:07:04 2001 @@ -11473,6 +11473,16 @@ (the one containing the directory /) cannot be a module, so saying M could be dangerous. If unsure, say N. +PReP residual data support +CONFIG_PREP_RESIDUAL + Some PReP systems have residual data passed to the kernel by the + firmware. This allows detection of memory size, devices present and + other useful pieces of information. Sometimes this information is not + present or incorrect. + + Unless you expect to boot on a PReP system, there is not need to select + yes. + /proc file system support CONFIG_PROC_FS This is a virtual file system providing information about the status @@ -12669,6 +12679,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 @@ -13182,6 +13201,14 @@ say M here and read Documentation/modules.txt. The module will be called msbusmouse.o. +Apple Desktop Bus support +CONFIG_ADB + Apple Desktop Bus (ADB) support is for support of devices which + are connected to the to an ADB port. ADB devices tend to have + 4 pins. If you have an Apple Macintosh prior to the iMac, or a + "Blue and White G3", you probably want to say Y here. Otherwise + say N. + Apple Desktop Bus mouse support CONFIG_ADBMOUSE Say Y here if you have this type of bus mouse (4 pin connector) as @@ -16227,22 +16254,58 @@ Processor Type CONFIG_6xx There are four types of PowerPC chips supported. The more common - types (601, 603, 604, 740, 750), the Motorola embedded versions - (821, 823, 850, 855, 860), the IBM embedded versions (403 and + types (601, 603, 604, 740, 750, 7400), the Motorola embedded versions + (821, 823, 850, 855, 860, 8260), the IBM embedded versions (403 and 405) and the high end 64 bit Power processors (Power 3, Power 4). - Unless you are building a kernel for one of the embedded - processor systems, or a 64 bit IBM RS/6000, choose 6xx. Note that - the kernel runs in 32-bit mode even on 64-bit chips. + Unless you are building a kernel for one of the embedded processor + systems, or a 64 bit IBM RS/6000, choose 6xx. Note that the kernel + runs in 32-bit mode even on 64-bit chips. Also note that because + the 82xx family has a 603e core, specific support for that chipset + is asked later on. + +Motorola MPC8260 CPM support +CONFIG_8260 + The MPC8260 CPM (Communications Processor Module) is a typically + embedded CPU made by Motorola. Selecting this option means that + you wish to build a kernel for a machine with specifically an 8260 + for a CPU. + + If in doubt, say N. + +Workarounds for PPC601 bugs +CONFIG_PPC601_SYNC_FIX + Some versions of the PPC601 (the first PowerPC chip) have bugs which + mean that extra synchronization instructions are required near certain + instructions, typically those that make major changes to the CPU state. + These extra instructions reduce performance slightly. If you say N + here, these extra instructions will not be included, resulting in a + kernel which will run faster but may not run at all on some systems + with the PPC601 chip. + + If in doubt, say Y here. Machine Type -CONFIG_PMAC +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, Amiga Power-Up systems (APUS), CHRP and the - embedded MBX boards from Motorola. Currently, a single kernel binary - only supports one type or the other. However, there is very early - work on support for CHRP, PReP and PowerMac's from a single binary. + 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 @@ -16302,6 +16365,37 @@ an image of the device tree that the kernel copies from Open Firmware. If unsure, say Y here. +RTAS proc interface +CONFIG_PPC_RTAS + When you use this option, you will be able to use RTAS from + userspace. + + RTAS stands for RunTime Abstraction Services and should + provide a portable way to access and set system information. This is + commonly used on RS/6000 (pSeries) computers. + + You can access RTAS via the special proc filesystem entry rtas. + Don't confuse this rtas entry with the one in /proc/device-tree/rtas + which is readonly. + + If you don't know if you can use RTAS look into + /proc/device-tree/rtas. If there are some entries, it is very likely + that you will be able to use RTAS. + + You can do cool things with rtas. To print out information about + various sensors in the system, just do a + + $ cat /proc/rtas/sensors + + or if you power off your machine at night but want it running when + you enter your office at 7:45 am, do a + + # date -d 'tomorrow 7:30' +%s > /proc/rtas/poweron + + and shutdown. + + If unsure, say Y + MESH (Power Mac internal SCSI) support CONFIG_SCSI_MESH Many Power Macintoshes and clones have a MESH (Macintosh Enhanced @@ -16345,6 +16439,16 @@ which can be inserted in and removed from the running kernel whenever you want). If you want to compile it as a module, say M here and read Documentation/modules.txt. + +Use AAUI port instead of TP by default +CONFIG_MACE_AAUI_PORT + Some Apple machines (notably the Apple Network Server) which use the + MACE ethernet chip have an Apple AUI port (small 15-pin connector), + instead of an 8-pin RJ45 connector for twisted-pair ethernet. Say + Y here if you have such a machine. If unsure, say N. + The driver will default to AAUI on ANS anyway, and if you use it as + a module, you can provide the port_aaui=0|1 to force the driver + setting. BMAC (G3 ethernet) support CONFIG_BMAC diff -Nru a/Documentation/powerpc/00-INDEX b/Documentation/powerpc/00-INDEX --- a/Documentation/powerpc/00-INDEX Mon May 21 17:07:04 2001 +++ b/Documentation/powerpc/00-INDEX Mon May 21 17:07:04 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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/Documentation/sysrq.txt b/Documentation/sysrq.txt --- a/Documentation/sysrq.txt Mon May 21 17:07:04 2001 +++ b/Documentation/sysrq.txt Mon May 21 17:07:04 2001 @@ -29,7 +29,8 @@ You send a BREAK, then within 5 seconds a command key. Sending BREAK twice is interpreted as a normal BREAK. -On Mac - Press 'Keypad+-F13-' +On PowerPC - Press 'ALT - Print Screen (or F13) - , + Print Screen (or F13) - may suffice. On other - If you know of the key combos for other architectures, please let me know so I can add them to this section. diff -Nru a/MAINTAINERS b/MAINTAINERS --- a/MAINTAINERS Mon May 21 17:07:04 2001 +++ b/MAINTAINERS Mon May 21 17:07:04 2001 @@ -596,6 +596,11 @@ W: http://www.uni-mainz.de/~langm000/linux.html S: Maintained +IBM RS/6000 LINUX +P: Paul Mackerras +M: paulus@samba.org +S: Supported + IBM ServeRAID RAID DRIVER P: Keith Mitchell M: ipslinux@us.ibm.com @@ -780,12 +785,14 @@ 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 @@ -1054,7 +1061,7 @@ P: Paul Mackerras M: paulus@samba.org L: linux-ppp@vger.kernel.org -S: Maintained +S: Supported PPP OVER ETHERNET P: Michal Ostrowski diff -Nru a/Makefile b/Makefile --- a/Makefile Mon May 21 17:07:04 2001 +++ b/Makefile Mon May 21 17:07:04 2001 @@ -160,7 +160,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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/8260_io/Makefile Mon May 21 17:07:04 2001 @@ -1,3 +1,5 @@ +# 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/8260_io/commproc.c Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ /* * General Purpose functions for the global management of the diff -Nru a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c --- a/arch/ppc/8260_io/enet.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/8260_io/enet.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Ethernet driver for Motorola MPC8260. * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) * Copyright (c) 2000 MontaVista Software Inc. (source@mvista.com) 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/8260_io/fcc_enet.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Fast Ethernet Controller (FCC) driver for Motorola MPC8260. * Copyright (c) 2000 MontaVista Software, Inc. Dan Malek (dmalek@jlc.net) * diff -Nru a/arch/ppc/8260_io/uart.c b/arch/ppc/8260_io/uart.c --- a/arch/ppc/8260_io/uart.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/8260_io/uart.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * UART driver for MPC8260 CPM SCC or SMC * Copyright (c) 1999 Dan Malek (dmalek@jlc.net) * Copyright (c) 2000 MontaVista Software, Inc. (source@mvista.com) diff -Nru a/arch/ppc/8xx_io/Makefile b/arch/ppc/8xx_io/Makefile --- a/arch/ppc/8xx_io/Makefile Mon May 21 17:07:04 2001 +++ b/arch/ppc/8xx_io/Makefile Mon May 21 17:07:04 2001 @@ -1,3 +1,5 @@ +# 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/8xx_io/commproc.c Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ /* * General Purpose functions for the global management of the diff -Nru a/arch/ppc/8xx_io/commproc.h b/arch/ppc/8xx_io/commproc.h --- a/arch/ppc/8xx_io/commproc.h Mon May 21 17:07:04 2001 +++ b/arch/ppc/8xx_io/commproc.h Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ /* * MPC8xx Communication Processor Module. diff -Nru a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c --- a/arch/ppc/8xx_io/enet.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/8xx_io/enet.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Ethernet driver for Motorola MPC8xx. * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) * diff -Nru a/arch/ppc/8xx_io/fec.c b/arch/ppc/8xx_io/fec.c --- a/arch/ppc/8xx_io/fec.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/8xx_io/fec.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Fast Ethernet Controller (FEC) driver for Motorola MPC8xx. * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) * diff -Nru a/arch/ppc/8xx_io/uart.c b/arch/ppc/8xx_io/uart.c --- a/arch/ppc/8xx_io/uart.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/8xx_io/uart.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * UART driver for MPC860 CPM SCC or SMC * Copyright (c) 1997 Dan Malek (dmalek@jlc.net) * diff -Nru a/arch/ppc/Makefile b/arch/ppc/Makefile --- a/arch/ppc/Makefile Mon May 21 17:07:04 2001 +++ b/arch/ppc/Makefile Mon May 21 17:07:04 2001 @@ -1,3 +1,5 @@ +# 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 # for "archclean" and "archdep" for cleaning up and making dependencies for @@ -65,10 +67,6 @@ endif MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot -MAKECOFFBOOT = $(MAKE) -C arch/$(ARCH)/coffboot -MAKECHRPBOOT = $(MAKE) -C arch/$(ARCH)/chrpboot -MAKEMBXBOOT = $(MAKE) -C arch/$(ARCH)/mbxboot -MAKETREEBOOT = $(MAKE) -C arch/$(ARCH)/treeboot ifdef CONFIG_8xx SUBDIRS += arch/ppc/8xx_io @@ -89,111 +87,24 @@ checks: @$(MAKE) -C arch/$(ARCH)/kernel checks -BOOT_TARGETS = zImage znetboot.initrd zImage.initrd - -ifdef CONFIG_4xx -$(BOOT_TARGETS): $(CHECKS) vmlinux - @$(MAKETREEBOOT) $@ -endif - -ifdef CONFIG_8xx -$(BOOT_TARGETS): $(CHECKS) vmlinux - @$(MAKECOFFBOOT) $@ - @$(MAKEMBXBOOT) $@ -endif - -ifdef CONFIG_6xx -ifndef CONFIG_8260 -$(BOOT_TARGETS): $(CHECKS) vmlinux - @$(MAKECOFFBOOT) $@ - @$(MAKEBOOT) $@ - @$(MAKECHRPBOOT) $@ - -znetboot: $(CHECKS) vmlinux -ifdef CONFIG_ALL_PPC -ifdef CONFIG_SMP - cp -f vmlinux /tftpboot/vmlinux.smp -else - cp -f vmlinux /tftpboot/vmlinux -endif -endif - @$(MAKECOFFBOOT) $@ - @$(MAKEBOOT) $@ - @$(MAKECHRPBOOT) $@ -else -# 8260 is custom 6xx -$(BOOT_TARGETS): $(CHECKS) vmlinux - @$(MAKECOFFBOOT) $@ - @$(MAKEMBXBOOT) $@ -endif -endif +BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd -ifdef CONFIG_PPC64BRIDGE $(BOOT_TARGETS): $(CHECKS) vmlinux - @$(MAKECOFFBOOT) $@ - @$(MAKEBOOT) $@ - @$(MAKECHRPBOOT) $@ - -znetboot: $(CHECKS) vmlinux - cp -f vmlinux /tftpboot/vmlinux.64 - @$(MAKECOFFBOOT) $@ @$(MAKEBOOT) $@ - @$(MAKECHRPBOOT) $@ -endif .PHONY: clean_config clean_config: rm -f .config arch/ppc/defconfig -gemini_config: clean_config - cp -f arch/ppc/configs/gemini_defconfig arch/ppc/defconfig - -pmac_config: clean_config - cp -f arch/ppc/configs/pmac_defconfig arch/ppc/defconfig - -prep_config: clean_config - cp -f arch/ppc/configs/prep_defconfig arch/ppc/defconfig - -chrp_config: clean_config - cp -f arch/ppc/configs/chrp_defconfig arch/ppc/defconfig - -common_config: clean_config - cp -f arch/ppc/configs/common_defconfig arch/ppc/defconfig - -mbx_config: clean_config - cp -f arch/ppc/configs/mbx_defconfig arch/ppc/defconfig - -apus_config: clean_config - cp -f arch/ppc/configs/apus_defconfig arch/ppc/defconfig - -oak_config: clean_config - cp -f arch/ppc/configs/oak_defconfig arch/ppc/defconfig - -walnut_config: clean_config - cp -f arch/ppc/configs/walnut_defconfig arch/ppc/defconfig - -rpxlite_config: clean_config - cp -f arch/ppc/configs/rpxlite_defconfig arch/ppc/defconfig - -rpxcllf_config: clean_config - cp -f arch/ppc/configs/rpxcllf_defconfig arch/ppc/defconfig - -bseip_config: clean_config - cp -f arch/ppc/configs/bseip_defconfig arch/ppc/defconfig - -est8260_config: clean_config - cp -f arch/ppc/configs/est8260_defconfig arch/ppc/defconfig +%_config: arch/ppc/configs/%_defconfig + rm -f .config arch/ppc/defconfig + cp -f arch/ppc/configs/$(@:config=defconfig) arch/ppc/defconfig archclean: rm -f arch/ppc/kernel/{mk_defs,ppc_defs.h,find_name,checks} - @$(MAKECOFFBOOT) clean @$(MAKEBOOT) clean - @$(MAKECHRPBOOT) clean - @$(MAKEMBXBOOT) clean - @$(MAKETREEBOOT) clean archmrproper: archdep: - $(MAKEBOOT) fastdep - $(MAKECHRPBOOT) fastdep + $(MAKEBOOT) dep diff -Nru a/arch/ppc/amiga/Makefile b/arch/ppc/amiga/Makefile --- a/arch/ppc/amiga/Makefile Mon May 21 17:07:03 2001 +++ b/arch/ppc/amiga/Makefile Mon May 21 17:07:03 2001 @@ -1,3 +1,5 @@ +# BK Id: %F% %I% %G% %U% %#% +# # # Makefile for Linux arch/m68k/amiga source directory # @@ -14,6 +16,6 @@ obj-y := config.o amiints.o cia.o time.o bootinfo.o amisound.o \ chipram.o amiga_ksyms.o -obj-$(CONFIG_AMIGA_PCMCIA) += pcmia.o +obj-$(CONFIG_AMIGA_PCMCIA) += pcmcia.o include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/amiga/amiga_ksyms.c b/arch/ppc/amiga/amiga_ksyms.c --- a/arch/ppc/amiga/amiga_ksyms.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/amiga/amiga_ksyms.c Mon May 21 17:07:04 2001 @@ -1 +1,4 @@ +/* + * 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/amiga/amiints.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/m68k/amiga/amiints.c -- Amiga Linux interrupt handling code * * This file is subject to the terms and conditions of the GNU General Public @@ -255,9 +258,10 @@ return; } - if (irq >= IRQ_AMIGA_AUTO) + if (irq >= IRQ_AMIGA_AUTO) { sys_free_irq(irq - IRQ_AMIGA_AUTO, dev_id); - + return; + } if (irq >= IRQ_AMIGA_CIAA) { cia_free_irq(irq, dev_id); return; @@ -295,7 +299,10 @@ return; } - if (--ami_ablecount[irq]) + ami_ablecount[irq]--; + if (ami_ablecount[irq]<0) + ami_ablecount[irq]=0; + else if (ami_ablecount[irq]) return; /* No action for auto-vector interrupts */ @@ -347,64 +354,16 @@ ami_irq_list[irq]->handler(irq, ami_irq_list[irq]->dev_id, fp); } -void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server) +void amiga_do_irq_list(int irq, struct pt_regs *fp) { - irq_node_t *node, *slow_nodes; - unsigned short intena; - unsigned long flags; + irq_node_t *node; kstat.irqs[0][SYS_IRQS + irq]++; - if (server->count++) - server->reentrance = 1; - - intena = ami_intena_vals[irq]; - custom.intreq = intena; - /* serve first fast handlers - there can only be one of these */ - node = ami_irq_list[irq]; - - /* - * Timer interrupts show up like this - */ - if (!node) { - server->count--; - return; - } + custom.intreq = ami_intena_vals[irq]; - if (node && (node->flags & SA_INTERRUPT)) { - save_flags(flags); - cli(); + for (node = ami_irq_list[irq]; node; node = node->next) node->handler(irq, node->dev_id, fp); - restore_flags(flags); - - server->count--; - return; - } - - /* - * Disable the interrupt source in question and reenable all - * other interrupts. No interrupt handler should ever touch - * the intena flags directly! - */ - custom.intena = intena; - save_flags(flags); - sti(); - - slow_nodes = node; - for (;;) { - for (; node; node = node->next) - node->handler(irq, node->dev_id, fp); - - if (!server->reentrance) { - server->count--; - restore_flags(flags); - custom.intena = IF_SETCLR | intena; - return; - } - - server->reentrance = 0; - node = slow_nodes; - } } /* @@ -437,7 +396,6 @@ static void ami_int3(int irq, void *dev_id, struct pt_regs *fp) { unsigned short ints = custom.intreqr & custom.intenar; - static struct irq_server server = {0, 0}; /* if a blitter interrupt */ if (ints & IF_BLIT) { @@ -453,7 +411,7 @@ /* if a vertical blank interrupt */ if (ints & IF_VERTB) - amiga_do_irq_list(IRQ_AMIGA_VERTB, fp, &server); + amiga_do_irq_list(IRQ_AMIGA_VERTB, fp); } static void ami_int4(int irq, void *dev_id, struct pt_regs *fp) @@ -512,7 +470,7 @@ and executes them in a loop. Having ami_badint at the end of the chain is a bad idea. */ void (*amiga_default_handler[SYS_IRQS])(int, void *, struct pt_regs *) = { - NULL, ami_int1, NULL, NULL /* FB expects to replace ami_int3*/, + NULL, ami_int1, NULL, ami_int3, ami_int4, ami_int5, NULL, ami_int7 }; #else diff -Nru a/arch/ppc/amiga/amisound.c b/arch/ppc/amiga/amisound.c --- a/arch/ppc/amiga/amisound.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/amiga/amisound.c Mon May 21 17:07:04 2001 @@ -1 +1,4 @@ +/* + * 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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/amiga/bootinfo.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/amiga/bootinfo.c * * Extracted from arch/m68k/kernel/setup.c. diff -Nru a/arch/ppc/amiga/chipram.c b/arch/ppc/amiga/chipram.c --- a/arch/ppc/amiga/chipram.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/amiga/chipram.c Mon May 21 17:07:04 2001 @@ -1,183 +1,4 @@ /* -** linux/amiga/chipram.c -** -** Modified 03-May-94 by Geert Uytterhoeven -** - 64-bit aligned allocations for full AGA compatibility -*/ - -#include -#include -#include -#include -#include -#include - -struct chip_desc { - unsigned first : 1; - unsigned last : 1; - unsigned alloced : 1; - unsigned length : 24; - long pad; /* We suppose this makes this struct 64 bits long!! */ -}; - -#define DP(ptr) ((struct chip_desc *)(ptr)) - -u_long amiga_chip_size; -static unsigned long chipavail; - -static struct resource chipram = { "Chip RAM", 0 }; - -unsigned long amiga_chip_avail( void ) -{ -#ifdef DEBUG - printk("chip_avail : %ld bytes\n",chipavail); -#endif - return chipavail; -} - - -void __init amiga_chip_init (void) -{ - struct chip_desc *dp; - - if (!AMIGAHW_PRESENT(CHIP_RAM)) - return; - -#ifndef CONFIG_APUS_FAST_EXCEPT - /* - * Remove the first 4 pages where PPC exception handlers will - * be located. - */ - amiga_chip_size -= 0x4000; -#endif - chipram.end = amiga_chip_size-1; - request_resource(&iomem_resource, &chipram); - - /* initialize start boundary */ - - dp = DP(chipaddr); - dp->first = 1; - - dp->alloced = 0; - dp->length = amiga_chip_size - 2*sizeof(*dp); - - /* initialize end boundary */ - dp = DP(chipaddr + amiga_chip_size) - 1; - dp->last = 1; - - dp->alloced = 0; - dp->length = amiga_chip_size - 2*sizeof(*dp); - chipavail = dp->length; /*MILAN*/ - -#ifdef DEBUG - printk ("chipram end boundary is %p, length is %d\n", dp, - dp->length); -#endif -} - -void *amiga_chip_alloc(long size, const char *name) -{ - /* last chunk */ - struct chip_desc *dp; - void *ptr; - - /* round off */ - size = (size + 7) & ~7; - -#ifdef DEBUG - printk("amiga_chip_alloc: allocate %ld bytes\n", size); -#endif - - /* - * get pointer to descriptor for last chunk by - * going backwards from end chunk - */ - dp = DP(chipaddr + amiga_chip_size) - 1; - dp = DP((unsigned long)dp - dp->length) - 1; - - while ((dp->alloced || dp->length < size) - && !dp->first) - dp = DP ((unsigned long)dp - dp[-1].length) - 2; - - if (dp->alloced || dp->length < size) { - printk ("no chipmem available for %ld allocation\n", size); - return NULL; - } - - if (dp->length < (size + 2*sizeof(*dp))) { - /* length too small to split; allocate the whole thing */ - dp->alloced = 1; - ptr = (void *)(dp+1); - dp = DP((unsigned long)ptr + dp->length); - dp->alloced = 1; -#ifdef DEBUG - printk ("amiga_chip_alloc: no split\n"); -#endif - } else { - /* split the extent; use the end part */ - long newsize = dp->length - (2*sizeof(*dp) + size); - -#ifdef DEBUG - printk ("amiga_chip_alloc: splitting %d to %ld\n", dp->length, - newsize); -#endif - dp->length = newsize; - dp = DP((unsigned long)(dp+1) + newsize); - dp->first = dp->last = 0; - dp->alloced = 0; - dp->length = newsize; - dp++; - dp->first = dp->last = 0; - dp->alloced = 1; - dp->length = size; - ptr = (void *)(dp+1); - dp = DP((unsigned long)ptr + size); - dp->alloced = 1; - dp->length = size; - } - -#ifdef DEBUG - printk ("amiga_chip_alloc: returning %p\n", ptr); -#endif - - if ((unsigned long)ptr & 7) - panic("amiga_chip_alloc: alignment violation\n"); - - chipavail -= size + (2*sizeof(*dp)); /*MILAN*/ - - if (!request_mem_region(ZTWO_PADDR(ptr), size, name)) - printk(KERN_WARNING "amiga_chip_alloc: region of size %ld at 0x%08lx " - "is busy\n", size, ZTWO_PADDR(ptr)); - - return ptr; -} - -void amiga_chip_free (void *ptr) -{ - struct chip_desc *sdp = DP(ptr) - 1, *dp2; - struct chip_desc *edp = DP((unsigned long)ptr + sdp->length); - - chipavail += sdp->length + (2* sizeof(sdp)); /*MILAN*/ -#ifdef DEBUG - printk("chip_free: free %ld bytes at %p\n",sdp->length,ptr); -#endif - /* deallocate the chunk */ - sdp->alloced = edp->alloced = 0; - release_mem_region(ZTWO_PADDR(ptr), sdp->length); - - /* check if we should merge with the previous chunk */ - if (!sdp->first && !sdp[-1].alloced) { - dp2 = DP((unsigned long)sdp - sdp[-1].length) - 2; - dp2->length += sdp->length + 2*sizeof(*sdp); - edp->length = dp2->length; - sdp = dp2; - } - - /* check if we should merge with the following chunk */ - if (!edp->last && !edp[1].alloced) { - dp2 = DP((unsigned long)edp + edp[1].length) + 2; - dp2->length += edp->length + 2*sizeof(*sdp); - sdp->length = dp2->length; - edp = dp2; - } -} + * 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/amiga/cia.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/m68k/amiga/cia.c - CIA support * * Copyright (C) 1996 Roman Zippel @@ -27,18 +30,17 @@ u_short int_mask; int handler_irq, cia_irq, server_irq; char *name; - struct irq_server server; irq_handler_t irq_list[CIA_IRQS]; } ciaa_base = { &ciaa, 0, 0, IF_PORTS, IRQ_AMIGA_AUTO_2, IRQ_AMIGA_CIAA, IRQ_AMIGA_PORTS, - "CIAA handler", {0, 0} + "CIAA handler" }, ciab_base = { &ciab, 0, 0, IF_EXTER, IRQ_AMIGA_AUTO_6, IRQ_AMIGA_CIAB, IRQ_AMIGA_EXTER, - "CIAB handler", {0, 0} + "CIAB handler" }; #define CIA_SET_BASE_ADJUST_IRQ(base, irq) \ @@ -197,7 +199,7 @@ } ints >>= 1; } - amiga_do_irq_list(base->server_irq, fp, &base->server); + amiga_do_irq_list(base->server_irq, fp); } void __init cia_init_IRQ(struct ciabase *base) diff -Nru a/arch/ppc/amiga/config.c b/arch/ppc/amiga/config.c --- a/arch/ppc/amiga/config.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/amiga/config.c Mon May 21 17:07:03 2001 @@ -1,12 +1,8 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #define m68k_debug_device debug_device -#include - -/* machine dependent "kbd-reset" setup function */ -void (*mach_kbd_reset_setup) (char *, int) __initdata = 0; - -#include - /* * linux/arch/m68k/amiga/config.c * @@ -28,6 +24,10 @@ #include #include #include +#include +#ifdef CONFIG_ZORRO +#include +#endif #include #include @@ -36,10 +36,12 @@ #include #include #include +#include #include -#include +#include unsigned long powerup_PCI_present; +unsigned long powerup_BPPCPLUS_present; unsigned long amiga_model; unsigned long amiga_eclock; unsigned long amiga_masterclock; @@ -121,7 +123,7 @@ }; #ifdef CONFIG_MAGIC_SYSRQ -static char amiga_sysrq_xlate[128] = +char amiga_sysrq_xlate[128] = "\0001234567890-=\\\000\000" /* 0x00 - 0x0f */ "qwertyuiop[]\000123" /* 0x10 - 0x1f */ "asdfghjkl;'\000\000456" /* 0x20 - 0x2f */ @@ -139,16 +141,18 @@ * Motherboard Resources present in all Amiga models */ -static struct resource mb_res[] = { - { "Ranger Memory", 0x00c00000, 0x00c7ffff }, - { "CIA B", 0x00bfd000, 0x00bfdfff }, - { "CIA A", 0x00bfe000, 0x00bfefff }, - { "Custom I/O", 0x00dff000, 0x00dfffff }, - { "Kickstart ROM", 0x00f80000, 0x00ffffff } +static struct { + struct resource _ciab, _ciaa, _custom, _kickstart; +} mb_resources = { +// { "Ranger Memory", 0x00c00000, 0x00c7ffff }, + _ciab: { "CIA B", 0x00bfd000, 0x00bfdfff }, + _ciaa: { "CIA A", 0x00bfe000, 0x00bfefff }, + _custom: { "Custom I/O", 0x00dff000, 0x00dfffff }, + _kickstart: { "Kickstart ROM", 0x00f80000, 0x00ffffff } }; static struct resource rtc_resource = { - "A2000 RTC", 0x00dc0000, 0x00dcffff + NULL, 0x00dc0000, 0x00dcffff }; static struct resource ram_resource[NUM_MEMINFO]; @@ -194,6 +198,7 @@ break; case BI_AMIGA_AUTOCON: +#ifdef CONFIG_ZORRO if (zorro_num_autocon < ZORRO_NUM_AUTO) { const struct ConfigDev *cd = (struct ConfigDev *)data; struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++]; @@ -204,12 +209,21 @@ dev->resource.end = dev->resource.start+cd->cd_BoardSize-1; } else printk("amiga_parse_bootinfo: too many AutoConfig devices\n"); +#endif /* CONFIG_ZORRO */ break; case BI_AMIGA_SERPER: /* serial port period: ignored here */ break; + case BI_AMIGA_PUP_BRIDGE: + powerup_PCI_present = *(const unsigned short *)data; + break; + + case BI_AMIGA_BPPC_SCSI: + powerup_BPPCPLUS_present = *(const unsigned short *)data; + break; + default: unknown = 1; } @@ -392,11 +406,8 @@ /* Some APUS boxes may have PCI memory, but ... */ iomem_resource.name = "Memory"; - request_resource(&iomem_resource, &ranger_resource); - request_resource(&iomem_resource, &ciab_resource); - request_resource(&iomem_resource, &ciaa_resource); - request_resource(&iomem_resource, &custom_chips_resource); - request_resource(&iomem_resource, &kickstart_resource); + for (i = 0; i < 4; i++) + request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]); mach_sched_init = amiga_sched_init; mach_keyb_init = amiga_keyb_init; @@ -415,11 +426,12 @@ mach_gettimeoffset = amiga_gettimeoffset; if (AMIGAHW_PRESENT(A3000_CLK)){ mach_gettod = a3000_gettod; - rtc_resource.name[1] = '3'; + rtc_resource.name = "A3000 RTC"; request_resource(&iomem_resource, &rtc_resource); } else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */ mach_gettod = a2000_gettod; + rtc_resource.name = "A2000 RTC"; request_resource(&iomem_resource, &rtc_resource); } @@ -439,14 +451,10 @@ mach_floppy_setup = amiga_floppy_setup; #endif mach_reset = amiga_reset; +#ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; - kd_mksound = amiga_mksound; -#ifdef CONFIG_MAGIC_SYSRQ - mach_sysrq_key = 0x5f; /* HELP */ - mach_sysrq_shift_state = 0x03; /* SHIFT+ALTGR */ - mach_sysrq_shift_mask = 0xff; /* all modifiers except CapsLock */ - mach_sysrq_xlate = amiga_sysrq_xlate; #endif + kd_mksound = amiga_mksound; #ifdef CONFIG_HEARTBEAT mach_heartbeat = amiga_heartbeat; #endif @@ -500,11 +508,14 @@ static unsigned short jiffy_ticks; static void __init amiga_sched_init(void (*timer_routine)(int, void *, - struct pt_regs *)) + struct pt_regs *)) { + static struct resource sched_res = { + "timer", 0x00bfd400, 0x00bfd5ff, + }; jiffy_ticks = (amiga_eclock+HZ/2)/HZ; - if (!request_mem_region(CIAB_PHYSADDR+0x400, 0x200, "timer")) + if (request_resource(&mb_resources._ciab, &sched_res)) printk("Cannot allocate ciab.ta{lo,hi}\n"); ciab.cra &= 0xC0; /* turn off timer A, continuous mode, from Eclk */ ciab.talo = jiffy_ticks % 256; @@ -612,6 +623,8 @@ t->wday = tod->weekday; t->mon = tod->month1 * 10 + tod->month2 - 1; t->year = tod->year1 * 10 + tod->year2; + if (t->year <= 69) + t->year += 100; } else { tod->second1 = t->sec / 10; tod->second2 = t->sec % 10; @@ -625,6 +638,8 @@ tod->weekday = t->wday; tod->month1 = (t->mon + 1) / 10; tod->month2 = (t->mon + 1) % 10; + if (t->year >= 100) + t->year -= 100; tod->year1 = t->year / 10; tod->year2 = t->year % 10; } @@ -646,6 +661,8 @@ t->wday = tod->weekday; t->mon = tod->month1 * 10 + tod->month2 - 1; t->year = tod->year1 * 10 + tod->year2; + if (t->year <= 69) + t->year += 100; if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){ if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12) @@ -672,6 +689,8 @@ tod->weekday = t->wday; tod->month1 = (t->mon + 1) / 10; tod->month2 = (t->mon + 1) % 10; + if (t->year >= 100) + t->year -= 100; tod->year1 = t->year / 10; tod->year2 = t->year % 10; } @@ -796,7 +815,9 @@ static void amiga_savekmsg_init(void) { - savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM, "Debug"); + static struct resource debug_res = { "Debug" }; + + savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); savekmsg->magic1 = SAVEKMSG_MAGIC1; savekmsg->magic2 = SAVEKMSG_MAGIC2; savekmsg->magicptr = virt_to_phys(savekmsg); diff -Nru a/arch/ppc/amiga/ints.c b/arch/ppc/amiga/ints.c --- a/arch/ppc/amiga/ints.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/amiga/ints.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/amiga/ints.c * * Linux/m68k general interrupt handling code from arch/m68k/kernel/ints.c diff -Nru a/arch/ppc/amiga/pcmcia.c b/arch/ppc/amiga/pcmcia.c --- a/arch/ppc/amiga/pcmcia.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/amiga/pcmcia.c Mon May 21 17:07:04 2001 @@ -1 +1,4 @@ +/* + * 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/amiga/time.c Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #include /* CONFIG_HEARTBEAT */ #include #include diff -Nru a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile --- a/arch/ppc/boot/Makefile Mon May 21 17:07:05 2001 +++ b/arch/ppc/boot/Makefile Mon May 21 17:07:05 2001 @@ -9,27 +9,24 @@ # Adapted for PowerPC by Gary Thomas # modified by Cort (cort@cs.nmt.edu) # + .c.s: $(CC) $(CFLAGS) -S -o $*.s $< .s.o: $(AS) -o $*.o $< .c.o: - $(CC) $(CFLAGS) -DINITRD_OFFSET=$(IOFF) -DINITRD_SIZE=$(ISZ) -DZIMAGE_OFFSET=$(ZOFF) -DZIMAGE_SIZE=$(ZSZ) -D__BOOTER__ -c -o $*.o $< + $(CC) $(CFLAGS) -c -o $*.o $< .S.s: $(CPP) $(AFLAGS) -traditional -o $*.o $< .S.o: $(CC) $(AFLAGS) -traditional -c -o $*.o $< -ZOFF = 0 -ZSZ = 0 -IOFF = 0 -ISZ = 0 +GZIP_FLAGS = -v9f -ifeq ($(CONFIG_SMP),y) -TFTPIMAGE=/tftpboot/zImage.prep.smp$(MSIZE) -else -TFTPIMAGE=/tftpboot/zImage.prep$(MSIZE) -endif +CFLAGS := $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -D__BOOTER__ \ + -I$(TOPDIR)/arch/$(ARCH)/boot/include +AFLAGS += -D__BOOTER__ +OBJCOPY_ARGS = -O elf32-powerpc ifeq ($(CONFIG_SMP),y) TFTPSIMAGE=/tftpboot/sImage.smp @@ -37,145 +34,81 @@ TFTPSIMAGE=/tftpboot/sImage endif -ifeq ($(CONFIG_PPC64BRIDGE),y) -MSIZE=.64 -else -MSIZE= -endif -ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00800000 +lib/zlib.a: + $(MAKE) -C lib -GZIP_FLAGS = -v9f +images/vmlinux.gz: $(TOPDIR)/vmlinux + $(MAKE) -C images vmlinux.gz -OBJECTS := head.o misc.o ../coffboot/zlib.o -CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -OBJCOPY_ARGS = -O elf32-powerpc - -OBJECTS += vreset.o kbd.o of1275.o -ifeq ($(CONFIG_SERIAL_CONSOLE),y) -OBJECTS += ns16550.o -endif - -all: zImage - -zvmlinux.initrd: zvmlinux - $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=initrd=ramdisk.image.gz \ - --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.initrd.tmp zvmlinux.initrd - $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd initrd` \ - -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd initrd` \ - -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd image` \ - -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd image` \ - -D__BOOTER__ \ - -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=initrd=ramdisk.image.gz \ - --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.initrd.tmp $@ - rm zvmlinux.initrd.tmp +# Since gemini doesn't need/have it's own directory, we do znetboot* here ifdef CONFIG_GEMINI - $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) - $(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.initrd.tmp svmlinux.initrd.tmp - ./mksimage svmlinux.initrd.tmp ../coffboot/vmlinux.gz ramdisk.image.gz \ - -o svmlinux.initrd > sImage.map - $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh sioffset initrd` \ - -DINITRD_SIZE=`sh sisize initrd` \ - -DZIMAGE_OFFSET=`sh sioffset zimage` \ - -DZIMAGE_SIZE=`sh sisize zimage` \ - -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) - $(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.initrd.tmp svmlinux.initrd.tmp - ./mksimage svmlinux.initrd.tmp ../coffboot/vmlinux.gz ramdisk.image.gz \ - -o svmlinux.initrd > /dev/null - rm svmlinux.initrd.tmp zvmlinux.initrd.tmp sImage.map +BOOT_TARGETS = zImage zImage.initrd +else +BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd endif -zImage: zvmlinux mkprep sImage mksimage +# We go into the utils dir by hand to ensure HOSTCC builds +$(BOOT_TARGETS): sImage vmapus lib/zlib.a images/vmlinux.gz +ifneq ("xx$(CONFIG_8260)$(CONFIG_8xx)","xx") + $(MAKE) -C mbx $@ +endif ifdef CONFIG_ALL_PPC - ./mkprep -pbp zvmlinux zImage + $(MAKE) -C utils addnote piggyback mknote hack-coff mkprep + $(MAKE) -C chrp $@ + $(MAKE) -C pmac $@ + $(MAKE) -C prep $@ endif -ifdef CONFIG_APUS - $(STRIP) ../../../vmlinux -o vmapus - gzip $(GZIP_FLAGS) vmapus +ifdef CONFIG_4xx + $(MAKE) -C tree $@ endif - -sImage: ../../../vmlinux -ifdef CONFIG_GEMINI - $(OBJCOPY) -I elf32-powerpc -O binary ../../../vmlinux sImage +ifdef CONFIG_K2 + $(MAKE) -C pmon $@ endif - -zImage.initrd: zvmlinux.initrd mkprep -ifdef CONFIG_ALL_PPC - ./mkprep -pbp zvmlinux.initrd zImage.initrd +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 -zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz mksimage -# -# build the boot loader image and then compute the offset into it -# for the kernel image -# - $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.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) zvmlinux image` \ - -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux image` \ - -D__BOOTER__ \ - -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.tmp $@ - rm zvmlinux.tmp +sImage: $(TOPDIR)/vmlinux ifdef CONFIG_GEMINI - $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) - $(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.tmp svmlinux.tmp - ./mksimage svmlinux.tmp ../coffboot/vmlinux.gz -o svmlinux > sImage.map - $(CC) $(CFLAGS) -DINITRD_OFFSET=0 -DINITRD_SIZE=0 \ - -DZIMAGE_OFFSET=`sh sioffset zimage` \ - -DZIMAGE_SIZE=`sh sisize zimage` \ - -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) - $(OBJCOPY) -I elf32-powerpc -O binary zvmlinux.tmp svmlinux.tmp - ./mksimage svmlinux.tmp ../coffboot/vmlinux.gz -o svmlinux > /dev/null - rm svmlinux.tmp sImage.map zvmlinux.tmp + $(OBJCOPY) -I elf32-powerpc -O binary $(TOPDIR)/vmlinux images/sImage endif -floppy: $(TOPDIR)/vmlinux zImage - dd if=zImage of=/dev/fd0H1440 bs=64b - -mkprep : mkprep.c - $(HOSTCC) -o mkprep mkprep.c - -mksimage: mksimage.c - $(HOSTCC) -o mksimage mksimage.c - -znetboot : zImage -ifdef CONFIG_ALL_PPC - cp zImage $(TFTPIMAGE) +vmapus: $(TOPDIR)/vmlinux +ifdef CONFIG_APUS + $(STRIP) $(TOPDIR)/vmlinux -o images/vmapus + gzip $(GZIP_FLAGS) images/vmapus endif + ifdef CONFIG_GEMINI - cp sImage $(TFTPSIMAGE) +znetboot : zImage + cp images/sImage $(TFTPSIMAGE) endif -znetboot.initrd : zImage.initrd - cp zImage.initrd $(TFTPIMAGE) - +# Do the dirs clean: - rm -f vmlinux* zvmlinux* mkprep zImage* sImage* mksimage - -fastdep: - $(TOPDIR)/scripts/mkdep *.[Sch] > .depend + $(MAKE) -C images clean + $(MAKE) -C spruce clean + $(MAKE) -C tree clean + $(MAKE) -C utils clean dep: - $(CPP) $(CPPFLAGS) -M *.S *.c > .depend - -# just here to match coffboot/Makefile -vmlinux.coff: -vmlinux.coff.initrd: +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/chrp/Makefile b/arch/ppc/boot/chrp/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/chrp/Makefile Mon May 21 17:07:04 2001 @@ -0,0 +1,73 @@ +# BK Id: %F% %I% %G% %U% %#% +# +# Makefile for making ELF bootable images for booting on CHRP +# using Open Firmware. +# +# Geert Uytterhoeven September 1997 +# +# Based on coffboot by Paul Mackerras + +ifeq ($(CONFIG_PPC64BRIDGE),y) +MSIZE=.64 +AFLAGS += -Wa,-mppc64bridge +else +MSIZE= +endif + +.c.o: + $(CC) $(CFLAGS) -DKERNELBASE=$(KERNELBASE) -c -o $*.o $< +.S.o: + $(CC) $(AFLAGS) -traditional -c -o $*.o $< + +LD_ARGS = -Ttext 0x00400000 + +OBJS = ../common/crt0.o start.o main.o misc.o ../common/string.o image.o +LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a +ADDNOTE = ../utils/addnote +PIGGYBACK = ../utils/piggyback + +ifeq ($(CONFIG_SMP),y) +TFTPIMAGE=/tftpboot/zImage.chrp.smp$(MSIZE) +else +TFTPIMAGE=/tftpboot/zImage.chrp$(MSIZE) +endif + +all: zImage + +znetboot: zImage +ifdef CONFIG_SMP + cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux.smp +else + cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux +endif +ifdef CONFIG_PPC64BRIDGE + cp -f $(TOPDIR)/vmlinux /tftpboot/vmlinux.64 +endif + cp ../images/zImage.chrp $(TFTPIMAGE) + +znetboot.initrd: zImage.initrd + cp ../images/zImage.initrd.chrp $(TFTPIMAGE) + +floppy: zImage + mcopy zImage a:zImage + +image.o: $(PIGGYBACK) ../images/vmlinux.gz + $(PIGGYBACK) image < ../images/vmlinux.gz | $(AS) -o $@ + +sysmap.o: $(PIGGYBACK) $(TOPDIR)/System.map + $(PIGGYBACK) sysmap < $(TOPDIR)/System.map | $(AS) -o $@ + +initrd.o: ../images/ramdisk.image.gz $(PIGGYBACK) + $(PIGGYBACK) initrd < ../images/ramdisk.image.gz | $(AS) -o $@ + +zImage: $(OBJS) $(LIBS) ../common/no_initrd.o $(ADDNOTE) ../images/vmlinux.gz + $(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) ../common/no_initrd.o $(LIBS) + cp ../images/$@.chrp ../images/$@.chrp-rs6k + $(ADDNOTE) ../images/$@.chrp-rs6k + +zImage.initrd: $(OBJS) $(LIBS) initrd.o $(ADDNOTE) ../images/vmlinux.gz + $(LD) $(LD_ARGS) -o ../images/$@.chrp $(OBJS) initrd.o $(LIBS) + cp ../images/$@.chrp ../images/$@.chrp-rs6k + $(ADDNOTE) ../images/$@.chrp-rs6k + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/chrp/main.c b/arch/ppc/boot/chrp/main.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/chrp/main.c Mon May 21 17:07:03 2001 @@ -0,0 +1,198 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include "nonstdio.h" +#include "zlib.h" +#include +#include +#include + +extern void *finddevice(const char *); +extern int getprop(void *, const char *, void *, int); +void gunzip(void *, int, unsigned char *, int *); + +#define RAM_START 0x00000000 +#define RAM_END (64<<20) + +#define BOOT_START ((unsigned long)_start) +#define BOOT_END ((unsigned long)(_end + 0xFFF) & ~0xFFF) + +#define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF) +#define PROG_START 0x00010000 + +char *avail_ram; +char *end_avail; + +extern char _end[]; +extern char image_data[]; +extern int image_len; +extern char initrd_data[]; +extern int initrd_len; +extern char sysmap_data[]; +extern int sysmap_len; + +static char scratch[1024<<10]; /* 1MB of scratch space for gunzip */ + +chrpboot(int a1, int a2, void *prom) +{ + int ns, oh, i; + unsigned sa, len; + void *dst; + unsigned char *im; + unsigned initrd_start, initrd_size; + extern char _start; + + printf("chrpboot starting: loaded at 0x%x\n\r", &_start); + + if (initrd_len) { + initrd_size = initrd_len; + initrd_start = (RAM_END - initrd_size) & ~0xFFF; + a1 = initrd_start; + a2 = initrd_size; + claim(initrd_start, RAM_END - initrd_start, 0); + printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n\r", + initrd_start, initrd_data, initrd_size); + memcpy((char *)initrd_start, initrd_data, initrd_size); + } + + im = image_data; + len = image_len; + /* claim 4MB starting at PROG_START */ + claim(PROG_START, (4<<20) - PROG_START, 0); + dst = (void *) PROG_START; + if (im[0] == 0x1f && im[1] == 0x8b) { + avail_ram = scratch; + end_avail = scratch + sizeof(scratch); + printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); + gunzip(dst, 0x400000, im, &len); + printf("done %u bytes\n\r", len); + } else { + memmove(dst, im, len); + } + + flush_cache(dst, len); + + sa = (unsigned long)PROG_START; + printf("start address = 0x%x\n\r", sa); + + { + struct bi_record *rec; + + rec = (struct bi_record *)_ALIGN((unsigned long)dst+len+(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; + sprintf( (char *)rec->data, "chrpboot"); + rec->size = sizeof(struct bi_record) + strlen("chrpboot") + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = _MACH_chrp; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); +#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 = (struct bi_record *)((unsigned long)rec + rec->size); +#endif + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + } + (*(void (*)())sa)(a1, a2, prom); + + printf("returned?\n\r"); + + pause(); +} + +void *zalloc(void *x, unsigned items, unsigned size) +{ + void *p = avail_ram; + + size *= items; + size = (size + 7) & -8; + avail_ram += size; + if (avail_ram > end_avail) { + printf("oops... out of memory\n\r"); + pause(); + } + return p; +} + +void zfree(void *x, void *addr, unsigned nb) +{ + nb = (nb + 7) & -8; + if (addr == (avail_ram - nb)) { + avail_ram -= nb; + } +} + +#define HEAD_CRC 2 +#define EXTRA_FIELD 4 +#define ORIG_NAME 8 +#define COMMENT 0x10 +#define RESERVED 0xe0 + +#define DEFLATED 8 + +void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) +{ + z_stream s; + int r, i, flags; + + /* skip header */ + i = 10; + flags = src[3]; + if (src[2] != DEFLATED || (flags & RESERVED) != 0) { + printf("bad gzipped data\n\r"); + exit(); + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << 8); + if ((flags & ORIG_NAME) != 0) + while (src[i++] != 0) + ; + if ((flags & COMMENT) != 0) + while (src[i++] != 0) + ; + if ((flags & HEAD_CRC) != 0) + i += 2; + if (i >= *lenp) { + printf("gunzip: ran out of data in header\n\r"); + exit(); + } + + s.zalloc = zalloc; + s.zfree = zfree; + r = inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf("inflateInit2 returned %d\n\r", r); + exit(); + } + s.next_in = src + i; + s.avail_in = *lenp - i; + s.next_out = dst; + s.avail_out = dstlen; + r = inflate(&s, Z_FINISH); + if (r != Z_OK && r != Z_STREAM_END) { + printf("inflate returned %d msg: %s\n\r", r, s.msg); + exit(); + } + *lenp = s.next_out - (unsigned char *) dst; + inflateEnd(&s); +} diff -Nru a/arch/ppc/boot/chrp/misc.S b/arch/ppc/boot/chrp/misc.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/chrp/misc.S Mon May 21 17:07:04 2001 @@ -0,0 +1,53 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + .text + +/* + * Use the BAT0 registers to map the 1st 8MB of RAM to 0x90000000. + */ + .globl setup_bats +setup_bats: + mfpvr 3 + rlwinm 3,3,16,16,31 /* r3 = 1 for 601, 4 for 604 */ + cmpi 0,3,1 + lis 4,0x9000 + bne 4f + ori 4,4,4 /* set up BAT registers for 601 */ + li 5,0x7f + b 5f +4: ori 4,4,0xff /* set up BAT registers for 604 */ + li 5,2 + mtdbatu 3,4 + mtdbatl 3,5 +5: mtibatu 3,4 + mtibatl 3,5 + isync + blr + +/* + * Flush the dcache and invalidate the icache for a range of addresses. + * + * flush_cache(addr, len) + */ + .global flush_cache +flush_cache: + addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ + rlwinm. 4,4,27,5,31 + mtctr 4 + beqlr +1: dcbf 0,3 + icbi 0,3 + addi 3,3,0x20 + bdnz 1b + sync + isync + blr diff -Nru a/arch/ppc/boot/chrp/start.c b/arch/ppc/boot/chrp/start.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/chrp/start.c Mon May 21 17:07:03 2001 @@ -0,0 +1,308 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include + +int (*prom)(); + +void *chosen_handle; +void *stdin; +void *stdout; +void *stderr; + +void exit(void); +void *finddevice(const char *name); +int getprop(void *phandle, const char *name, void *buf, int buflen); + +void printk(char *fmt, ...); + +void +start(int a1, int a2, void *promptr) +{ + prom = (int (*)()) promptr; + chosen_handle = finddevice("/chosen"); + if (chosen_handle == (void *) -1) + exit(); + if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) + exit(); + stderr = stdout; + if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) + exit(); + + chrpboot(a1, a2, promptr); + for (;;) + exit(); +} + +int +write(void *handle, void *ptr, int nb) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *ihandle; + void *addr; + int len; + int actual; + } args; + + args.service = "write"; + args.nargs = 3; + args.nret = 1; + args.ihandle = handle; + args.addr = ptr; + args.len = nb; + args.actual = -1; + (*prom)(&args); + return args.actual; +} + +int +read(void *handle, void *ptr, int nb) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *ihandle; + void *addr; + int len; + int actual; + } args; + + args.service = "read"; + args.nargs = 3; + args.nret = 1; + args.ihandle = handle; + args.addr = ptr; + args.len = nb; + args.actual = -1; + (*prom)(&args); + return args.actual; +} + +void +exit() +{ + struct prom_args { + char *service; + } args; + + for (;;) { + args.service = "exit"; + (*prom)(&args); + } +} + +void +pause() +{ + struct prom_args { + char *service; + } args; + + args.service = "enter"; + (*prom)(&args); +} + +void * +finddevice(const char *name) +{ + struct prom_args { + char *service; + int nargs; + int nret; + const char *devspec; + void *phandle; + } args; + + args.service = "finddevice"; + args.nargs = 1; + args.nret = 1; + args.devspec = name; + args.phandle = (void *) -1; + (*prom)(&args); + return args.phandle; +} + +void * +claim(unsigned int virt, unsigned int size, unsigned int align) +{ + struct prom_args { + char *service; + int nargs; + int nret; + unsigned int virt; + unsigned int size; + unsigned int align; + void *ret; + } args; + + args.service = "claim"; + args.nargs = 3; + args.nret = 1; + args.virt = virt; + args.size = size; + args.align = align; + (*prom)(&args); + return args.ret; +} + +int +getprop(void *phandle, const char *name, void *buf, int buflen) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *phandle; + const char *name; + void *buf; + int buflen; + int size; + } args; + + args.service = "getprop"; + args.nargs = 4; + args.nret = 1; + args.phandle = phandle; + args.name = name; + args.buf = buf; + args.buflen = buflen; + args.size = -1; + (*prom)(&args); + return args.size; +} + +int +putc(int c, void *f) +{ + char ch = c; + + if (c == '\n') + putc('\r', f); + return write(f, &ch, 1) == 1? c: -1; +} + +int +putchar(int c) +{ + return putc(c, stdout); +} + +int +fputs(char *str, void *f) +{ + int n = strlen(str); + + return write(f, str, n) == n? 0: -1; +} + +int +readchar() +{ + char ch; + + for (;;) { + switch (read(stdin, &ch, 1)) { + case 1: + return ch; + case -1: + printk("read(stdin) returned -1\r\n"); + return -1; + } + } +} + +static char line[256]; +static char *lineptr; +static int lineleft; + +int +getchar() +{ + int c; + + if (lineleft == 0) { + lineptr = line; + for (;;) { + c = readchar(); + if (c == -1 || c == 4) + break; + if (c == '\r' || c == '\n') { + *lineptr++ = '\n'; + putchar('\n'); + break; + } + switch (c) { + case 0177: + case '\b': + if (lineptr > line) { + putchar('\b'); + putchar(' '); + putchar('\b'); + --lineptr; + } + break; + case 'U' & 0x1F: + while (lineptr > line) { + putchar('\b'); + putchar(' '); + putchar('\b'); + --lineptr; + } + break; + default: + if (lineptr >= &line[sizeof(line) - 1]) + putchar('\a'); + else { + putchar(c); + *lineptr++ = c; + } + } + } + lineleft = lineptr - line; + lineptr = line; + } + if (lineleft == 0) + return -1; + --lineleft; + return *lineptr++; +} + +extern int vsprintf(char *buf, const char *fmt, va_list args); +static char sprint_buf[1024]; + +void +printk(char *fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vsprintf(sprint_buf, fmt, args); + va_end(args); + write(stdout, sprint_buf, n); +} + +int +printf(char *fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vsprintf(sprint_buf, fmt, args); + va_end(args); + write(stdout, sprint_buf, n); + return n; +} diff -Nru a/arch/ppc/boot/common/Makefile b/arch/ppc/boot/common/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/common/Makefile Mon May 21 17:07:05 2001 @@ -0,0 +1,27 @@ +# +# arch/ppc/boot/common/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Tom Rini January 2001 +# + +.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 $< + +OBJCOPY_ARGS = -O elf32-powerpc + +coffcrt0.o: + $(CC) $(AFLAGS) -DXCOFF -traditional -c -o coffcrt0.o crt0.S + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/common/crt0.S b/arch/ppc/boot/common/crt0.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/common/crt0.S Mon May 21 17:07:04 2001 @@ -0,0 +1,84 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* Copyright (c) 1997 Paul Mackerras + * Initial Power Macintosh COFF version. + * Copyright (c) 1999 Grant Erickson + * Modifications for IBM PowerPC 400-class processor evaluation + * boards. + * + * Module name: crt0.S + * + * Description: + * Boot loader execution entry point. Clears out .bss section as per + * ANSI C requirements. Invalidates and flushes the caches over the + * range covered by the boot loader's .text section. Sets up a stack + * below the .text section entry point. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include "../../kernel/ppc_asm.tmpl" + + .text + + .globl _start +_start: +#ifdef XCOFF + .long __start,0,0 + + .globl __start +__start: +#endif +#ifdef CONFIG_4xx + ## Clear out the BSS as per ANSI C requirements + + lis r7,_end@ha + addi r7,r7,_end@l # r7 = &_end + lis r8,__bss_start@ha # + addi r8,r8,__bss_start@l # r8 = &_bss_start + + ## Determine how large an area, in number of words, to clear + + subf r7,r8,r7 # r7 = &_end - &_bss_start + 1 + addi r7,r7,3 # r7 += 3 + srwi. r7,r7,2 # r7 = size in words. + beq 2f # If the size is zero, do not bother + addi r8,r8,-4 # r8 -= 4 + mtctr r7 # SPRN_CTR = number of words to clear + li r0,0 # r0 = 0 +1: stwu r0,4(r8) # Clear out a word + bdnz 1b # If we are not done yet, keep clearing +#endif + + ## Flush and invalidate the caches for the range in memory covering + ## the .text section of the boot loader + +2: lis r9,_start@h # r9 = &_start + lis r8,_etext@ha # + addi r8,r8,_etext@l # r8 = &_etext +3: dcbf r0,r9 # Flush the data cache + icbi r0,r9 # Invalidate the instruction cache + addi r9,r9,0x10 # Increment by one cache line + cmplw cr0,r9,r8 # Are we at the end yet? + blt 3b # No, keep flushing and invalidating + sync # sync ; isync after flushing the icache + isync + +#ifdef CONFIG_4xx + ## Set up the stack + + lis r9,_start@h # r9 = &_start (text section entry) + addi r9,r9,_start@l + subi r1,r9,64 # Start the stack 64 bytes below _start + clrrwi r1,r1,4 # Make sure it is aligned on 16 bytes. + li r0,0 + stwu r0,-16(r1) + mtlr r9 +#endif + + b start # All done, start the real work. diff -Nru a/arch/ppc/boot/common/misc-common.c b/arch/ppc/boot/common/misc-common.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/common/misc-common.c Mon May 21 17:07:05 2001 @@ -0,0 +1,539 @@ +/* + * arch/ppc/boot/common/misc-common.c + * + * Misc. bootloader code (almost) all platforms can use + * + * Author: Johnnie Peters + * Editor: Tom Rini + * + * 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 + +/* 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 +extern void cursor(int x, int y); +extern void scroll(void); +extern char *vidmem; +extern int lines, cols; +extern int orig_x, orig_y; +extern int keyb_present; +extern int CRT_tstc(void); +extern int CRT_getc(void); +#else +int cursor(int x, int y) {return 0;} +void scroll(void) {} +char vidmem[1]; +#define lines 0 +#define cols 0 +int orig_x = 0; +int orig_y = 0; +#define keyb_present 0 +int CRT_tstc(void) {return 0;} +int CRT_getc(void) {return 0;} +#endif + +extern char *avail_ram; +extern char *end_avail; +extern char _end[]; + +void puts(const char *); +void putc(const char c); +void puthex(unsigned long val); +void _bcopy(char *src, char *dst, int len); +void gunzip(void *, int, unsigned char *, int *); +static int _cvt(unsigned long val, char *buf, long radix, char *digits); + +void _vprintk(void(*)(const char), const char *, va_list); + +#if defined(CONFIG_SERIAL_CONSOLE) +struct NS16550 *com_port; + +int serial_tstc(volatile struct NS16550 *); +unsigned char serial_getc(volatile struct NS16550 *); +void serial_putc(volatile struct NS16550 *, unsigned char); +#endif + +void pause(void) +{ + puts("pause\n"); +} + +void exit(void) +{ + puts("exit\n"); + while(1); +} + +int tstc(void) +{ +#if defined(CONFIG_SERIAL_CONSOLE) + if(keyb_present) + return (CRT_tstc() || serial_tstc(com_port)); + else + return (serial_tstc(com_port)); +#else + return CRT_tstc(); +#endif +} + +int getc(void) +{ + while (1) { +#if defined(CONFIG_SERIAL_CONSOLE) + if (serial_tstc(com_port)) + return (serial_getc(com_port)); +#endif /* CONFIG_SERIAL_CONSOLE */ + if (keyb_present) + if(CRT_tstc()) + return (CRT_getc()); + } +} + +void +putc(const char c) +{ + int x,y; + +#if defined(CONFIG_SERIAL_CONSOLE) + serial_putc(com_port, c); + if ( c == '\n' ) + serial_putc(com_port, '\r'); +#endif /* CONFIG_SERIAL_CONSOLE */ + + x = orig_x; + y = orig_y; + + if ( c == '\n' ) { + x = 0; + if ( ++y >= lines ) { + scroll(); + y--; + } + } else if (c == '\r') { + x = 0; + } else if (c == '\b') { + if (x > 0) { + x--; + } + } else { + vidmem [ ( x + cols * y ) * 2 ] = c; + if ( ++x >= cols ) { + x = 0; + if ( ++y >= lines ) { + scroll(); + y--; + } + } + } + + cursor(x, y); + + orig_x = x; + orig_y = y; +} + +void puts(const char *s) +{ + int x,y; + char c; + + x = orig_x; + y = orig_y; + + while ( ( c = *s++ ) != '\0' ) { +#if defined(CONFIG_SERIAL_CONSOLE) + serial_putc(com_port, c); + if ( c == '\n' ) serial_putc(com_port, '\r'); +#endif /* CONFIG_SERIAL_CONSOLE */ + + if ( c == '\n' ) { + x = 0; + if ( ++y >= lines ) { + scroll(); + y--; + } + } else if (c == '\b') { + if (x > 0) { + x--; + } + } else { + vidmem [ ( x + cols * y ) * 2 ] = c; + if ( ++x >= cols ) { + x = 0; + if ( ++y >= lines ) { + scroll(); + y--; + } + } + } + } + + cursor(x, y); + + orig_x = x; + orig_y = y; +} + +void error(char *x) +{ + puts("\n\n"); + puts(x); + puts("\n\n -- System halted"); + + while(1); /* Halt */ +} + +void *zalloc(void *x, unsigned items, unsigned size) +{ + void *p = avail_ram; + + size *= items; + size = (size + 7) & -8; + avail_ram += size; + if (avail_ram > end_avail) { + puts("oops... out of memory\n"); + pause(); + } + return p; +} + +void zfree(void *x, void *addr, unsigned nb) +{ +} + +#define HEAD_CRC 2 +#define EXTRA_FIELD 4 +#define ORIG_NAME 8 +#define COMMENT 0x10 +#define RESERVED 0xe0 + +#define DEFLATED 8 + +void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) +{ + z_stream s; + int r, i, flags; + + /* skip header */ + i = 10; + flags = src[3]; + if (src[2] != DEFLATED || (flags & RESERVED) != 0) { + puts("bad gzipped data\n"); + exit(); + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << 8); + if ((flags & ORIG_NAME) != 0) + while (src[i++] != 0) + ; + if ((flags & COMMENT) != 0) + while (src[i++] != 0) + ; + if ((flags & HEAD_CRC) != 0) + i += 2; + if (i >= *lenp) { + puts("gunzip: ran out of data in header\n"); + exit(); + } + + s.zalloc = zalloc; + s.zfree = zfree; + r = inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + puts("inflateInit2 returned %d\n"); + exit(); + } + s.next_in = src + i; + s.avail_in = *lenp - i; + s.next_out = dst; + s.avail_out = dstlen; + r = inflate(&s, Z_FINISH); + if (r != Z_OK && r != Z_STREAM_END) { + puts("inflate returned %d\n"); + exit(); + } + *lenp = s.next_out - (unsigned char *) dst; + inflateEnd(&s); +} + +void +puthex(unsigned long val) +{ + + unsigned char buf[10]; + int i; + for (i = 7; i >= 0; i--) + { + buf[i] = "0123456789ABCDEF"[val & 0x0F]; + val >>= 4; + } + buf[8] = '\0'; + puts(buf); +} + +#define FALSE 0 +#define TRUE 1 +#include + +void +_printk(char const *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + _vprintk(putc, fmt, ap); + va_end(ap); + return; +} + +#define is_digit(c) ((c >= '0') && (c <= '9')) + +void +_vprintk(void(*putc)(const char), const char *fmt0, va_list ap) +{ + char c, sign, *cp = 0; + int left_prec, right_prec, zero_fill, length = 0, pad, pad_on_right; + char buf[32]; + long val; + while ((c = *fmt0++)) + { + if (c == '%') + { + c = *fmt0++; + left_prec = right_prec = pad_on_right = 0; + if (c == '-') + { + c = *fmt0++; + pad_on_right++; + } + if (c == '0') + { + zero_fill = TRUE; + c = *fmt0++; + } else + { + zero_fill = FALSE; + } + while (is_digit(c)) + { + left_prec = (left_prec * 10) + (c - '0'); + c = *fmt0++; + } + if (c == '.') + { + c = *fmt0++; + zero_fill++; + while (is_digit(c)) + { + right_prec = (right_prec * 10) + (c - '0'); + c = *fmt0++; + } + } else + { + right_prec = left_prec; + } + sign = '\0'; + switch (c) + { + case 'd': + case 'x': + case 'X': + val = va_arg(ap, long); + switch (c) + { + case 'd': + if (val < 0) + { + sign = '-'; + val = -val; + } + length = _cvt(val, buf, 10, "0123456789"); + break; + case 'x': + length = _cvt(val, buf, 16, "0123456789abcdef"); + break; + case 'X': + length = _cvt(val, buf, 16, "0123456789ABCDEF"); + break; + } + cp = buf; + break; + case 's': + cp = va_arg(ap, char *); + length = strlen(cp); + break; + case 'c': + c = va_arg(ap, long /*char*/); + (*putc)(c); + continue; + default: + (*putc)('?'); + } + pad = left_prec - length; + if (sign != '\0') + { + pad--; + } + if (zero_fill) + { + c = '0'; + if (sign != '\0') + { + (*putc)(sign); + sign = '\0'; + } + } else + { + c = ' '; + } + if (!pad_on_right) + { + while (pad-- > 0) + { + (*putc)(c); + } + } + if (sign != '\0') + { + (*putc)(sign); + } + while (length-- > 0) + { + (*putc)(c = *cp++); + if (c == '\n') + { + (*putc)('\r'); + } + } + if (pad_on_right) + { + while (pad-- > 0) + { + (*putc)(c); + } + } + } else + { + (*putc)(c); + if (c == '\n') + { + (*putc)('\r'); + } + } + } +} + +int +_cvt(unsigned long val, char *buf, long radix, char *digits) +{ + char temp[80]; + char *cp = temp; + int length = 0; + if (val == 0) + { /* Special case */ + *cp++ = '0'; + } else + while (val) + { + *cp++ = digits[val % radix]; + val /= radix; + } + while (cp != temp) + { + *buf++ = *--cp; + length++; + } + *buf = '\0'; + return (length); +} + +void +_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base) +{ + int i, c; + if ((unsigned int)s > (unsigned int)p) + { + s = (unsigned int)s - (unsigned int)p; + } + while (s > 0) + { + if (base) + { + _printk("%06X: ", (int)p - (int)base); + } else + { + _printk("%06X: ", p); + } + for (i = 0; i < 16; i++) + { + if (i < s) + { + _printk("%02X", p[i] & 0xFF); + } else + { + _printk(" "); + } + if ((i % 2) == 1) _printk(" "); + if ((i % 8) == 7) _printk(" "); + } + _printk(" |"); + for (i = 0; i < 16; i++) + { + if (i < s) + { + c = p[i] & 0xFF; + if ((c < 0x20) || (c >= 0x7F)) c = '.'; + } else + { + c = ' '; + } + _printk("%c", c); + } + _printk("|\n"); + s -= 16; + p += 16; + } +} + +void +_dump_buf(unsigned char *p, int s) +{ + _printk("\n"); + _dump_buf_with_offset(p, s, 0); +} + +/* + * Local variables: + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff -Nru a/arch/ppc/boot/common/misc-simple.c b/arch/ppc/boot/common/misc-simple.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/common/misc-simple.c Mon May 21 17:07:05 2001 @@ -0,0 +1,182 @@ +/* + * arch/ppc/common/misc-simple.c + * + * Misc. bootloader code for many machines. This assumes you have are using + * a 6xx/7xx/74xx CPU in your machine. This assumes the chunk of memory + * below 8MB is free. Finally, it assumes you have a NS16550-style uart for + * your serial console. If a machine meets these requirements, it can quite + * likely use this code during boot. + * + * Author: Matt Porter + * Derived from arch/ppc/boot/prep/misc.c + * + * 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 "zlib.h" + +unsigned long com_port; + +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 puts(const char *); +extern void putc(const char c); +extern void puthex(unsigned long val); +extern void *memcpy(void * __dest, __const void * __src, + __kernel_size_t __n); +extern void gunzip(void *, int, unsigned char *, int *); +extern void udelay(long delay); +extern int tstc(void); +extern int getc(void); +extern volatile unsigned long serial_init(int chan); + +void +decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum) +{ + + int timer = 0; + extern unsigned long start; + char *cp, ch; + + com_port = serial_init(0); + + /* 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"); + if ( (unsigned long)load_addr != (unsigned long)&start ) + { + puts("relocated to: "); puthex((unsigned long)&start); + puts(" "); + puthex((unsigned long)((unsigned long)&start + (4*num_words))); + puts("\n"); + } + + /* we have to subtract 0x10000 here to correct for objdump including + the size of the elf header which we strip -- Cort */ + zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET); + zimage_size = ZIMAGE_SIZE; + + if ( INITRD_OFFSET ) + initrd_start = load_addr - 0x10000 + INITRD_OFFSET; + else + initrd_start = 0; + initrd_end = INITRD_SIZE + initrd_start; + + /* + * Find a place to stick the zimage and initrd and + * relocate them if we have to. -- Cort + */ + avail_ram = (char *)PAGE_ALIGN((unsigned long)_end); + puts("zimage at: "); puthex((unsigned long)zimage_start); + puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n"); + if ( (unsigned long)zimage_start <= 0x00800000 ) + { + memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size ); + zimage_start = (char *)avail_ram; + puts("relocated to: "); puthex((unsigned long)zimage_start); + puts(" "); + puthex((unsigned long)zimage_size+(unsigned long)zimage_start); + puts("\n"); + + /* relocate initrd */ + if ( initrd_start ) + { + puts("initrd at: "); puthex(initrd_start); + puts(" "); puthex(initrd_end); puts("\n"); + avail_ram = (char *)PAGE_ALIGN( + (unsigned long)zimage_size+(unsigned long)zimage_start); + memcpy ((void *)avail_ram, (void *)initrd_start, INITRD_SIZE ); + initrd_start = (unsigned long)avail_ram; + initrd_end = initrd_start + INITRD_SIZE; + puts("relocated to: "); puthex(initrd_start); + puts(" "); puthex(initrd_end); puts("\n"); + } + } else 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: "); + 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') { + /* 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"); + } + } else { + *cp++ = ch; + putc(ch); + } + } + break; /* Exit 'timer' loop */ + } + udelay(1000); /* 1 msec */ + } + *cp = 0; + puts("\n"); + + /* mappings on early boot can only handle 16M */ + if ( (int)(cmd_line[0]) > (16<<20)) + puts("cmd_line located > 16M\n"); + if ( initrd_start > (16<<20)) + puts("initrd_start located > 16M\n"); + + puts("Uncompressing Linux..."); + + gunzip(0, 0x400000, zimage_start, &zimage_size); + puts("done.\n"); + + puts("Now booting the kernel\n"); +} diff -Nru a/arch/ppc/boot/common/no_initrd.c b/arch/ppc/boot/common/no_initrd.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/common/no_initrd.c Mon May 21 17:07:04 2001 @@ -0,0 +1,5 @@ +/* + * 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 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/common/ns16550.c Mon May 21 17:07:03 2001 @@ -0,0 +1,80 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * COM1 NS16550 support + */ + +#include +#include +#include +#include + +/* Some machines, such as ones with a PReP memory map, initally have + * their serial port at an offset of 0x80000000 from where they are + * in . This tries to take that into account. */ +#ifndef IOOFFSET +#define IOOFFSET 0 +#endif + +static struct serial_state rs_table[RS_TABLE_SIZE] = { + SERIAL_PORT_DFNS /* Defined in */ +}; + +static int shift; + +volatile unsigned long serial_init(int chan) { + unsigned long com_port; + + /* Get the base, and add any offset we need to deal with. */ + com_port = rs_table[chan].port + IOOFFSET; + + /* How far apart the registers are. */ + shift = rs_table[chan].iomem_reg_shift; + + /* See if port is present */ + *((unsigned char *)com_port + (UART_LCR << shift)) = 0x00; + *((unsigned char *)com_port + (UART_IER << shift)) = 0x00; + /* Access baud rate */ + *((unsigned char *)com_port + (UART_LCR << shift)) = 0x00; +#ifdef CONFIG_SERIAL_CONSOLE_NONSTD + /* Input clock. */ + *((unsigned char *)com_port + (UART_DLL << shift)) = + (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD); + *((unsigned char *)com_port + (UART_DLM << shift)) = + (BASE_BAUD / CONFIG_SERIAL_CONSOLE_BAUD) >> 8; +#endif + /* 8 data, 1 stop, no parity */ + *((unsigned char *)com_port + (UART_LCR << shift)) = 0x03; + /* RTS/DTR */ + *((unsigned char *)com_port + (UART_MCR << shift)) = 0x03; + /* Clear & enable FIFOs */ + *((unsigned char *)com_port + (UART_FCR << shift)) = 0x07; + + return (com_port); +} + +void +serial_putc(volatile unsigned long com_port, unsigned char c) +{ + while ((*((volatile unsigned char *)com_port + (UART_LSR << shift)) & + UART_LSR_THRE) == 0) + ; + *(volatile unsigned char *)com_port = c; +} + +unsigned char +serial_getc(volatile unsigned long com_port) +{ + while ((*((volatile unsigned char *)com_port + (UART_LSR << shift)) + & UART_LSR_DR) == 0) + ; + return (*(volatile unsigned char *)com_port); +} + +int +serial_tstc(volatile unsigned long com_port) +{ + return ((*((volatile unsigned char *)com_port + (UART_LSR << shift)) + & UART_LSR_DR) != 0); +} diff -Nru a/arch/ppc/boot/common/string.S b/arch/ppc/boot/common/string.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/common/string.S Mon May 21 17:07:04 2001 @@ -0,0 +1,153 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * String handling functions for PowerPC. + * + * Copyright (C) 1996 Paul Mackerras. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#define r0 0 +#define r3 3 +#define r4 4 +#define r5 5 +#define r6 6 +#define r7 7 +#define r8 8 + + .globl strlen +strlen: + addi r4,r3,-1 +1: lbzu r0,1(r4) + cmpwi 0,r0,0 + bne 1b + subf r3,r3,r4 + blr + + .globl memset +memset: + rlwimi r4,r4,8,16,23 + rlwimi r4,r4,16,0,15 + addi r6,r3,-4 + cmplwi 0,r5,4 + blt 7f + stwu r4,4(r6) + beqlr + andi. r0,r6,3 + add r5,r0,r5 + subf r6,r0,r6 + rlwinm r0,r5,32-2,2,31 + mtctr r0 + bdz 6f +1: stwu r4,4(r6) + bdnz 1b +6: andi. r5,r5,3 +7: cmpwi 0,r5,0 + beqlr + mtctr r5 + addi r6,r6,3 +8: stbu r4,1(r6) + bdnz 8b + blr + + .globl memmove +memmove: + cmplw 0,r3,r4 + bgt backwards_memcpy + /* fall through */ + + .globl memcpy +memcpy: + rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ + addi r6,r3,-4 + addi r4,r4,-4 + beq 2f /* if less than 8 bytes to do */ + andi. r0,r6,3 /* get dest word aligned */ + mtctr r7 + bne 5f +1: lwz r7,4(r4) + lwzu r8,8(r4) + stw r7,4(r6) + stwu r8,8(r6) + bdnz 1b + andi. r5,r5,7 +2: cmplwi 0,r5,4 + blt 3f + lwzu r0,4(r4) + addi r5,r5,-4 + stwu r0,4(r6) +3: cmpwi 0,r5,0 + beqlr + mtctr r5 + addi r4,r4,3 + addi r6,r6,3 +4: lbzu r0,1(r4) + stbu r0,1(r6) + bdnz 4b + blr +5: subfic r0,r0,4 + mtctr r0 +6: lbz r7,4(r4) + addi r4,r4,1 + stb r7,4(r6) + addi r6,r6,1 + bdnz 6b + subf r5,r0,r5 + rlwinm. r7,r5,32-3,3,31 + beq 2b + mtctr r7 + b 1b + + .globl backwards_memcpy +backwards_memcpy: + rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ + add r6,r3,r5 + add r4,r4,r5 + beq 2f + andi. r0,r6,3 + mtctr r7 + bne 5f +1: lwz r7,-4(r4) + lwzu r8,-8(r4) + stw r7,-4(r6) + stwu r8,-8(r6) + bdnz 1b + andi. r5,r5,7 +2: cmplwi 0,r5,4 + blt 3f + lwzu r0,-4(r4) + subi r5,r5,4 + stwu r0,-4(r6) +3: cmpwi 0,r5,0 + beqlr + mtctr r5 +4: lbzu r0,-1(r4) + stbu r0,-1(r6) + bdnz 4b + blr +5: mtctr r0 +6: lbzu r7,-1(r4) + stbu r7,-1(r6) + bdnz 6b + subf r5,r0,r5 + rlwinm. r7,r5,32-3,3,31 + beq 2b + mtctr r7 + b 1b + + .globl memcmp +memcmp: + cmpwi 0,r5,0 + blelr + mtctr r5 + addi r6,r3,-1 + addi r4,r4,-1 +1: lbzu r3,1(r6) + lbzu r0,1(r4) + subf. r3,r0,r3 + bdnzt 2,1b + blr diff -Nru a/arch/ppc/boot/head.S b/arch/ppc/boot/head.S --- a/arch/ppc/boot/head.S Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,238 +0,0 @@ -#include "../kernel/ppc_defs.h" -#include "../kernel/ppc_asm.tmpl" -#include -#include - - .text - -/* - * $Id: head.S,v 1.33 1999/09/08 01:06:58 cort Exp $ - * - * Boot loader philosophy: - * ROM loads us to some arbitrary location - * Move the boot code to the link address (8M) - * Call decompress_kernel() - * Relocate the initrd, zimage and residual data to 8M - * Decompress the kernel to 0 - * Jump to the kernel entry - * -- Cort - */ - .globl start -start: - bl start_ -start_: - mr r11,r3 /* Save pointer to residual/board data */ - mr r25,r5 /* Save OFW pointer */ - li r3,MSR_IP /* Establish default MSR value */ - mtmsr r3 - -/* 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 */ - 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 -/* Run loader */ - mr r3,r8 /* Load point */ - mr r4,r7 /* Program length */ - mr r5,r6 /* Checksum */ - mr r6,r11 /* Residual data */ - mr r7,r25 /* OFW interfaces */ - bl decompress_kernel - - /* changed to use r3 (as firmware does) for kernel - as ptr to residual -- Cort*/ - 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 - - /* tell kernel we're prep */ - /* - * get start address of kernel code which is stored as a coff - * entry. see boot/head.S -- Cort - */ - li r9,0x4 - mtlr r9 - lis r10,0xdeadc0de@h - ori r10,r10,0xdeadc0de@l - li r9,0 - stw r10,0(r9) -/* - * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2 - * so disable BATs before setting this to avoid a clash - */ - li r8,0 - mtspr DBAT0U,r8 - mtspr DBAT1U,r8 - mtspr DBAT2U,r8 - mtspr DBAT3U,r8 - mtspr IBAT0U,r8 - mtspr IBAT1U,r8 - mtspr IBAT2U,r8 - mtspr IBAT3U,r8 - - 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/images/Makefile b/arch/ppc/boot/images/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/images/Makefile Mon May 21 17:07:05 2001 @@ -0,0 +1,12 @@ +# +# This dir holds all of the images for PPC machines. +# Tom Rini January 2001 + +include $(TOPDIR)/Rules.make + +vmlinux.gz: $(TOPDIR)/vmlinux + $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux + gzip -vf9 vmlinux + +clean: + rm -f sImage vmapus vmlinux.* miboot.image* zImage* zvmlinux.* diff -Nru a/arch/ppc/boot/include/nonstdio.h b/arch/ppc/boot/include/nonstdio.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/include/nonstdio.h Mon May 21 17:07:03 2001 @@ -0,0 +1,21 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +typedef int FILE; +extern FILE *stdin, *stdout; +#define NULL ((void *)0) +#define EOF (-1) +#define fopen(n, m) NULL +#define fflush(f) 0 +#define fclose(f) 0 +extern char *fgets(); + +#define perror(s) printf("%s: no files!\n", (s)) diff -Nru a/arch/ppc/boot/include/rs6000.h b/arch/ppc/boot/include/rs6000.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/include/rs6000.h Mon May 21 17:07:04 2001 @@ -0,0 +1,246 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* IBM RS/6000 "XCOFF" file definitions for BFD. + Copyright (C) 1990, 1991 Free Software Foundation, Inc. + FIXME: Can someone provide a transliteration of this name into ASCII? + Using the following chars caused a compiler warning on HIUX (so I replaced + them with octal escapes), and isn't useful without an understanding of what + character set it is. + Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM + and John Gilmore of Cygnus Support. */ + +/********************** FILE HEADER **********************/ + +struct external_filehdr { + char f_magic[2]; /* magic number */ + char f_nscns[2]; /* number of sections */ + char f_timdat[4]; /* time & date stamp */ + char f_symptr[4]; /* file pointer to symtab */ + char f_nsyms[4]; /* number of symtab entries */ + char f_opthdr[2]; /* sizeof(optional hdr) */ + char f_flags[2]; /* flags */ +}; + + /* IBM RS/6000 */ +#define U802WRMAGIC 0730 /* writeable text segments **chh** */ +#define U802ROMAGIC 0735 /* readonly sharable text segments */ +#define U802TOCMAGIC 0737 /* readonly text segments and TOC */ + +#define BADMAG(x) \ + ((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \ + (x).f_magic != U802TOCMAGIC) + +#define FILHDR struct external_filehdr +#define FILHSZ 20 + + +/********************** AOUT "OPTIONAL HEADER" **********************/ + + +typedef struct +{ + unsigned char magic[2]; /* type of file */ + unsigned char vstamp[2]; /* version stamp */ + unsigned char tsize[4]; /* text size in bytes, padded to FW bdry */ + unsigned char dsize[4]; /* initialized data " " */ + unsigned char bsize[4]; /* uninitialized data " " */ + unsigned char entry[4]; /* entry pt. */ + unsigned char text_start[4]; /* base of text used for this file */ + unsigned char data_start[4]; /* base of data used for this file */ + unsigned char o_toc[4]; /* address of TOC */ + unsigned char o_snentry[2]; /* section number of entry point */ + unsigned char o_sntext[2]; /* section number of .text section */ + unsigned char o_sndata[2]; /* section number of .data section */ + unsigned char o_sntoc[2]; /* section number of TOC */ + unsigned char o_snloader[2]; /* section number of .loader section */ + unsigned char o_snbss[2]; /* section number of .bss section */ + unsigned char o_algntext[2]; /* .text alignment */ + unsigned char o_algndata[2]; /* .data alignment */ + unsigned char o_modtype[2]; /* module type (??) */ + unsigned char o_cputype[2]; /* cpu type */ + unsigned char o_maxstack[4]; /* max stack size (??) */ + unsigned char o_maxdata[4]; /* max data size (??) */ + unsigned char o_resv2[12]; /* reserved */ +} +AOUTHDR; + +#define AOUTSZ 72 +#define SMALL_AOUTSZ (28) +#define AOUTHDRSZ 72 + +#define RS6K_AOUTHDR_OMAGIC 0x0107 /* old: text & data writeable */ +#define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */ +#define RS6K_AOUTHDR_ZMAGIC 0x010B /* paged: text r/o, both page-aligned */ + + +/********************** SECTION HEADER **********************/ + + +struct external_scnhdr { + char s_name[8]; /* section name */ + char s_paddr[4]; /* physical address, aliased s_nlib */ + char s_vaddr[4]; /* virtual address */ + char s_size[4]; /* section size */ + char s_scnptr[4]; /* file ptr to raw data for section */ + char s_relptr[4]; /* file ptr to relocation */ + char s_lnnoptr[4]; /* file ptr to line numbers */ + char s_nreloc[2]; /* number of relocation entries */ + char s_nlnno[2]; /* number of line number entries*/ + char s_flags[4]; /* flags */ +}; + +/* + * names of "special" sections + */ +#define _TEXT ".text" +#define _DATA ".data" +#define _BSS ".bss" +#define _PAD ".pad" +#define _LOADER ".loader" + +#define SCNHDR struct external_scnhdr +#define SCNHSZ 40 + +/* XCOFF uses a special .loader section with type STYP_LOADER. */ +#define STYP_LOADER 0x1000 + +/* XCOFF uses a special .debug section with type STYP_DEBUG. */ +#define STYP_DEBUG 0x2000 + +/* XCOFF handles line number or relocation overflow by creating + another section header with STYP_OVRFLO set. */ +#define STYP_OVRFLO 0x8000 + +/********************** LINE NUMBERS **********************/ + +/* 1 line number entry for every "breakpointable" source line in a section. + * Line numbers are grouped on a per function basis; first entry in a function + * grouping will have l_lnno = 0 and in place of physical address will be the + * symbol table index of the function name. + */ +struct external_lineno { + union { + char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ + char l_paddr[4]; /* (physical) address of line number */ + } l_addr; + char l_lnno[2]; /* line number */ +}; + + +#define LINENO struct external_lineno +#define LINESZ 6 + + +/********************** SYMBOLS **********************/ + +#define E_SYMNMLEN 8 /* # characters in a symbol name */ +#define E_FILNMLEN 14 /* # characters in a file name */ +#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ + +struct external_syment +{ + union { + char e_name[E_SYMNMLEN]; + struct { + char e_zeroes[4]; + char e_offset[4]; + } e; + } e; + char e_value[4]; + char e_scnum[2]; + char e_type[2]; + char e_sclass[1]; + char e_numaux[1]; +}; + + + +#define N_BTMASK (017) +#define N_TMASK (060) +#define N_BTSHFT (4) +#define N_TSHIFT (2) + + +union external_auxent { + struct { + char x_tagndx[4]; /* str, un, or enum tag indx */ + union { + struct { + char x_lnno[2]; /* declaration line number */ + char x_size[2]; /* str/union/array size */ + } x_lnsz; + char x_fsize[4]; /* size of function */ + } x_misc; + union { + struct { /* if ISFCN, tag, or .bb */ + char x_lnnoptr[4]; /* ptr to fcn line # */ + char x_endndx[4]; /* entry ndx past block end */ + } x_fcn; + struct { /* if ISARY, up to 4 dimen. */ + char x_dimen[E_DIMNUM][2]; + } x_ary; + } x_fcnary; + char x_tvndx[2]; /* tv index */ + } x_sym; + + union { + char x_fname[E_FILNMLEN]; + struct { + char x_zeroes[4]; + char x_offset[4]; + } x_n; + } x_file; + + struct { + char x_scnlen[4]; /* section length */ + char x_nreloc[2]; /* # relocation entries */ + char x_nlinno[2]; /* # line numbers */ + } x_scn; + + struct { + char x_tvfill[4]; /* tv fill value */ + char x_tvlen[2]; /* length of .tv */ + char x_tvran[2][2]; /* tv range */ + } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ + + struct { + unsigned char x_scnlen[4]; + unsigned char x_parmhash[4]; + unsigned char x_snhash[2]; + unsigned char x_smtyp[1]; + unsigned char x_smclas[1]; + unsigned char x_stab[4]; + unsigned char x_snstab[2]; + } x_csect; + +}; + +#define SYMENT struct external_syment +#define SYMESZ 18 +#define AUXENT union external_auxent +#define AUXESZ 18 +#define DBXMASK 0x80 /* for dbx storage mask */ +#define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK) + + + +/********************** RELOCATION DIRECTIVES **********************/ + + +struct external_reloc { + char r_vaddr[4]; + char r_symndx[4]; + char r_size[1]; + char r_type[1]; +}; + + +#define RELOC struct external_reloc +#define RELSZ 10 + +#define DEFAULT_DATA_SECTION_ALIGNMENT 4 +#define DEFAULT_BSS_SECTION_ALIGNMENT 4 +#define DEFAULT_TEXT_SECTION_ALIGNMENT 4 +/* For new sections we havn't heard of before */ +#define DEFAULT_SECTION_ALIGNMENT 4 diff -Nru a/arch/ppc/boot/include/zlib.h b/arch/ppc/boot/include/zlib.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/include/zlib.h Mon May 21 17:07:03 2001 @@ -0,0 +1,433 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * This file is derived from zlib.h and zconf.h from the zlib-0.95 + * distribution by Jean-loup Gailly and Mark Adler, with some additions + * by Paul Mackerras to aid in implementing Deflate compression and + * decompression for PPP packets. + */ + +/* + * ==FILEVERSION 960122== + * + * This marker is used by the Linux installation script to determine + * whether an up-to-date version of this file is already installed. + */ + +/* zlib.h -- interface of the 'zlib' general purpose compression library + version 0.95, Aug 16th, 1995. + + Copyright (C) 1995 Jean-loup Gailly and Mark Adler + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + Jean-loup Gailly Mark Adler + gzip@prep.ai.mit.edu madler@alumni.caltech.edu + */ + +#ifndef _ZLIB_H +#define _ZLIB_H + +/* #include "zconf.h" */ /* included directly here */ + +/* zconf.h -- configuration of the zlib compression library + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ + +/* + The library does not install any signal handler. It is recommended to + add at least a handler for SIGSEGV when decompressing; the library checks + the consistency of the input data whenever possible but may go nuts + for some forms of corrupted input. + */ + +/* + * Compile with -DMAXSEG_64K if the alloc function cannot allocate more + * than 64k bytes at a time (needed on systems with 16-bit int). + * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints + * at addresses which are not a multiple of their size. + * Under DOS, -DFAR=far or -DFAR=__far may be needed. + */ + +#ifndef STDC +# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) +# define STDC +# endif +#endif + +#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ +# include +#endif + +/* Maximum value for memLevel in deflateInit2 */ +#ifndef MAX_MEM_LEVEL +# ifdef MAXSEG_64K +# define MAX_MEM_LEVEL 8 +# else +# define MAX_MEM_LEVEL 9 +# endif +#endif + +#ifndef FAR +# define FAR +#endif + +/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ +#ifndef MAX_WBITS +# define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* The memory requirements for deflate are (in bytes): + 1 << (windowBits+2) + 1 << (memLevel+9) + that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) + plus a few kilobytes for small objects. For example, if you want to reduce + the default memory requirements from 256K to 128K, compile with + make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" + Of course this will generally degrade compression (there's no free lunch). + + The memory requirements for inflate are (in bytes) 1 << windowBits + that is, 32K for windowBits=15 (default value) plus a few kilobytes + for small objects. +*/ + + /* Type declarations */ + +#ifndef OF /* function prototypes */ +# ifdef STDC +# define OF(args) args +# else +# define OF(args) () +# endif +#endif + +typedef unsigned char Byte; /* 8 bits */ +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ + +typedef Byte FAR Bytef; +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; +typedef uLong FAR uLongf; + +#ifdef STDC + typedef void FAR *voidpf; + typedef void *voidp; +#else + typedef Byte FAR *voidpf; + typedef Byte *voidp; +#endif + +/* end of original zconf.h */ + +#define ZLIB_VERSION "0.95P" + +/* + The 'zlib' compression library provides in-memory compression and + decompression functions, including integrity checks of the uncompressed + data. This version of the library supports only one compression method + (deflation) but other algorithms may be added later and will have the same + stream interface. + + For compression the application must provide the output buffer and + may optionally provide the input buffer for optimization. For decompression, + the application must provide the input buffer and may optionally provide + the output buffer for optimization. + + Compression can be done in a single step if the buffers are large + enough (for example if an input file is mmap'ed), or can be done by + repeated calls of the compression function. In the latter case, the + application must provide more input and/or consume the output + (providing more output space) before each call. +*/ + +typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); +typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); + +struct internal_state; + +typedef struct z_stream_s { + Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total nb of input bytes read so far */ + + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total nb of bytes output so far */ + + char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ + + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidp opaque; /* private data object passed to zalloc and zfree */ + + Byte data_type; /* best guess about the data type: ascii or binary */ + +} z_stream; + +/* + The application must update next_in and avail_in when avail_in has + dropped to zero. It must update next_out and avail_out when avail_out + has dropped to zero. The application must initialize zalloc, zfree and + opaque before calling the init function. All other fields are set by the + compression library and must not be updated by the application. + + The opaque value provided by the application will be passed as the first + parameter for calls of zalloc and zfree. This can be useful for custom + memory management. The compression library attaches no meaning to the + opaque value. + + zalloc must return Z_NULL if there is not enough memory for the object. + On 16-bit systems, the functions zalloc and zfree must be able to allocate + exactly 65536 bytes, but will not be required to allocate more than this + if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, + pointers returned by zalloc for objects of exactly 65536 bytes *must* + have their offset normalized to zero. The default allocation function + provided by this library ensures this (see zutil.c). To reduce memory + requirements and avoid any allocation of 64K objects, at the expense of + compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). + + The fields total_in and total_out can be used for statistics or + progress reports. After compression, total_in holds the total size of + the uncompressed data and may be saved for use in the decompressor + (particularly if the decompressor wants to decompress everything in + a single step). +*/ + + /* constants */ + +#define Z_NO_FLUSH 0 +#define Z_PARTIAL_FLUSH 1 +#define Z_FULL_FLUSH 2 +#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ +#define Z_FINISH 4 +#define Z_PACKET_FLUSH 5 +/* See deflate() below for the usage of these constants */ + +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) +/* error codes for the compression/decompression functions */ + +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) +/* compression levels */ + +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_DEFAULT_STRATEGY 0 + +#define Z_BINARY 0 +#define Z_ASCII 1 +#define Z_UNKNOWN 2 +/* Used to set the data_type field */ + +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ + +extern char *zlib_version; +/* The application can compare zlib_version and ZLIB_VERSION for consistency. + If the first character differs, the library code actually used is + not compatible with the zlib.h header file used by the application. + */ + + /* basic functions */ + +extern int inflateInit OF((z_stream *strm)); +/* + Initializes the internal stream state for decompression. The fields + zalloc and zfree must be initialized before by the caller. If zalloc and + zfree are set to Z_NULL, inflateInit updates them to use default allocation + functions. + + inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not + enough memory. msg is set to null if there is no error message. + inflateInit does not perform any decompression: this will be done by + inflate(). +*/ + + +extern int inflate OF((z_stream *strm, int flush)); +/* + Performs one or both of the following actions: + + - Decompress more input starting at next_in and update next_in and avail_in + accordingly. If not all input can be processed (because there is not + enough room in the output buffer), next_in is updated and processing + will resume at this point for the next call of inflate(). + + - Provide more output starting at next_out and update next_out and avail_out + accordingly. inflate() always provides as much output as possible + (until there is no more input data or no more space in the output buffer). + + Before the call of inflate(), the application should ensure that at least + one of the actions is possible, by providing more input and/or consuming + more output, and updating the next_* and avail_* values accordingly. + The application can consume the uncompressed output when it wants, for + example when the output buffer is full (avail_out == 0), or after each + call of inflate(). + + If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, + inflate flushes as much output as possible to the output buffer. The + flushing behavior of inflate is not specified for values of the flush + parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the + current implementation actually flushes as much output as possible + anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data + has been consumed, it is expecting to see the length field of a stored + block; if not, it returns Z_DATA_ERROR. + + inflate() should normally be called until it returns Z_STREAM_END or an + error. However if all decompression is to be performed in a single step + (a single call of inflate), the parameter flush should be set to + Z_FINISH. In this case all pending input is processed and all pending + output is flushed; avail_out must be large enough to hold all the + uncompressed data. (The size of the uncompressed data may have been saved + by the compressor for this purpose.) The next operation on this stream must + be inflateEnd to deallocate the decompression state. The use of Z_FINISH + is never required, but can be used to inform inflate that a faster routine + may be used for the single inflate() call. + + inflate() returns Z_OK if some progress has been made (more input + processed or more output produced), Z_STREAM_END if the end of the + compressed data has been reached and all uncompressed output has been + produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if + the stream structure was inconsistent (for example if next_in or next_out + was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no + progress is possible or if there was not enough room in the output buffer + when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then + call inflateSync to look for a good compression block. */ + + +extern int inflateEnd OF((z_stream *strm)); +/* + All dynamically allocated data structures for this stream are freed. + This function discards any unprocessed input and does not flush any + pending output. + + inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state + was inconsistent. In the error case, msg may be set but then points to a + static string (which must not be deallocated). +*/ + + /* advanced functions */ + +extern int inflateInit2 OF((z_stream *strm, + int windowBits)); +/* + This is another version of inflateInit with more compression options. The + fields next_out, zalloc and zfree must be initialized before by the caller. + + The windowBits parameter is the base two logarithm of the maximum window + size (the size of the history buffer). It should be in the range 8..15 for + this version of the library (the value 16 will be allowed soon). The + default value is 15 if inflateInit is used instead. If a compressed stream + with a larger window size is given as input, inflate() will return with + the error code Z_DATA_ERROR instead of trying to allocate a larger window. + + If next_out is not null, the library will use this buffer for the history + buffer; the buffer must either be large enough to hold the entire output + data, or have at least 1< - -#include <../drivers/char/defkeymap.c> /* yeah I know it's bad -- Cort */ - - -unsigned char shfts, ctls, alts, caps; - -#define KBDATAP 0x60 /* kbd data port */ -#define KBSTATUSPORT 0x61 /* kbd status */ -#define KBSTATP 0x64 /* kbd status port */ -#define KBINRDY 0x01 -#define KBOUTRDY 0x02 - - -static int kbd(int noblock) -{ - unsigned char dt, brk, val; - unsigned code; -loop: - if (noblock) { - if ((inb(KBSTATP) & KBINRDY) == 0) - return (-1); - } else while((inb(KBSTATP) & KBINRDY) == 0) ; - - dt = inb(KBDATAP); - - brk = dt & 0x80; /* brk == 1 on key release */ - dt = dt & 0x7f; /* keycode */ - - if (shfts) - code = shift_map[dt]; - else if (ctls) - code = ctrl_map[dt]; - else - code = plain_map[dt]; - - val = KVAL(code); - switch (KTYP(code) & 0x0f) { - case KT_LATIN: - if (brk) - break; - if (alts) - val |= 0x80; - if (val == 0x7f) /* map delete to backspace */ - val = '\b'; - return val; - - case KT_LETTER: - if (brk) - break; - if (caps) - val -= 'a'-'A'; - return val; - - case KT_SPEC: - if (brk) - break; - if (val == KVAL(K_CAPS)) - caps = !caps; - else if (val == KVAL(K_ENTER)) { -enter: /* Wait for key up */ - while (1) { - while((inb(KBSTATP) & KBINRDY) == 0) ; - dt = inb(KBDATAP); - if (dt & 0x80) /* key up */ break; - } - return 10; - } - break; - - case KT_PAD: - if (brk) - break; - if (val < 10) - return val; - if (val == KVAL(K_PENTER)) - goto enter; - break; - - case KT_SHIFT: - switch (val) { - case KG_SHIFT: - case KG_SHIFTL: - case KG_SHIFTR: - shfts = brk ? 0 : 1; - break; - case KG_ALT: - case KG_ALTGR: - alts = brk ? 0 : 1; - break; - case KG_CTRL: - case KG_CTRLL: - case KG_CTRLR: - ctls = brk ? 0 : 1; - break; - } - break; - - case KT_LOCK: - switch (val) { - case KG_SHIFT: - case KG_SHIFTL: - case KG_SHIFTR: - if (brk) - shfts = !shfts; - break; - case KG_ALT: - case KG_ALTGR: - if (brk) - alts = !alts; - break; - case KG_CTRL: - case KG_CTRLL: - case KG_CTRLR: - if (brk) - ctls = !ctls; - break; - } - break; - } - if (brk) return (-1); /* Ignore initial 'key up' codes */ - goto loop; -} - -static void kbdreset(void) -{ - unsigned char c; - int i; - - /* flush input queue */ - while ((inb(KBSTATP) & KBINRDY)) - { - (void)inb(KBDATAP); - } - /* Send self-test */ - while (inb(KBSTATP) & KBOUTRDY) ; - outb(KBSTATP,0xAA); - while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */ - if ((c = inb(KBDATAP)) != 0x55) - { - puts("Keyboard self test failed - result:"); - puthex(c); - puts("\n"); - } - /* Enable interrupts and keyboard controller */ - while (inb(KBSTATP) & KBOUTRDY) ; - outb(KBSTATP,0x60); - while (inb(KBSTATP) & KBOUTRDY) ; - outb(KBDATAP,0x45); - for (i = 0; i < 10000; i++) udelay(1); - - while (inb(KBSTATP) & KBOUTRDY) ; - outb(KBSTATP,0x20); - while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */ - if (! (inb(KBDATAP) & 0x40)) { - /* - * Quote from PS/2 System Reference Manual: - * - * "Address hex 0060 and address hex 0064 should be - * written only when the input-buffer-full bit and - * output-buffer-full bit in the Controller Status - * register are set 0." (KBINRDY and KBOUTRDY) - */ - - while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ; - outb(KBDATAP,0xF0); - while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ; - outb(KBDATAP,0x01); - } - - while (inb(KBSTATP) & KBOUTRDY) ; - outb(KBSTATP,0xAE); -} - -/* We have to actually read the keyboard when CRT_tstc is called, - * since the pending data might be a key release code, and therefore - * not valid data. In this case, kbd() will return -1, even though there's - * data to be read. Of course, we might actually read a valid key press, - * in which case it gets queued into key_pending for use by CRT_getc. - */ - -static int kbd_reset = 0; - -static int key_pending = -1; - -int CRT_getc(void) -{ - int c; - if (!kbd_reset) {kbdreset(); kbd_reset++; } - - if (key_pending != -1) { - c = key_pending; - key_pending = -1; - return c; - } else { - while ((c = kbd(0)) == 0) ; - return c; - } -} - -int CRT_tstc(void) -{ - if (!kbd_reset) {kbdreset(); kbd_reset++; } - - while (key_pending == -1 && ((inb(KBSTATP) & KBINRDY) != 0)) { - key_pending = kbd(1); - } - - return (key_pending != -1); -} diff -Nru a/arch/ppc/boot/lib/Makefile b/arch/ppc/boot/lib/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/lib/Makefile Mon May 21 17:07:05 2001 @@ -0,0 +1,9 @@ +# +# Makefile for some libs needed by zImage. +# + +L_TARGET := zlib.a + +obj-y := zlib.o + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/lib/zlib.c b/arch/ppc/boot/lib/zlib.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/lib/zlib.c Mon May 21 17:07:03 2001 @@ -0,0 +1,2150 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * This file is derived from various .h and .c files from the zlib-0.95 + * distribution by Jean-loup Gailly and Mark Adler, with some additions + * by Paul Mackerras to aid in implementing Deflate compression and + * decompression for PPP packets. See zlib.h for conditions of + * distribution and use. + * + * Changes that have been made include: + * - changed functions not used outside this file to "local" + * - added minCompression parameter to deflateInit2 + * - added Z_PACKET_FLUSH (see zlib.h for details) + * - added inflateIncomp + * + */ + +/*+++++*/ +/* zutil.h -- internal interface and configuration of the compression library + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */ + +#define _Z_UTIL_H + +#include "zlib.h" + +#ifndef local +# define local static +#endif +/* compile with -Dlocal if your debugger can't find static symbols */ + +#define FAR + +typedef unsigned char uch; +typedef uch FAR uchf; +typedef unsigned short ush; +typedef ush FAR ushf; +typedef unsigned long ulg; + +extern char *z_errmsg[]; /* indexed by 1-zlib_error */ + +#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) +/* To be used only when the state is known to be valid */ + +#ifndef NULL +#define NULL ((void *) 0) +#endif + + /* common constants */ + +#define DEFLATED 8 + +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif +/* default windowBits for decompression. MAX_WBITS is for compression only */ + +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#endif +/* default memLevel */ + +#define STORED_BLOCK 0 +#define STATIC_TREES 1 +#define DYN_TREES 2 +/* The three kinds of block type */ + +#define MIN_MATCH 3 +#define MAX_MATCH 258 +/* The minimum and maximum match lengths */ + + /* functions */ + +#include +#define zmemcpy memcpy +#define zmemzero(dest, len) memset(dest, 0, len) + +/* Diagnostic functions */ +#ifdef DEBUG_ZLIB +# include +# ifndef verbose +# define verbose 0 +# endif +# define Assert(cond,msg) {if(!(cond)) z_error(msg);} +# define Trace(x) fprintf x +# define Tracev(x) {if (verbose) fprintf x ;} +# define Tracevv(x) {if (verbose>1) fprintf x ;} +# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} +# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} +#else +# define Assert(cond,msg) +# define Trace(x) +# define Tracev(x) +# define Tracevv(x) +# define Tracec(c,x) +# define Tracecv(c,x) +#endif + + +typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); + +/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ +/* void zcfree OF((voidpf opaque, voidpf ptr)); */ + +#define ZALLOC(strm, items, size) \ + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr, size) \ + (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) +#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} + +/* deflate.h -- internal compression state + * Copyright (C) 1995 Jean-loup Gailly + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/*+++++*/ +/* infblock.h -- header to use infblock.c + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_blocks_state; +typedef struct inflate_blocks_state FAR inflate_blocks_statef; + +local inflate_blocks_statef * inflate_blocks_new OF(( + z_stream *z, + check_func c, /* check function */ + uInt w)); /* window size */ + +local int inflate_blocks OF(( + inflate_blocks_statef *, + z_stream *, + int)); /* initial return code */ + +local void inflate_blocks_reset OF(( + inflate_blocks_statef *, + z_stream *, + uLongf *)); /* check value on output */ + +local int inflate_blocks_free OF(( + inflate_blocks_statef *, + z_stream *, + uLongf *)); /* check value on output */ + +local int inflate_addhistory OF(( + inflate_blocks_statef *, + z_stream *)); + +local int inflate_packet_flush OF(( + inflate_blocks_statef *)); + +/*+++++*/ +/* inftrees.h -- header to use inftrees.c + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* Huffman code lookup table entry--this entry is four bytes for machines + that have 16-bit pointers (e.g. PC's in the small or medium model). */ + +typedef struct inflate_huft_s FAR inflate_huft; + +struct inflate_huft_s { + union { + struct { + Byte Exop; /* number of extra bits or operation */ + Byte Bits; /* number of bits in this code or subcode */ + } what; + uInt Nalloc; /* number of these allocated here */ + Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ + } word; /* 16-bit, 8 bytes for 32-bit machines) */ + union { + uInt Base; /* literal, length base, or distance base */ + inflate_huft *Next; /* pointer to next level of table */ + } more; +}; + +#ifdef DEBUG_ZLIB + local uInt inflate_hufts; +#endif + +local int inflate_trees_bits OF(( + uIntf *, /* 19 code lengths */ + uIntf *, /* bits tree desired/actual depth */ + inflate_huft * FAR *, /* bits tree result */ + z_stream *)); /* for zalloc, zfree functions */ + +local int inflate_trees_dynamic OF(( + uInt, /* number of literal/length codes */ + uInt, /* number of distance codes */ + uIntf *, /* that many (total) code lengths */ + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *, /* distance tree result */ + z_stream *)); /* for zalloc, zfree functions */ + +local int inflate_trees_fixed OF(( + uIntf *, /* literal desired/actual bit depth */ + uIntf *, /* distance desired/actual bit depth */ + inflate_huft * FAR *, /* literal/length tree result */ + inflate_huft * FAR *)); /* distance tree result */ + +local int inflate_trees_free OF(( + inflate_huft *, /* tables to free */ + z_stream *)); /* for zfree function */ + + +/*+++++*/ +/* infcodes.h -- header to use infcodes.c + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +struct inflate_codes_state; +typedef struct inflate_codes_state FAR inflate_codes_statef; + +local inflate_codes_statef *inflate_codes_new OF(( + uInt, uInt, + inflate_huft *, inflate_huft *, + z_stream *)); + +local int inflate_codes OF(( + inflate_blocks_statef *, + z_stream *, + int)); + +local void inflate_codes_free OF(( + inflate_codes_statef *, + z_stream *)); + + +/*+++++*/ +/* inflate.c -- zlib interface to inflate modules + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* inflate private state */ +struct internal_state { + + /* mode */ + enum { + METHOD, /* waiting for method byte */ + FLAG, /* waiting for flag byte */ + BLOCKS, /* decompressing blocks */ + CHECK4, /* four check bytes to go */ + CHECK3, /* three check bytes to go */ + CHECK2, /* two check bytes to go */ + CHECK1, /* one check byte to go */ + DONE, /* finished check, done */ + BAD} /* got an error--stay here */ + mode; /* current inflate mode */ + + /* mode dependent information */ + union { + uInt method; /* if FLAGS, method byte */ + struct { + uLong was; /* computed check value */ + uLong need; /* stream check value */ + } check; /* if CHECK, check values to compare */ + uInt marker; /* if BAD, inflateSync's marker bytes count */ + } sub; /* submode */ + + /* mode independent information */ + int nowrap; /* flag for no wrapper */ + uInt wbits; /* log2(window size) (8..15, defaults to 15) */ + inflate_blocks_statef + *blocks; /* current inflate_blocks state */ + +}; + + +int inflateReset(z) +z_stream *z; +{ + uLong c; + + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + z->total_in = z->total_out = 0; + z->msg = Z_NULL; + z->state->mode = z->state->nowrap ? BLOCKS : METHOD; + inflate_blocks_reset(z->state->blocks, z, &c); + Trace((stderr, "inflate: reset\n")); + return Z_OK; +} + + +int inflateEnd(z) +z_stream *z; +{ + uLong c; + + if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->blocks != Z_NULL) + inflate_blocks_free(z->state->blocks, z, &c); + ZFREE(z, z->state, sizeof(struct internal_state)); + z->state = Z_NULL; + Trace((stderr, "inflate: end\n")); + return Z_OK; +} + + +int inflateInit2(z, w) +z_stream *z; +int w; +{ + /* initialize state */ + if (z == Z_NULL) + return Z_STREAM_ERROR; +/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ +/* if (z->zfree == Z_NULL) z->zfree = zcfree; */ + if ((z->state = (struct internal_state FAR *) + ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) + return Z_MEM_ERROR; + z->state->blocks = Z_NULL; + + /* handle undocumented nowrap option (no zlib header or check) */ + z->state->nowrap = 0; + if (w < 0) + { + w = - w; + z->state->nowrap = 1; + } + + /* set window size */ + if (w < 8 || w > 15) + { + inflateEnd(z); + return Z_STREAM_ERROR; + } + z->state->wbits = (uInt)w; + + /* create inflate_blocks state */ + if ((z->state->blocks = + inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) + == Z_NULL) + { + inflateEnd(z); + return Z_MEM_ERROR; + } + Trace((stderr, "inflate: allocated\n")); + + /* reset state */ + inflateReset(z); + return Z_OK; +} + + +int inflateInit(z) +z_stream *z; +{ + return inflateInit2(z, DEF_WBITS); +} + + +#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} +#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) + +int inflate(z, f) +z_stream *z; +int f; +{ + int r; + uInt b; + + if (z == Z_NULL || z->next_in == Z_NULL) + return Z_STREAM_ERROR; + r = Z_BUF_ERROR; + while (1) switch (z->state->mode) + { + case METHOD: + NEEDBYTE + if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) + { + z->state->mode = BAD; + z->msg = "unknown compression method"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if ((z->state->sub.method >> 4) + 8 > z->state->wbits) + { + z->state->mode = BAD; + z->msg = "invalid window size"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + z->state->mode = FLAG; + case FLAG: + NEEDBYTE + if ((b = NEXTBYTE) & 0x20) + { + z->state->mode = BAD; + z->msg = "invalid reserved bit"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + if (((z->state->sub.method << 8) + b) % 31) + { + z->state->mode = BAD; + z->msg = "incorrect header check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Trace((stderr, "inflate: zlib header ok\n")); + z->state->mode = BLOCKS; + case BLOCKS: + r = inflate_blocks(z->state->blocks, z, r); + if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) + r = inflate_packet_flush(z->state->blocks); + if (r == Z_DATA_ERROR) + { + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + break; + } + if (r != Z_STREAM_END) + return r; + r = Z_OK; + inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); + if (z->state->nowrap) + { + z->state->mode = DONE; + break; + } + z->state->mode = CHECK4; + case CHECK4: + NEEDBYTE + z->state->sub.check.need = (uLong)NEXTBYTE << 24; + z->state->mode = CHECK3; + case CHECK3: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 16; + z->state->mode = CHECK2; + case CHECK2: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE << 8; + z->state->mode = CHECK1; + case CHECK1: + NEEDBYTE + z->state->sub.check.need += (uLong)NEXTBYTE; + + if (z->state->sub.check.was != z->state->sub.check.need) + { + z->state->mode = BAD; + z->msg = "incorrect data check"; + z->state->sub.marker = 5; /* can't try inflateSync */ + break; + } + Trace((stderr, "inflate: zlib check ok\n")); + z->state->mode = DONE; + case DONE: + return Z_STREAM_END; + case BAD: + return Z_DATA_ERROR; + default: + return Z_STREAM_ERROR; + } + + empty: + if (f != Z_PACKET_FLUSH) + return r; + z->state->mode = BAD; + z->state->sub.marker = 0; /* can try inflateSync */ + return Z_DATA_ERROR; +} + +/* + * This subroutine adds the data at next_in/avail_in to the output history + * without performing any output. The output buffer must be "caught up"; + * i.e. no pending output (hence s->read equals s->write), and the state must + * be BLOCKS (i.e. we should be willing to see the start of a series of + * BLOCKS). On exit, the output will also be caught up, and the checksum + * will have been updated if need be. + */ + +int inflateIncomp(z) +z_stream *z; +{ + if (z->state->mode != BLOCKS) + return Z_DATA_ERROR; + return inflate_addhistory(z->state->blocks, z); +} + + +int inflateSync(z) +z_stream *z; +{ + uInt n; /* number of bytes to look at */ + Bytef *p; /* pointer to bytes */ + uInt m; /* number of marker bytes found in a row */ + uLong r, w; /* temporaries to save total_in and total_out */ + + /* set up */ + if (z == Z_NULL || z->state == Z_NULL) + return Z_STREAM_ERROR; + if (z->state->mode != BAD) + { + z->state->mode = BAD; + z->state->sub.marker = 0; + } + if ((n = z->avail_in) == 0) + return Z_BUF_ERROR; + p = z->next_in; + m = z->state->sub.marker; + + /* search */ + while (n && m < 4) + { + if (*p == (Byte)(m < 2 ? 0 : 0xff)) + m++; + else if (*p) + m = 0; + else + m = 4 - m; + p++, n--; + } + + /* restore */ + z->total_in += p - z->next_in; + z->next_in = p; + z->avail_in = n; + z->state->sub.marker = m; + + /* return no joy or set up to restart on a new block */ + if (m != 4) + return Z_DATA_ERROR; + r = z->total_in; w = z->total_out; + inflateReset(z); + z->total_in = r; z->total_out = w; + z->state->mode = BLOCKS; + return Z_OK; +} + +#undef NEEDBYTE +#undef NEXTBYTE + +/*+++++*/ +/* infutil.h -- types and macros common to blocks and codes + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +/* inflate blocks semi-private state */ +struct inflate_blocks_state { + + /* mode */ + enum { + TYPE, /* get type bits (3, including end bit) */ + LENS, /* get lengths for stored */ + STORED, /* processing stored block */ + TABLE, /* get table lengths */ + BTREE, /* get bit lengths tree for a dynamic block */ + DTREE, /* get length, distance trees for a dynamic block */ + CODES, /* processing fixed or dynamic block */ + DRY, /* output remaining window bytes */ + DONEB, /* finished last block, done */ + BADB} /* got a data error--stuck here */ + mode; /* current inflate_block mode */ + + /* mode dependent information */ + union { + uInt left; /* if STORED, bytes left to copy */ + struct { + uInt table; /* table lengths (14 bits) */ + uInt index; /* index into blens (or border) */ + uIntf *blens; /* bit lengths of codes */ + uInt bb; /* bit length tree depth */ + inflate_huft *tb; /* bit length decoding tree */ + int nblens; /* # elements allocated at blens */ + } trees; /* if DTREE, decoding info for trees */ + struct { + inflate_huft *tl, *td; /* trees to free */ + inflate_codes_statef + *codes; + } decode; /* if CODES, current state */ + } sub; /* submode */ + uInt last; /* true if this block is the last block */ + + /* mode independent information */ + uInt bitk; /* bits in bit buffer */ + uLong bitb; /* bit buffer */ + Bytef *window; /* sliding window */ + Bytef *end; /* one byte after sliding window */ + Bytef *read; /* window read pointer */ + Bytef *write; /* window write pointer */ + check_func checkfn; /* check function */ + uLong check; /* check on output */ + +}; + + +/* defines for inflate input/output */ +/* update pointers and return */ +#define UPDBITS {s->bitb=b;s->bitk=k;} +#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} +#define UPDOUT {s->write=q;} +#define UPDATE {UPDBITS UPDIN UPDOUT} +#define LEAVE {UPDATE return inflate_flush(s,z,r);} +/* get bytes and bits */ +#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} +#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} +#define NEXTBYTE (n--,*p++) +#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} +/* output bytes */ +#define WAVAIL (qread?s->read-q-1:s->end-q) +#define LOADOUT {q=s->write;m=WAVAIL;} +#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} +#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} +#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} +#define OUTBYTE(a) {*q++=(Byte)(a);m--;} +/* load local pointers */ +#define LOAD {LOADIN LOADOUT} + +/* + * The IBM 150 firmware munges the data right after _etext[]. This + * protects it. -- Cort + */ +local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0}; +/* And'ing with mask[n] masks the lower n bits */ +local uInt inflate_mask[] = { + 0x0000, + 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, + 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff +}; + +/* copy as much as possible from the sliding window to the output area */ +local int inflate_flush OF(( + inflate_blocks_statef *, + z_stream *, + int)); + +/*+++++*/ +/* inffast.h -- header to use inffast.c + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* WARNING: this file should *not* be used by applications. It is + part of the implementation of the compression library and is + subject to change. Applications should only use zlib.h. + */ + +local int inflate_fast OF(( + uInt, + uInt, + inflate_huft *, + inflate_huft *, + inflate_blocks_statef *, + z_stream *)); + + +/*+++++*/ +/* infblock.c -- interpret and process block types to last block + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* Table for deflate from PKZIP's appnote.txt. */ +local uInt border[] = { /* Order of the bit length code lengths */ + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + +/* + Notes beyond the 1.93a appnote.txt: + + 1. Distance pointers never point before the beginning of the output + stream. + 2. Distance pointers can point back across blocks, up to 32k away. + 3. There is an implied maximum of 7 bits for the bit length table and + 15 bits for the actual data. + 4. If only one code exists, then it is encoded using one bit. (Zero + would be more efficient, but perhaps a little confusing.) If two + codes exist, they are coded using one bit each (0 and 1). + 5. There is no way of sending zero distance codes--a dummy must be + sent if there are none. (History: a pre 2.0 version of PKZIP would + store blocks with no distance codes, but this was discovered to be + too harsh a criterion.) Valid only for 1.93a. 2.04c does allow + zero distance codes, which is sent as one code of zero bits in + length. + 6. There are up to 286 literal/length codes. Code 256 represents the + end-of-block. Note however that the static length tree defines + 288 codes just to fill out the Huffman codes. Codes 286 and 287 + cannot be used though, since there is no length base or extra bits + defined for them. Similarily, there are up to 30 distance codes. + However, static trees define 32 codes (all 5 bits) to fill out the + Huffman codes, but the last two had better not show up in the data. + 7. Unzip can check dynamic Huffman blocks for complete code sets. + The exception is that a single code would not be complete (see #4). + 8. The five bits following the block type is really the number of + literal codes sent minus 257. + 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits + (1+6+6). Therefore, to output three times the length, you output + three codes (1+1+1), whereas to output four times the same length, + you only need two codes (1+3). Hmm. + 10. In the tree reconstruction algorithm, Code = Code + Increment + only if BitLength(i) is not zero. (Pretty obvious.) + 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) + 12. Note: length code 284 can represent 227-258, but length code 285 + really is 258. The last length deserves its own, short code + since it gets used a lot in very redundant files. The length + 258 is special since 258 - 3 (the min match length) is 255. + 13. The literal/length and distance code bit lengths are read as a + single stream of lengths. It is possible (and advantageous) for + a repeat code (16, 17, or 18) to go across the boundary between + the two sets of lengths. + */ + + +local void inflate_blocks_reset(s, z, c) +inflate_blocks_statef *s; +z_stream *z; +uLongf *c; +{ + if (s->checkfn != Z_NULL) + *c = s->check; + if (s->mode == BTREE || s->mode == DTREE) + ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); + if (s->mode == CODES) + { + inflate_codes_free(s->sub.decode.codes, z); + inflate_trees_free(s->sub.decode.td, z); + inflate_trees_free(s->sub.decode.tl, z); + } + s->mode = TYPE; + s->bitk = 0; + s->bitb = 0; + s->read = s->write = s->window; + if (s->checkfn != Z_NULL) + s->check = (*s->checkfn)(0L, Z_NULL, 0); + Trace((stderr, "inflate: blocks reset\n")); +} + + +local inflate_blocks_statef *inflate_blocks_new(z, c, w) +z_stream *z; +check_func c; +uInt w; +{ + inflate_blocks_statef *s; + + if ((s = (inflate_blocks_statef *)ZALLOC + (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) + return s; + if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) + { + ZFREE(z, s, sizeof(struct inflate_blocks_state)); + return Z_NULL; + } + s->end = s->window + w; + s->checkfn = c; + s->mode = TYPE; + Trace((stderr, "inflate: blocks allocated\n")); + inflate_blocks_reset(s, z, &s->check); + return s; +} + + +local int inflate_blocks(s, z, r) +inflate_blocks_statef *s; +z_stream *z; +int r; +{ + uInt t; /* temporary storage */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input based on current state */ + while (1) switch (s->mode) + { + case TYPE: + NEEDBITS(3) + t = (uInt)b & 7; + s->last = t & 1; + switch (t >> 1) + { + case 0: /* stored */ + Trace((stderr, "inflate: stored block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + t = k & 7; /* go to byte boundary */ + DUMPBITS(t) + s->mode = LENS; /* get length of stored block */ + break; + case 1: /* fixed */ + Trace((stderr, "inflate: fixed codes block%s\n", + s->last ? " (last)" : "")); + { + uInt bl, bd; + inflate_huft *tl, *td; + + inflate_trees_fixed(&bl, &bd, &tl, &td); + s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); + if (s->sub.decode.codes == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.decode.tl = Z_NULL; /* don't try to free these */ + s->sub.decode.td = Z_NULL; + } + DUMPBITS(3) + s->mode = CODES; + break; + case 2: /* dynamic */ + Trace((stderr, "inflate: dynamic codes block%s\n", + s->last ? " (last)" : "")); + DUMPBITS(3) + s->mode = TABLE; + break; + case 3: /* illegal */ + DUMPBITS(3) + s->mode = BADB; + z->msg = "invalid block type"; + r = Z_DATA_ERROR; + LEAVE + } + break; + case LENS: + NEEDBITS(32) + if (((~b) >> 16) != (b & 0xffff)) + { + s->mode = BADB; + z->msg = "invalid stored block lengths"; + r = Z_DATA_ERROR; + LEAVE + } + s->sub.left = (uInt)b & 0xffff; + b = k = 0; /* dump bits */ + Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); + s->mode = s->sub.left ? STORED : TYPE; + break; + case STORED: + if (n == 0) + LEAVE + NEEDOUT + t = s->sub.left; + if (t > n) t = n; + if (t > m) t = m; + zmemcpy(q, p, t); + p += t; n -= t; + q += t; m -= t; + if ((s->sub.left -= t) != 0) + break; + Tracev((stderr, "inflate: stored end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + s->mode = s->last ? DRY : TYPE; + break; + case TABLE: + NEEDBITS(14) + s->sub.trees.table = t = (uInt)b & 0x3fff; +#ifndef PKZIP_BUG_WORKAROUND + if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) + { + s->mode = BADB; + z->msg = "too many length or distance symbols"; + r = Z_DATA_ERROR; + LEAVE + } +#endif + t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); + if (t < 19) + t = 19; + if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) + { + r = Z_MEM_ERROR; + LEAVE + } + s->sub.trees.nblens = t; + DUMPBITS(14) + s->sub.trees.index = 0; + Tracev((stderr, "inflate: table sizes ok\n")); + s->mode = BTREE; + case BTREE: + while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) + { + NEEDBITS(3) + s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; + DUMPBITS(3) + } + while (s->sub.trees.index < 19) + s->sub.trees.blens[border[s->sub.trees.index++]] = 0; + s->sub.trees.bb = 7; + t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, + &s->sub.trees.tb, z); + if (t != Z_OK) + { + r = t; + if (r == Z_DATA_ERROR) + s->mode = BADB; + LEAVE + } + s->sub.trees.index = 0; + Tracev((stderr, "inflate: bits tree ok\n")); + s->mode = DTREE; + case DTREE: + while (t = s->sub.trees.table, + s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) + { + inflate_huft *h; + uInt i, j, c; + + t = s->sub.trees.bb; + NEEDBITS(t) + h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); + t = h->word.what.Bits; + c = h->more.Base; + if (c < 16) + { + DUMPBITS(t) + s->sub.trees.blens[s->sub.trees.index++] = c; + } + else /* c == 16..18 */ + { + i = c == 18 ? 7 : c - 14; + j = c == 18 ? 11 : 3; + NEEDBITS(t + i) + DUMPBITS(t) + j += (uInt)b & inflate_mask[i]; + DUMPBITS(i) + i = s->sub.trees.index; + t = s->sub.trees.table; + if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || + (c == 16 && i < 1)) + { + s->mode = BADB; + z->msg = "invalid bit length repeat"; + r = Z_DATA_ERROR; + LEAVE + } + c = c == 16 ? s->sub.trees.blens[i - 1] : 0; + do { + s->sub.trees.blens[i++] = c; + } while (--j); + s->sub.trees.index = i; + } + } + inflate_trees_free(s->sub.trees.tb, z); + s->sub.trees.tb = Z_NULL; + { + uInt bl, bd; + inflate_huft *tl, *td; + inflate_codes_statef *c; + + bl = 9; /* must be <= 9 for lookahead assumptions */ + bd = 6; /* must be <= 9 for lookahead assumptions */ + t = s->sub.trees.table; + t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), + s->sub.trees.blens, &bl, &bd, &tl, &td, z); + if (t != Z_OK) + { + if (t == (uInt)Z_DATA_ERROR) + s->mode = BADB; + r = t; + LEAVE + } + Tracev((stderr, "inflate: trees ok\n")); + if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) + { + inflate_trees_free(td, z); + inflate_trees_free(tl, z); + r = Z_MEM_ERROR; + LEAVE + } + ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); + s->sub.decode.codes = c; + s->sub.decode.tl = tl; + s->sub.decode.td = td; + } + s->mode = CODES; + case CODES: + UPDATE + if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) + return inflate_flush(s, z, r); + r = Z_OK; + inflate_codes_free(s->sub.decode.codes, z); + inflate_trees_free(s->sub.decode.td, z); + inflate_trees_free(s->sub.decode.tl, z); + LOAD + Tracev((stderr, "inflate: codes end, %lu total out\n", + z->total_out + (q >= s->read ? q - s->read : + (s->end - s->read) + (q - s->window)))); + if (!s->last) + { + s->mode = TYPE; + break; + } + if (k > 7) /* return unused byte, if any */ + { + Assert(k < 16, "inflate_codes grabbed too many bytes") + k -= 8; + n++; + p--; /* can always return one */ + } + s->mode = DRY; + case DRY: + FLUSH + if (s->read != s->write) + LEAVE + s->mode = DONEB; + case DONEB: + r = Z_STREAM_END; + LEAVE + case BADB: + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +local int inflate_blocks_free(s, z, c) +inflate_blocks_statef *s; +z_stream *z; +uLongf *c; +{ + inflate_blocks_reset(s, z, c); + ZFREE(z, s->window, s->end - s->window); + ZFREE(z, s, sizeof(struct inflate_blocks_state)); + Trace((stderr, "inflate: blocks freed\n")); + return Z_OK; +} + +/* + * This subroutine adds the data at next_in/avail_in to the output history + * without performing any output. The output buffer must be "caught up"; + * i.e. no pending output (hence s->read equals s->write), and the state must + * be BLOCKS (i.e. we should be willing to see the start of a series of + * BLOCKS). On exit, the output will also be caught up, and the checksum + * will have been updated if need be. + */ +local int inflate_addhistory(s, z) +inflate_blocks_statef *s; +z_stream *z; +{ + uLong b; /* bit buffer */ /* NOT USED HERE */ + uInt k; /* bits in bit buffer */ /* NOT USED HERE */ + uInt t; /* temporary storage */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + + if (s->read != s->write) + return Z_STREAM_ERROR; + if (s->mode != TYPE) + return Z_DATA_ERROR; + + /* we're ready to rock */ + LOAD + /* while there is input ready, copy to output buffer, moving + * pointers as needed. + */ + while (n) { + t = n; /* how many to do */ + /* is there room until end of buffer? */ + if (t > m) t = m; + /* update check information */ + if (s->checkfn != Z_NULL) + s->check = (*s->checkfn)(s->check, q, t); + zmemcpy(q, p, t); + q += t; + p += t; + n -= t; + z->total_out += t; + s->read = q; /* drag read pointer forward */ +/* WRAP */ /* expand WRAP macro by hand to handle s->read */ + if (q == s->end) { + s->read = q = s->window; + m = WAVAIL; + } + } + UPDATE + return Z_OK; +} + + +/* + * At the end of a Deflate-compressed PPP packet, we expect to have seen + * a `stored' block type value but not the (zero) length bytes. + */ +local int inflate_packet_flush(s) + inflate_blocks_statef *s; +{ + if (s->mode != LENS) + return Z_DATA_ERROR; + s->mode = TYPE; + return Z_OK; +} + + +/*+++++*/ +/* inftrees.c -- generate Huffman trees for efficient decoding + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + + +local int huft_build OF(( + uIntf *, /* code lengths in bits */ + uInt, /* number of codes */ + uInt, /* number of "simple" codes */ + uIntf *, /* list of base values for non-simple codes */ + uIntf *, /* list of extra bits for non-simple codes */ + inflate_huft * FAR*,/* result: starting table */ + uIntf *, /* maximum lookup bits (returns actual) */ + z_stream *)); /* for zalloc function */ + +local voidpf falloc OF(( + voidpf, /* opaque pointer (not used) */ + uInt, /* number of items */ + uInt)); /* size of item */ + +local void ffree OF(( + voidpf q, /* opaque pointer (not used) */ + voidpf p, /* what to free (not used) */ + uInt n)); /* number of bytes (not used) */ + +/* Tables for deflate from PKZIP's appnote.txt. */ +local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + /* actually lengths - 2; also see note #13 above about 258 */ +local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ + 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ +local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577}; +local uInt cpdext[] = { /* Extra bits for distance codes */ + 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, + 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, + 12, 12, 13, 13}; + +/* + Huffman code decoding is performed using a multi-level table lookup. + The fastest way to decode is to simply build a lookup table whose + size is determined by the longest code. However, the time it takes + to build this table can also be a factor if the data being decoded + is not very long. The most common codes are necessarily the + shortest codes, so those codes dominate the decoding time, and hence + the speed. The idea is you can have a shorter table that decodes the + shorter, more probable codes, and then point to subsidiary tables for + the longer codes. The time it costs to decode the longer codes is + then traded against the time it takes to make longer tables. + + This results of this trade are in the variables lbits and dbits + below. lbits is the number of bits the first level table for literal/ + length codes can decode in one step, and dbits is the same thing for + the distance codes. Subsequent tables are also less than or equal to + those sizes. These values may be adjusted either when all of the + codes are shorter than that, in which case the longest code length in + bits is used, or when the shortest code is *longer* than the requested + table size, in which case the length of the shortest code in bits is + used. + + There are two different values for the two tables, since they code a + different number of possibilities each. The literal/length table + codes 286 possible values, or in a flat code, a little over eight + bits. The distance table codes 30 possible values, or a little less + than five bits, flat. The optimum values for speed end up being + about one bit more than those, so lbits is 8+1 and dbits is 5+1. + The optimum values may differ though from machine to machine, and + possibly even between compilers. Your mileage may vary. + */ + + +/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ +#define BMAX 15 /* maximum bit length of any code */ +#define N_MAX 288 /* maximum number of codes in any set */ + +#ifdef DEBUG_ZLIB + uInt inflate_hufts; +#endif + +local int huft_build(b, n, s, d, e, t, m, zs) +uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ +uInt n; /* number of codes (assumed <= N_MAX) */ +uInt s; /* number of simple-valued codes (0..s-1) */ +uIntf *d; /* list of base values for non-simple codes */ +uIntf *e; /* list of extra bits for non-simple codes */ +inflate_huft * FAR *t; /* result: starting table */ +uIntf *m; /* maximum lookup bits, returns actual */ +z_stream *zs; /* for zalloc function */ +/* Given a list of code lengths and a maximum table size, make a set of + tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR + if the given code set is incomplete (the tables are still built in this + case), Z_DATA_ERROR if the input is invalid (all zero length codes or an + over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ +{ + + uInt a; /* counter for codes of length k */ + uInt c[BMAX+1]; /* bit length count table */ + uInt f; /* i repeats in table every f entries */ + int g; /* maximum code length */ + int h; /* table level */ + register uInt i; /* counter, current code */ + register uInt j; /* counter */ + register int k; /* number of bits in current code */ + int l; /* bits per table (returned in m) */ + register uIntf *p; /* pointer into c[], b[], or v[] */ + inflate_huft *q; /* points to current table */ + struct inflate_huft_s r; /* table entry for structure assignment */ + inflate_huft *u[BMAX]; /* table stack */ + uInt v[N_MAX]; /* values in order of bit length */ + register int w; /* bits before this table == (l * h) */ + uInt x[BMAX+1]; /* bit offsets, then code stack */ + uIntf *xp; /* pointer into x */ + int y; /* number of dummy codes added */ + uInt z; /* number of entries in current table */ + + + /* Generate counts for each bit length */ + p = c; +#define C0 *p++ = 0; +#define C2 C0 C0 C0 C0 +#define C4 C2 C2 C2 C2 + C4 /* clear c[]--assume BMAX+1 is 16 */ + p = b; i = n; + do { + c[*p++]++; /* assume all entries <= BMAX */ + } while (--i); + if (c[0] == n) /* null input--all zero length codes */ + { + *t = (inflate_huft *)Z_NULL; + *m = 0; + return Z_OK; + } + + + /* Find minimum and maximum length, bound *m by those */ + l = *m; + for (j = 1; j <= BMAX; j++) + if (c[j]) + break; + k = j; /* minimum code length */ + if ((uInt)l < j) + l = j; + for (i = BMAX; i; i--) + if (c[i]) + break; + g = i; /* maximum code length */ + if ((uInt)l > i) + l = i; + *m = l; + + + /* Adjust last length count to fill out codes, if needed */ + for (y = 1 << j; j < i; j++, y <<= 1) + if ((y -= c[j]) < 0) + return Z_DATA_ERROR; + if ((y -= c[i]) < 0) + return Z_DATA_ERROR; + c[i] += y; + + + /* Generate starting offsets into the value table for each length */ + x[1] = j = 0; + p = c + 1; xp = x + 2; + while (--i) { /* note that i == g from above */ + *xp++ = (j += *p++); + } + + + /* Make a table of values in order of bit lengths */ + p = b; i = 0; + do { + if ((j = *p++) != 0) + v[x[j]++] = i; + } while (++i < n); + + + /* Generate the Huffman codes and for each, make the table entries */ + x[0] = i = 0; /* first Huffman code is zero */ + p = v; /* grab values in bit order */ + h = -1; /* no tables yet--level -1 */ + w = -l; /* bits decoded == (l * h) */ + u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ + q = (inflate_huft *)Z_NULL; /* ditto */ + z = 0; /* ditto */ + + /* go through the bit lengths (k already is bits in shortest code) */ + for (; k <= g; k++) + { + a = c[k]; + while (a--) + { + /* here i is the Huffman code of length k bits for value *p */ + /* make tables up to required level */ + while (k > w + l) + { + h++; + w += l; /* previous table always l bits */ + + /* compute minimum size table less than or equal to l bits */ + z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ + if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ + { /* too few codes for k-w bit table */ + f -= a + 1; /* deduct codes from patterns left */ + xp = c + k; + if (j < z) + while (++j < z) /* try smaller tables up to z bits */ + { + if ((f <<= 1) <= *++xp) + break; /* enough codes to use up j bits */ + f -= *xp; /* else deduct codes from patterns */ + } + } + z = 1 << j; /* table entries for j-bit table */ + + /* allocate and link in new table */ + if ((q = (inflate_huft *)ZALLOC + (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) + { + if (h) + inflate_trees_free(u[0], zs); + return Z_MEM_ERROR; /* not enough memory */ + } + q->word.Nalloc = z + 1; +#ifdef DEBUG_ZLIB + inflate_hufts += z + 1; +#endif + *t = q + 1; /* link to list for huft_free() */ + *(t = &(q->next)) = Z_NULL; + u[h] = ++q; /* table starts after link */ + + /* connect to last table, if there is one */ + if (h) + { + x[h] = i; /* save pattern for backing up */ + r.bits = (Byte)l; /* bits to dump before this table */ + r.exop = (Byte)j; /* bits in this table */ + r.next = q; /* pointer to this table */ + j = i >> (w - l); /* (get around Turbo C bug) */ + u[h-1][j] = r; /* connect to last table */ + } + } + + /* set up table entry in r */ + r.bits = (Byte)(k - w); + if (p >= v + n) + r.exop = 128 + 64; /* out of values--invalid code */ + else if (*p < s) + { + r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ + r.base = *p++; /* simple code is just the value */ + } + else + { + r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ + r.base = d[*p++ - s]; + } + + /* fill code-like entries with r */ + f = 1 << (k - w); + for (j = i >> w; j < z; j += f) + q[j] = r; + + /* backwards increment the k-bit code i */ + for (j = 1 << (k - 1); i & j; j >>= 1) + i ^= j; + i ^= j; + + /* backup over finished tables */ + while ((i & ((1 << w) - 1)) != x[h]) + { + h--; /* don't need to update q */ + w -= l; + } + } + } + + + /* Return Z_BUF_ERROR if we were given an incomplete table */ + return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; +} + + +local int inflate_trees_bits(c, bb, tb, z) +uIntf *c; /* 19 code lengths */ +uIntf *bb; /* bits tree desired/actual depth */ +inflate_huft * FAR *tb; /* bits tree result */ +z_stream *z; /* for zfree function */ +{ + int r; + + r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); + if (r == Z_DATA_ERROR) + z->msg = "oversubscribed dynamic bit lengths tree"; + else if (r == Z_BUF_ERROR) + { + inflate_trees_free(*tb, z); + z->msg = "incomplete dynamic bit lengths tree"; + r = Z_DATA_ERROR; + } + return r; +} + + +local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) +uInt nl; /* number of literal/length codes */ +uInt nd; /* number of distance codes */ +uIntf *c; /* that many (total) code lengths */ +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +z_stream *z; /* for zfree function */ +{ + int r; + + /* build literal/length tree */ + if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) + { + if (r == Z_DATA_ERROR) + z->msg = "oversubscribed literal/length tree"; + else if (r == Z_BUF_ERROR) + { + inflate_trees_free(*tl, z); + z->msg = "incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + return r; + } + + /* build distance tree */ + if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) + { + if (r == Z_DATA_ERROR) + z->msg = "oversubscribed literal/length tree"; + else if (r == Z_BUF_ERROR) { +#ifdef PKZIP_BUG_WORKAROUND + r = Z_OK; + } +#else + inflate_trees_free(*td, z); + z->msg = "incomplete literal/length tree"; + r = Z_DATA_ERROR; + } + inflate_trees_free(*tl, z); + return r; +#endif + } + + /* done */ + return Z_OK; +} + + +/* build fixed tables only once--keep them here */ +local int fixed_lock = 0; +local int fixed_built = 0; +#define FIXEDH 530 /* number of hufts used by fixed tables */ +local uInt fixed_left = FIXEDH; +local inflate_huft fixed_mem[FIXEDH]; +local uInt fixed_bl; +local uInt fixed_bd; +local inflate_huft *fixed_tl; +local inflate_huft *fixed_td; + + +local voidpf falloc(q, n, s) +voidpf q; /* opaque pointer (not used) */ +uInt n; /* number of items */ +uInt s; /* size of item */ +{ + Assert(s == sizeof(inflate_huft) && n <= fixed_left, + "inflate_trees falloc overflow"); + if (q) s++; /* to make some compilers happy */ + fixed_left -= n; + return (voidpf)(fixed_mem + fixed_left); +} + + +local void ffree(q, p, n) +voidpf q; +voidpf p; +uInt n; +{ + Assert(0, "inflate_trees ffree called!"); + if (q) q = p; /* to make some compilers happy */ +} + + +local int inflate_trees_fixed(bl, bd, tl, td) +uIntf *bl; /* literal desired/actual bit depth */ +uIntf *bd; /* distance desired/actual bit depth */ +inflate_huft * FAR *tl; /* literal/length tree result */ +inflate_huft * FAR *td; /* distance tree result */ +{ + /* build fixed tables if not built already--lock out other instances */ + while (++fixed_lock > 1) + fixed_lock--; + if (!fixed_built) + { + int k; /* temporary variable */ + unsigned c[288]; /* length list for huft_build */ + z_stream z; /* for falloc function */ + + /* set up fake z_stream for memory routines */ + z.zalloc = falloc; + z.zfree = ffree; + z.opaque = Z_NULL; + + /* literal table */ + for (k = 0; k < 144; k++) + c[k] = 8; + for (; k < 256; k++) + c[k] = 9; + for (; k < 280; k++) + c[k] = 7; + for (; k < 288; k++) + c[k] = 8; + fixed_bl = 7; + huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); + + /* distance table */ + for (k = 0; k < 30; k++) + c[k] = 5; + fixed_bd = 5; + huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); + + /* done */ + fixed_built = 1; + } + fixed_lock--; + *bl = fixed_bl; + *bd = fixed_bd; + *tl = fixed_tl; + *td = fixed_td; + return Z_OK; +} + + +local int inflate_trees_free(t, z) +inflate_huft *t; /* table to free */ +z_stream *z; /* for zfree function */ +/* Free the malloc'ed tables built by huft_build(), which makes a linked + list of the tables it made, with the links in a dummy first entry of + each table. */ +{ + register inflate_huft *p, *q; + + /* Go through linked list, freeing from the malloced (t[-1]) address. */ + p = t; + while (p != Z_NULL) + { + q = (--p)->next; + ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); + p = q; + } + return Z_OK; +} + +/*+++++*/ +/* infcodes.c -- process literals and length/distance pairs + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + +/* inflate codes private state */ +struct inflate_codes_state { + + /* mode */ + enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + START, /* x: set up for LEN */ + LEN, /* i: get length/literal/eob next */ + LENEXT, /* i: getting length extra (have base) */ + DIST, /* i: get distance next */ + DISTEXT, /* i: getting distance extra */ + COPY, /* o: copying bytes in window, waiting for space */ + LIT, /* o: got literal, waiting for output space */ + WASH, /* o: got eob, possibly still output waiting */ + END, /* x: got eob and all data flushed */ + BADCODE} /* x: got error */ + mode; /* current inflate_codes mode */ + + /* mode dependent information */ + uInt len; + union { + struct { + inflate_huft *tree; /* pointer into tree */ + uInt need; /* bits needed */ + } code; /* if LEN or DIST, where in tree */ + uInt lit; /* if LIT, literal */ + struct { + uInt get; /* bits to get for extra */ + uInt dist; /* distance back to copy from */ + } copy; /* if EXT or COPY, where and how much */ + } sub; /* submode */ + + /* mode independent information */ + Byte lbits; /* ltree bits decoded per branch */ + Byte dbits; /* dtree bits decoder per branch */ + inflate_huft *ltree; /* literal/length/eob tree */ + inflate_huft *dtree; /* distance tree */ + +}; + + +local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) +uInt bl, bd; +inflate_huft *tl, *td; +z_stream *z; +{ + inflate_codes_statef *c; + + if ((c = (inflate_codes_statef *) + ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) + { + c->mode = START; + c->lbits = (Byte)bl; + c->dbits = (Byte)bd; + c->ltree = tl; + c->dtree = td; + Tracev((stderr, "inflate: codes new\n")); + } + return c; +} + + +local int inflate_codes(s, z, r) +inflate_blocks_statef *s; +z_stream *z; +int r; +{ + uInt j; /* temporary storage */ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + Bytef *f; /* pointer to copy strings from */ + inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ + + /* copy input/output information to locals (UPDATE macro restores) */ + LOAD + + /* process input and output based on current state */ + while (1) switch (c->mode) + { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ + case START: /* x: set up for LEN */ +#ifndef SLOW + if (m >= 258 && n >= 10) + { + UPDATE + r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); + LOAD + if (r != Z_OK) + { + c->mode = r == Z_STREAM_END ? WASH : BADCODE; + break; + } + } +#endif /* !SLOW */ + c->sub.code.need = c->lbits; + c->sub.code.tree = c->ltree; + c->mode = LEN; + case LEN: /* i: get length/literal/eob next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e == 0) /* literal */ + { + c->sub.lit = t->base; + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: literal '%c'\n" : + "inflate: literal 0x%02x\n", t->base)); + c->mode = LIT; + break; + } + if (e & 16) /* length */ + { + c->sub.copy.get = e & 15; + c->len = t->base; + c->mode = LENEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t->next; + break; + } + if (e & 32) /* end of block */ + { + Tracevv((stderr, "inflate: end of block\n")); + c->mode = WASH; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = "invalid literal/length code"; + r = Z_DATA_ERROR; + LEAVE + case LENEXT: /* i: getting length extra (have base) */ + j = c->sub.copy.get; + NEEDBITS(j) + c->len += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + c->sub.code.need = c->dbits; + c->sub.code.tree = c->dtree; + Tracevv((stderr, "inflate: length %u\n", c->len)); + c->mode = DIST; + case DIST: /* i: get distance next */ + j = c->sub.code.need; + NEEDBITS(j) + t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); + DUMPBITS(t->bits) + e = (uInt)(t->exop); + if (e & 16) /* distance */ + { + c->sub.copy.get = e & 15; + c->sub.copy.dist = t->base; + c->mode = DISTEXT; + break; + } + if ((e & 64) == 0) /* next table */ + { + c->sub.code.need = e; + c->sub.code.tree = t->next; + break; + } + c->mode = BADCODE; /* invalid code */ + z->msg = "invalid distance code"; + r = Z_DATA_ERROR; + LEAVE + case DISTEXT: /* i: getting distance extra */ + j = c->sub.copy.get; + NEEDBITS(j) + c->sub.copy.dist += (uInt)b & inflate_mask[j]; + DUMPBITS(j) + Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); + c->mode = COPY; + case COPY: /* o: copying bytes in window, waiting for space */ +#ifndef __TURBOC__ /* Turbo C bug for following expression */ + f = (uInt)(q - s->window) < c->sub.copy.dist ? + s->end - (c->sub.copy.dist - (q - s->window)) : + q - c->sub.copy.dist; +#else + f = q - c->sub.copy.dist; + if ((uInt)(q - s->window) < c->sub.copy.dist) + f = s->end - (c->sub.copy.dist - (q - s->window)); +#endif + while (c->len) + { + NEEDOUT + OUTBYTE(*f++) + if (f == s->end) + f = s->window; + c->len--; + } + c->mode = START; + break; + case LIT: /* o: got literal, waiting for output space */ + NEEDOUT + OUTBYTE(c->sub.lit) + c->mode = START; + break; + case WASH: /* o: got eob, possibly more output */ + FLUSH + if (s->read != s->write) + LEAVE + c->mode = END; + case END: + r = Z_STREAM_END; + LEAVE + case BADCODE: /* x: got error */ + r = Z_DATA_ERROR; + LEAVE + default: + r = Z_STREAM_ERROR; + LEAVE + } +} + + +local void inflate_codes_free(c, z) +inflate_codes_statef *c; +z_stream *z; +{ + ZFREE(z, c, sizeof(struct inflate_codes_state)); + Tracev((stderr, "inflate: codes free\n")); +} + +/*+++++*/ +/* inflate_util.c -- data and routines common to blocks and codes + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* copy as much as possible from the sliding window to the output area */ +local int inflate_flush(s, z, r) +inflate_blocks_statef *s; +z_stream *z; +int r; +{ + uInt n; + Bytef *p, *q; + + /* local copies of source and destination pointers */ + p = z->next_out; + q = s->read; + + /* compute number of bytes to copy as far as end of window */ + n = (uInt)((q <= s->write ? s->write : s->end) - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + s->check = (*s->checkfn)(s->check, q, n); + + /* copy as far as end of window */ + zmemcpy(p, q, n); + p += n; + q += n; + + /* see if more to copy at beginning of window */ + if (q == s->end) + { + /* wrap pointers */ + q = s->window; + if (s->write == s->end) + s->write = s->window; + + /* compute bytes to copy */ + n = (uInt)(s->write - q); + if (n > z->avail_out) n = z->avail_out; + if (n && r == Z_BUF_ERROR) r = Z_OK; + + /* update counters */ + z->avail_out -= n; + z->total_out += n; + + /* update check information */ + if (s->checkfn != Z_NULL) + s->check = (*s->checkfn)(s->check, q, n); + + /* copy */ + zmemcpy(p, q, n); + p += n; + q += n; + } + + /* update pointers */ + z->next_out = p; + s->read = q; + + /* done */ + return r; +} + + +/*+++++*/ +/* inffast.c -- process literals and length/distance pairs fast + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* simplify the use of the inflate_huft type with some defines */ +#define base more.Base +#define next more.Next +#define exop word.what.Exop +#define bits word.what.Bits + +/* macros for bit input with no checking and for returning unused bytes */ +#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} + +/* Called with number of bytes left to write in window at least 258 + (the maximum string length) and number of input bytes available + at least ten. The ten bytes are six bytes for the longest length/ + distance pair plus four bytes for overloading the bit buffer. */ + +local int inflate_fast(bl, bd, tl, td, s, z) +uInt bl, bd; +inflate_huft *tl, *td; +inflate_blocks_statef *s; +z_stream *z; +{ + inflate_huft *t; /* temporary pointer */ + uInt e; /* extra bits or operation */ + uLong b; /* bit buffer */ + uInt k; /* bits in bit buffer */ + Bytef *p; /* input data pointer */ + uInt n; /* bytes available there */ + Bytef *q; /* output window write pointer */ + uInt m; /* bytes to end of window or read pointer */ + uInt ml; /* mask for literal/length tree */ + uInt md; /* mask for distance tree */ + uInt c; /* bytes to copy */ + uInt d; /* distance back to copy from */ + Bytef *r; /* copy source pointer */ + + /* load input, output, bit values */ + LOAD + + /* initialize masks */ + ml = inflate_mask[bl]; + md = inflate_mask[bd]; + + /* do until not enough input or output space for fast loop */ + do { /* assume called with m >= 258 && n >= 10 */ + /* get literal/length code */ + GRABBITS(20) /* max bits for literal/length code */ + if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + continue; + } + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits for length */ + e &= 15; + c = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * length %u\n", c)); + + /* decode distance base of block to copy */ + GRABBITS(15); /* max bits for distance code */ + e = (t = td + ((uInt)b & md))->exop; + do { + DUMPBITS(t->bits) + if (e & 16) + { + /* get extra bits to add to distance base */ + e &= 15; + GRABBITS(e) /* get extra bits (up to 13) */ + d = t->base + ((uInt)b & inflate_mask[e]); + DUMPBITS(e) + Tracevv((stderr, "inflate: * distance %u\n", d)); + + /* do the copy */ + m -= c; + if ((uInt)(q - s->window) >= d) /* offset before dest */ + { /* just copy */ + r = q - d; + *q++ = *r++; c--; /* minimum count is three, */ + *q++ = *r++; c--; /* so unroll loop a little */ + } + else /* else offset after destination */ + { + e = d - (q - s->window); /* bytes from offset to end */ + r = s->end - e; /* pointer to offset */ + if (c > e) /* if source crosses, */ + { + c -= e; /* copy to end of window */ + do { + *q++ = *r++; + } while (--e); + r = s->window; /* copy rest from start of window */ + } + } + do { /* copy all or what's left */ + *q++ = *r++; + } while (--c); + break; + } + else if ((e & 64) == 0) + e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; + else + { + z->msg = "invalid distance code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + break; + } + if ((e & 64) == 0) + { + if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) + { + DUMPBITS(t->bits) + Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? + "inflate: * literal '%c'\n" : + "inflate: * literal 0x%02x\n", t->base)); + *q++ = (Byte)t->base; + m--; + break; + } + } + else if (e & 32) + { + Tracevv((stderr, "inflate: * end of block\n")); + UNGRAB + UPDATE + return Z_STREAM_END; + } + else + { + z->msg = "invalid literal/length code"; + UNGRAB + UPDATE + return Z_DATA_ERROR; + } + } while (1); + } while (m >= 258 && n >= 10); + + /* not enough input or output--restore pointers and return */ + UNGRAB + UPDATE + return Z_OK; +} + + +/*+++++*/ +/* zutil.c -- target dependent utility functions for the compression library + * Copyright (C) 1995 Jean-loup Gailly. + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ + +char *zlib_version = ZLIB_VERSION; + +char *z_errmsg[] = { +"stream end", /* Z_STREAM_END 1 */ +"", /* Z_OK 0 */ +"file error", /* Z_ERRNO (-1) */ +"stream error", /* Z_STREAM_ERROR (-2) */ +"data error", /* Z_DATA_ERROR (-3) */ +"insufficient memory", /* Z_MEM_ERROR (-4) */ +"buffer error", /* Z_BUF_ERROR (-5) */ +""}; + + +/*+++++*/ +/* adler32.c -- compute the Adler-32 checksum of a data stream + * Copyright (C) 1995 Mark Adler + * For conditions of distribution and use, see copyright notice in zlib.h + */ + +/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ + +#define BASE 65521L /* largest prime smaller than 65536 */ +#define NMAX 5552 +/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +#define DO1(buf) {s1 += *buf++; s2 += s1;} +#define DO2(buf) DO1(buf); DO1(buf); +#define DO4(buf) DO2(buf); DO2(buf); +#define DO8(buf) DO4(buf); DO4(buf); +#define DO16(buf) DO8(buf); DO8(buf); + +/* ========================================================================= */ +uLong adler32(adler, buf, len) + uLong adler; + Bytef *buf; + uInt len; +{ + unsigned long s1 = adler & 0xffff; + unsigned long s2 = (adler >> 16) & 0xffff; + int k; + + if (buf == Z_NULL) return 1L; + + while (len > 0) { + k = len < NMAX ? len : NMAX; + len -= k; + while (k >= 16) { + DO16(buf); + k -= 16; + } + if (k != 0) do { + DO1(buf); + } while (--k); + s1 %= BASE; + s2 %= BASE; + } + return (s2 << 16) | s1; +} diff -Nru a/arch/ppc/boot/mbx/Makefile b/arch/ppc/boot/mbx/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/mbx/Makefile Mon May 21 17:07:04 2001 @@ -0,0 +1,127 @@ +# BK Id: %F% %I% %G% %U% %#% +# +# +# arch/ppc/mbxboot/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Copyright (C) 1994 by Linus Torvalds +# Adapted for PowerPC by Gary Thomas +# modified by Cort (cort@cs.nmt.edu) +# +.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.embedded + +OFFSET := ../utils/offset +SIZE := ../utils/size + +LIBS := ../lib/zlib.a +OBJCOPY_ARGS := -O elf32-powerpc + +ifdef CONFIG_8xx +ZLINKFLAGS := -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00180000 +OBJECTS := head.o m8xx_tty.o +CFLAGS += -DCONFIG_8xx +endif + +ifdef CONFIG_8260 +ZLINKFLAGS := -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00400000 +OBJECTS := head_8260.o m8260_tty.o embed_config.o +CFLAGS += -DCONFIG_8260 +endif + +OBJECTS += ../common/misc-common.o misc.o ../common/string.o +OBJCOPY_ARGS = -O elf32-powerpc + +ifeq ($(CONFIG_MBX),y) +OBJECTS += iic.o embed_config.o pci.o qspan_pci.o +CFLAGS += -DCONFIG_MBX +endif +ifeq ($(CONFIG_RPXLITE),y) +CFLAGS += -DCONFIG_RPXLITE +OBJECTS += iic.o embed_config.o +endif +ifeq ($(CONFIG_RPXCLASSIC),y) +CFLAGS += -DCONFIG_RPXCLASSIC +OBJECTS += iic.o embed_config.o pci.o qspan_pci.o +endif +ifeq ($(CONFIG_BSEIP),y) +CFLAGS += -DCONFIG_BSEIP +OBJECTS += iic.o embed_config.o +endif +ifeq ($(CONFIG_FADS),y) +CFLAGS += -DCONFIG_FADS +OBJECTS += embed_config.o +endif + +all: zImage + +misc.o: misc.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 misc.o misc.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 ../images/$@.mbx + +zImage: zvmlinux + ln -sf zvmlinux.mbx ../images/zImage.mbx + +zImage.initrd: zvmlinux.initrd + ln -sf zvmlinux.initrd.mbx ../images/zImage.initrd.mbx + +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 misc.o misc.c + $(LD) $(ZLINKFLAGS) -o $@.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz \ + $@.tmp ../images/$@.mbx +# Remove zvmlinux and zvmlinux.temp, we have ../images/zvmlinux.mbx + rm -f $@.tmp $@ + +znetboot : zImage + cp ../images/zImage.mbx $(TFTPIMAGE) + +znetboot.initrd : zImage.initrd + cp ../images/zImage.initrd.mbx $(TFTPIMAGE) + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/mbx/embed_config.c b/arch/ppc/boot/mbx/embed_config.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/mbx/embed_config.c Mon May 21 17:07:03 2001 @@ -0,0 +1,593 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ + +/* Board specific functions for those embedded 8xx boards that do + * not have boot monitor support for board information. + */ +#include +#include +#ifdef CONFIG_8xx +#include +#endif +#ifdef CONFIG_8260 +#include +#include +#endif + + +/* IIC functions. + * These are just the basic master read/write operations so we can + * examine serial EEPROM. + */ +extern void iic_read(uint devaddr, u_char *buf, uint offset, uint count); +static u_char aschex_to_byte(u_char *cp); + +/* Supply a default Ethernet address for those eval boards that don't + * ship with one. This is an address from the MBX board I have, so + * it is unlikely you will find it on your network. + */ +static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 }; + +#if defined(CONFIG_MBX) + +/* The MBX hands us a pretty much ready to go board descriptor. This + * is where the idea started in the first place. + */ +void +embed_config(bd_t *bd) +{ + u_char *mp; + u_char eebuf[128]; + int i; + + /* Read the first 128 bytes of the EEPROM. There is more, + * but this is all we need. + */ + iic_read(0xa4, eebuf, 0, 128); + + /* All we are looking for is the Ethernet MAC address. The + * first 8 bytes are 'MOTOROLA', so check for part of that. + * If it's there, assume we have a valid MAC address. If not, + * grab our default one. + */ + if ((*(uint *)eebuf) == 0x4d4f544f) + mp = &eebuf[0x4c]; + else + mp = (u_char *)def_enet_addr; + + for (i=0; i<6; i++) { + bd->bi_enetaddr[i] = *mp++; + } + + /* The boot rom passes these to us in MHz. Linux now expects + * them to be in Hz. + */ + bd->bi_intfreq *= 1000000; + bd->bi_busfreq *= 1000000; + + /* Stuff a baud rate here as well. + */ + bd->bi_baudrate = 9600; +} +#endif /* CONFIG_MBX */ + +#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) || defined(CONFIG_RPX6) + +/* Helper functions for Embedded Planet boards. +*/ +static void +rpx_eth(bd_t *bd, u_char *cp) +{ + int i; + + for (i=0; i<6; i++) { + bd->bi_enetaddr[i] = aschex_to_byte(cp); + cp += 2; + } +} + +static uint +rpx_baseten(u_char *cp) +{ + uint retval; + + retval = 0; + + while (*cp != '\n') { + retval *= 10; + retval += (*cp) - '0'; + cp++; + } + return(retval); +} + +static void +rpx_brate(bd_t *bd, u_char *cp) +{ + uint rate; + + rate = 0; + + while (*cp != '\n') { + rate *= 10; + rate += (*cp) - '0'; + cp++; + } + + bd->bi_baudrate = rate * 100; +} + +static void +rpx_memsize(bd_t *bd, u_char *cp) +{ + uint size; + + size = 0; + + while (*cp != '\n') { + size *= 10; + size += (*cp) - '0'; + cp++; + } + + bd->bi_memsize = size * 1024 * 1024; +} + +static void +rpx_cpuspeed(bd_t *bd, u_char *cp) +{ + uint num, den; + + num = den = 0; + + while (*cp != '\n') { + num *= 10; + num += (*cp) - '0'; + cp++; + if (*cp == '/') { + cp++; + den = (*cp) - '0'; + break; + } + } + + /* I don't know why the RPX just can't state the actual + * CPU speed..... + */ + if (den) { + num /= den; + num *= den; + } + bd->bi_intfreq = bd->bi_busfreq = num * 1000000; + + /* The 8xx can only run a maximum 50 MHz bus speed (until + * Motorola changes this :-). Greater than 50 MHz parts + * run internal/2 for bus speed. + */ + if (num > 50) + bd->bi_busfreq /= 2; +} + +/* Because I didn't find anything that would do this....... +*/ +u_char +aschex_to_byte(u_char *cp) +{ + u_char byte, c; + + c = *cp++; + + if ((c >= 'A') && (c <= 'F')) { + c -= 'A'; + c += 10; + } + else if ((c >= 'a') && (c <= 'f')) { + c -= 'a'; + c += 10; + } + else { + c -= '0'; + } + + byte = c * 16; + + c = *cp; + + if ((c >= 'A') && (c <= 'F')) { + c -= 'A'; + c += 10; + } + else if ((c >= 'a') && (c <= 'f')) { + c -= 'a'; + c += 10; + } + else { + c -= '0'; + } + + byte += c; + + return(byte); +} +#endif + +#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) + +/* Read the EEPROM on the RPX-Lite board. +*/ +void +embed_config(bd_t *bd) +{ + u_char eebuf[256], *cp; + + /* Read the first 256 bytes of the EEPROM. I think this + * is really all there is, and I hope if it gets bigger the + * info we want is still up front. + */ +#if 1 + iic_read(0xa8, eebuf, 0, 128); + iic_read(0xa8, &eebuf[128], 128, 128); + + /* We look for two things, the Ethernet address and the + * serial baud rate. The records are separated by + * newlines. + */ + cp = eebuf; + for (;;) { + if (*cp == 'E') { + cp++; + if (*cp == 'A') { + cp += 2; + rpx_eth(bd, cp); + } + } + if (*cp == 'S') { + cp++; + if (*cp == 'B') { + cp += 2; + rpx_brate(bd, cp); + } + } + if (*cp == 'D') { + cp++; + if (*cp == '1') { + cp += 2; + rpx_memsize(bd, cp); + } + } + if (*cp == 'H') { + cp++; + if (*cp == 'Z') { + cp += 2; + rpx_cpuspeed(bd, cp); + } + } + + /* Scan to the end of the record. + */ + while ((*cp != '\n') && (*cp != 0xff)) + cp++; + + /* If the next character is a 0 or ff, we are done. + */ + cp++; + if ((*cp == 0) || (*cp == 0xff)) + break; + } + bd->bi_memstart = 0; +#else + /* For boards without initialized EEPROM. + */ + bd->bi_memstart = 0; + bd->bi_memsize = (8 * 1024 * 1024); + bd->bi_intfreq = 48000000; + bd->bi_busfreq = 48000000; + bd->bi_baudrate = 9600; +#endif +} +#endif /* RPXLITE || RPXCLASSIC */ + +#ifdef CONFIG_BSEIP +/* Build a board information structure for the BSE ip-Engine. + * There is more to come since we will add some environment + * variables and a function to read them. + */ +void +embed_config(bd_t *bd) +{ + u_char *cp; + int i; + + /* Baud rate and processor speed will eventually come + * from the environment variables. + */ + bd->bi_baudrate = 9600; + + /* Get the Ethernet station address from the Flash ROM. + */ + cp = (u_char *)0xfe003ffa; + for (i=0; i<6; i++) { + bd->bi_enetaddr[i] = *cp++; + } + + /* The rest of this should come from the environment as well. + */ + bd->bi_memstart = 0; + bd->bi_memsize = (16 * 1024 * 1024); + bd->bi_intfreq = 48000000; + bd->bi_busfreq = 48000000; +} +#endif /* BSEIP */ + +#ifdef CONFIG_FADS +/* Build a board information structure for the FADS. + */ +void +embed_config(bd_t *bd) +{ + u_char *cp; + int i; + + /* Just fill in some known values. + */ + bd->bi_baudrate = 9600; + + /* Use default enet. + */ + cp = (u_char *)def_enet_addr; + for (i=0; i<6; i++) { + bd->bi_enetaddr[i] = *cp++; + } + + bd->bi_memstart = 0; + bd->bi_memsize = (8 * 1024 * 1024); + bd->bi_intfreq = 40000000; + bd->bi_busfreq = 40000000; +} +#endif /* FADS */ + +#ifdef CONFIG_8260 +/* Compute 8260 clock values if the rom doesn't provide them. + * We can't compute the internal core frequency (I don't know how to + * do that). + */ +static void +clk_8260(bd_t *bd) +{ + uint scmr, vco_out, clkin; + uint plldf, pllmf, busdf, brgdf, cpmdf; + volatile immap_t *ip; + + ip = (immap_t *)IMAP_ADDR; + scmr = ip->im_clkrst.car_scmr; + + /* The clkin is always bus frequency. + */ + clkin = bd->bi_busfreq; + + /* Collect the bits from the scmr. + */ + plldf = (scmr >> 12) & 1; + pllmf = scmr & 0xfff; + cpmdf = (scmr >> 16) & 0x0f; + busdf = (scmr >> 20) & 0x0f; + + /* This is arithmetic from the 8260 manual. + */ + vco_out = clkin / (plldf + 1); + vco_out *= 2 * (pllmf + 1); + bd->bi_vco = vco_out; /* Save for later */ + + bd->bi_cpmfreq = vco_out / 2; /* CPM Freq, in MHz */ + + /* Set Baud rate divisor. The power up default is divide by 16, + * but we set it again here in case it was changed. + */ + ip->im_clkrst.car_sccr = 1; /* DIV 16 BRG */ + bd->bi_brgfreq = vco_out / 16; +} +#endif + +#ifdef CONFIG_EST8260 +void +embed_config(bd_t **bdp) +{ + u_char *cp; + int i; + bd_t *bd; + + bd = *bdp; +#if 0 + /* This is actually provided by my boot rom. I have it + * here for those people that may load the kernel with + * a JTAG/COP tool and not the rom monitor. + */ + bd->bi_baudrate = 115200; + bd->bi_intfreq = 200000000; + bd->bi_busfreq = 66666666; + bd->bi_cpmfreq = 66666666; + bd->bi_brgfreq = 33333333; + bd->bi_memsize = 16 * 1024 * 1024; +#else + /* The boot rom passes these to us in MHz. Linux now expects + * them to be in Hz. + */ + bd->bi_intfreq *= 1000000; + bd->bi_busfreq *= 1000000; + bd->bi_cpmfreq *= 1000000; + bd->bi_brgfreq *= 1000000; +#endif + + cp = (u_char *)def_enet_addr; + for (i=0; i<6; i++) { + bd->bi_enetaddr[i] = *cp++; + } +} +#endif /* EST8260 */ + +#ifdef CONFIG_SBS8260 +/* We have to fill in everything. +*/ +static bd_t bdinfo; + +void +embed_config(bd_t **bdp) +{ + u_char *cp; + int i; + bd_t *bd; + + /* This should provided by the boot rom. + */ + bd = &bdinfo; + *bdp = bd; + bd->bi_baudrate = 9600; + bd->bi_memsize = 64 * 1024 * 1024; + + /* Set all of the clocks. We have to know the speed of the + * external clock. The development board had 66 MHz. + */ + bd->bi_busfreq = 66666666; + clk_8260(bd); + + /* I don't know how to compute this yet. + */ + bd->bi_intfreq = 133000000; + + + cp = (u_char *)def_enet_addr; + for (i=0; i<6; i++) { + bd->bi_enetaddr[i] = *cp++; + } +} +#endif /* SBS8260 */ + +#ifdef CONFIG_RPX6 +/* The pointer we are given is for the string of key values. + */ +static bd_t bdinfo; + +void +embed_config(bd_t **bdp) +{ + u_char *cp, *keyvals; + int i; + bd_t *bd; + + keyvals = (u_char *)*bdp; + + bd = &bdinfo; + *bdp = bd; + + /* This is almost identical to the RPX-Lite/Classic functions + * on the 8xx boards. It would be nice to have a key lookup + * function in a string, but the format of all of the fields + * is slightly different. + */ + cp = keyvals; + for (;;) { + if (*cp == 'E') { + cp++; + if (*cp == 'A') { + cp += 2; + rpx_eth(bd, cp); + } + } + if (*cp == 'S') { + cp++; + if (*cp == 'B') { + cp += 2; + bd->bi_baudrate = rpx_baseten(cp); + } + } + if (*cp == 'D') { + cp++; + if (*cp == '1') { + cp += 2; + bd->bi_memsize = rpx_baseten(cp) * 1024 * 1024; + } + } + if (*cp == 'X') { + cp++; + if (*cp == 'T') { + cp += 2; + bd->bi_busfreq = rpx_baseten(cp); + } + } + if (*cp == 'N') { + cp++; + if (*cp == 'V') { + cp += 2; + bd->bi_nvsize = rpx_baseten(cp) * 1024 * 1024; + } + } + + /* Scan to the end of the record. + */ + while ((*cp != '\n') && (*cp != 0xff)) + cp++; + + /* If the next character is a 0 or ff, we are done. + */ + cp++; + if ((*cp == 0) || (*cp == 0xff)) + break; + } + bd->bi_memstart = 0; + + /* The memory size includes both the 60x and local bus DRAM. + * I don't want to use the local bus DRAM for real memory, + * so subtract it out. It would be nice if they were separate + * keys. + */ + bd->bi_memsize -= 32 * 1024 * 1024; + + /* Set all of the clocks. We have to know the speed of the + * external clock. + */ + clk_8260(bd); + + /* I don't know how to compute this yet. + */ + bd->bi_intfreq = 200000000; +} +#endif /* RPX6 for testing */ + +#ifdef CONFIG_ADS8260 +/* We have to fill in everything. +*/ +static bd_t bdinfo; + +void +embed_config(bd_t **bdp) +{ + u_char *cp; + int i; + bd_t *bd; + + /* This should provided by the boot rom. + */ + bd = &bdinfo; + *bdp = bd; + bd->bi_baudrate = 9600; + bd->bi_memsize = 16 * 1024 * 1024; + + /* Set all of the clocks. We have to know the speed of the + * external clock. The development board had 66 MHz. + */ + bd->bi_busfreq = 66666666; + clk_8260(bd); + + /* I don't know how to compute this yet. + */ + bd->bi_intfreq = 200000000; + + + cp = (u_char *)def_enet_addr; + for (i=0; i<6; i++) { + bd->bi_enetaddr[i] = *cp++; + } +} +#endif /* ADS8260 */ + diff -Nru a/arch/ppc/boot/mbx/gzimage.c b/arch/ppc/boot/mbx/gzimage.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/mbx/gzimage.c Mon May 21 17:07:04 2001 @@ -0,0 +1,11 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * gzimage.c + * + * Dummy file to allow a compressed zImage to be added + * into a linker section, accessed by the boot coode + */ + +char dummy_for_gzimage; diff -Nru a/arch/ppc/boot/mbx/head.S b/arch/ppc/boot/mbx/head.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/mbx/head.S Mon May 21 17:07:04 2001 @@ -0,0 +1,243 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +#include +#include "../../kernel/ppc_defs.h" +#include "../../kernel/ppc_asm.tmpl" +#include +#include + + .text + +/* + * This code is loaded by the ROM loader at some arbitrary location. + * Move it to high memory so that it can load the kernel at 0x0000. + * + * This is a three step process that will also work when booting from + * a Flash PROM normally located in high memory. + * + * First, the entire image is loaded into some high memory address. + * This is usually at or above 0x02000000. This is done by a network + * boot function supported by the board or a debugger over BDM port. + * + * Second, the start up function here will relocate the decompress + * function to run at the link address of 0x01000000. + * + * Last, the decompression function will reloate the initrd, zImage, and + * the residual data to locations under 8 Meg. This is necessary because + * the embedded kernel start up uses 8 Meg translations to access physical + * space before the MMU is enabled. Finally, the zImage is uncompressed + * to location 0 and we jump to it. + * + * On the MBX, + * R1 - Stack pointer at a high memory address. + * R3 - Pointer to Board Information Block. + * R4 - Pointer to argument string. + * Interrupts masked, cache and MMU disabled. + * + * ...and the first and second functions listed above are + * done for us (it knows ELF images). + * + * For other embedded boards we build the Board Information Block. + */ + + .globl start +start: + bl start_ +start_: +#ifndef CONFIG_MBX + lis r11, local_bd_info@h + ori r11, r11, local_bd_info@l +#else + mr r11, r3 +#endif + + mfmsr r3 /* Turn off interrupts */ + li r4,0 + ori r4,r4,MSR_EE + andc r3,r3,r4 + mtmsr r3 + + li r4,0 /* Zero DER to prevent FRZ */ + mtspr SPRN_DER,r4 + +/* 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 +#if 0 + cmp 0,r3,r4 + beq start_ldr /* Branch if loaded OK */ +#endif + +/* + * no matter where we're loaded, move ourselves to -Ttext address + * This computes the sizes we need to determine other things. + */ + 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: +/* Most 8xx boards don't boot up with the I-cache enabled. Do that + * now because the decompress runs much faster that way. + */ + lis r3, IDC_INVALL@h + mtspr IC_CST, r3 + lis r3, IDC_ENABLE@h + mtspr IC_CST, r3 + +/* Clear all of BSS */ + 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 + + 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 + + /* Perform configuration of the various boards. This is done + * by reading some configuration data from EEPROM and building + * the board information structure. + */ + mr r3, r11 + mr r21, r11 + mr r22, r8 + mr r23, r7 + mr r24, r6 + + bl embed_config + mr r3, r21 + bl serial_init /* Init MBX serial port */ + + mr r11, r21 + mr r8, r22 + mr r7, r23 + mr r6, r24 + +#ifdef CONFIG_MBX + /* On the MBX (or anything that will TFTP load an ELF image), + * we have to find the intermediate address. The ELF loader + * only moves the Linux boostrap/decompress, not the zImage. + */ +#define ILAP_ADDRESS 0xfa000020 + lis r8, ILAP_ADDRESS@h + lwz r8, ILAP_ADDRESS@l(r8) + addis r8, r8, 1 /* Add 64K */ +#endif + + mr r3,r8 /* Load point */ + mr r4,r7 /* Program length */ + mr r5,r6 /* Checksum */ + mr r6,r11 /* Residual data */ + bl decompress_kernel + + /* changed to use r3 (as firmware does) for kernel + as ptr to residual -- Cort*/ + 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) + + /* The world starts from the beginning. + */ + li r9,0x0 + mtlr r9 + + /* Invalidate the instruction cache because we just copied a + * bunch of kernel instructions. + */ + lis r9, IDC_INVALL@h + mtspr IC_CST, r9 + + blr +hang: + b hang + +/* + * Delay for a number of microseconds + * -- Use the BUS timer (assumes 66MHz) + */ + .globl udelay +udelay: + 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_MSR +_get_MSR: + mfmsr r3 + blr + +.globl _put_MSR +_put_MSR: + mtmsr r3 + blr + + .comm .stack,4096*2,4 +#ifndef CONFIG_MBX +local_bd_info: + .long 0 + .long 0x01000000 + .long 64 + .long 64 + .long 0 + .long 0 + .long 0 +#endif diff -Nru a/arch/ppc/boot/mbx/head_8260.S b/arch/ppc/boot/mbx/head_8260.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/mbx/head_8260.S Mon May 21 17:07:03 2001 @@ -0,0 +1,259 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +#include "../../kernel/ppc_defs.h" +#include "../../kernel/ppc_asm.tmpl" +#include +#include + + .text + +/* + * Boot loader philosophy: + * + * ROM loads us to some arbitrary location + * ROM loads these registers: + * + * R3 = Pointer to the board configuration data + * R5 = Pointer to Open Firmware data + * + * ROM jumps to start/start_ + * Move the boot code to the link address (4 MB) + * Call decompress_kernel() + * Relocate the initrd, zimage and residual data to 4 MB + * Decompress the kernel to 0 + * Jump to the kernel entry + * -- Cort + */ + .globl start +start: + bl start_ +start_: + mr r11,r3 /* Save pointer to residual/board data */ + mr r25,r5 /* Save OFW pointer */ + li r3,MSR_IP /* Establish default MSR value */ + mtmsr r3 + +/* 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 */ + 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 + + /* Speed us up a little. + */ + bl flush_instruction_cache + +/* Run loader */ + mr r3,r8 /* Load point */ + mr r4,r7 /* Program length */ + mr r5,r6 /* Checksum */ + mr r6,r11 /* Residual data */ + mr r7,r25 /* OFW interfaces */ + bl decompress_kernel + + /* changed to use r3 (as firmware does) for kernel + as ptr to residual -- Cort*/ + 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) + + /* tell kernel we're prep */ + /* + * get start address of kernel code which is stored as a coff + * entry. see boot/head.S -- Cort + */ + li r9,0x4 + mtlr r9 + lis r10,0xdeadc0de@h + ori r10,r10,0xdeadc0de@l + li r9,0 + stw r10,0(r9) +/* + * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2 + * so disable BATs before setting this to avoid a clash + */ + li r8,0 + mtspr DBAT0U,r8 + mtspr DBAT1U,r8 + mtspr DBAT2U,r8 + mtspr DBAT3U,r8 + mtspr IBAT0U,r8 + mtspr IBAT1U,r8 + mtspr IBAT2U,r8 + mtspr IBAT3U,r8 + + 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/mbx/iic.c b/arch/ppc/boot/mbx/iic.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/mbx/iic.c Mon May 21 17:07:05 2001 @@ -0,0 +1,218 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ + +/* Minimal support functions to read configuration from IIC EEPROMS + * on MPC8xx boards. Originally written for RPGC RPX-Lite. + * Dan Malek (dmalek@jlc.net). + */ +#include +#include +#include +#include "../../8xx_io/commproc.h" + + +/* IIC functions. + * These are just the basic master read/write operations so we can + * examine serial EEPROM. + */ +void iic_read(uint devaddr, u_char *buf, uint offset, uint count); + +static int iic_init_done; + +static void +iic_init() +{ + volatile iic_t *iip; + volatile i2c8xx_t *i2c; + volatile cpm8xx_t *cp; + volatile immap_t *immap; + uint dpaddr; + + immap = (immap_t *)IMAP_ADDR; + cp = (cpm8xx_t *)&(immap->im_cpm); + + /* Reset the CPM. This is necessary on the 860 processors + * that may have started the SCC1 ethernet without relocating + * the IIC. + * This also stops the Ethernet in case we were loaded by a + * BOOTP rom monitor. + */ + cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG); + + /* Wait for it. + */ + while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG)); + + /* Remove any microcode patches. We will install our own + * later. + */ + cp->cp_cpmcr1 = 0; + cp->cp_cpmcr2 = 0; + cp->cp_cpmcr3 = 0; + cp->cp_cpmcr4 = 0; + cp->cp_rccr = 0; + + iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; + i2c = (i2c8xx_t *)&(immap->im_i2c); + + /* Initialize Port B IIC pins. + */ + cp->cp_pbpar |= 0x00000030; + cp->cp_pbdir |= 0x00000030; + cp->cp_pbodr |= 0x00000030; + + /* Initialize the parameter ram. + */ + + /* Allocate space for a two transmit and one receive buffer + * descriptor in the DP ram. + * For now, this address seems OK, but it may have to + * change with newer versions of the firmware. + */ + dpaddr = 0x0840; + + /* Set up the IIC parameters in the parameter ram. + */ + iip->iic_tbase = dpaddr; + iip->iic_rbase = dpaddr + (2 * sizeof(cbd_t)); + + iip->iic_tfcr = SMC_EB; + iip->iic_rfcr = SMC_EB; + + /* This should really be done by the reader/writer. + */ + iip->iic_mrblr = 128; + + /* Initialize Tx/Rx parameters. + */ + 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; + + /* Enable SDMA. + */ + immap->im_siu_conf.sc_sdcr = 1; + + iic_init_done = 1; +} + +/* Read from IIC. + * Caller provides device address, memory buffer, and byte count. + */ +static u_char iitemp[32]; + +void +iic_read(uint devaddr, u_char *buf, uint offset, uint count) +{ + volatile iic_t *iip; + volatile i2c8xx_t *i2c; + volatile cbd_t *tbdf, *rbdf; + volatile cpm8xx_t *cp; + volatile immap_t *immap; + u_char *tb; + uint temp; + + /* If the interface has not been initialized, do that now. + */ + if (!iic_init_done) + iic_init(); + + immap = (immap_t *)IMAP_ADDR; + cp = (cpm8xx_t *)&(immap->im_cpm); + + iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; + i2c = (i2c8xx_t *)&(immap->im_i2c); + + tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; + rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase]; + + /* Send a "dummy write" operation. This is a write request with + * only the offset sent, followed by another start condition. + * This will ensure we start reading from the first location + * of the EEPROM. + */ + tb = iitemp; + tb = (u_char *)(((uint)tb + 15) & ~15); + tbdf->cbd_bufaddr = (int)tb; + *tb = devaddr & 0xfe; /* Device address */ + *(tb+1) = offset; /* Offset */ + tbdf->cbd_datlen = 2; /* Length */ + tbdf->cbd_sc = + BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START; + + i2c->i2c_i2mod = 1; /* Enable */ + i2c->i2c_i2cer = 0xff; + i2c->i2c_i2com = 0x81; /* Start master */ + + /* Wait for IIC transfer. + */ +#if 0 + while ((i2c->i2c_i2cer & 3) == 0); + + if (tbdf->cbd_sc & BD_SC_READY) + printf("IIC ra complete but tbuf ready\n"); +#else + temp = 10000000; + while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0)) + temp--; +#if 0 + /* We can't do this...there is no serial port yet! + */ + if (temp == 0) { + printf("Timeout reading EEPROM\n"); + return; + } +#endif +#endif + + /* Chip errata, clear enable. + */ + i2c->i2c_i2mod = 0; + + /* 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). + */ + tbdf->cbd_bufaddr = (int)tb; + *tb = devaddr | 1; /* Device address */ + rbdf->cbd_bufaddr = (uint)buf; /* Desination buffer */ + tbdf->cbd_datlen = rbdf->cbd_datlen = count + 1; /* Length */ + tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START; + rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; + + /* Chip bug, set enable here. + */ + i2c->i2c_i2mod = 1; /* Enable */ + i2c->i2c_i2cer = 0xff; + i2c->i2c_i2com = 0x81; /* Start master */ + + /* Wait for IIC transfer. + */ +#if 0 + while ((i2c->i2c_i2cer & 1) == 0); + + if (rbdf->cbd_sc & BD_SC_EMPTY) + printf("IIC read complete but rbuf empty\n"); +#else + temp = 10000000; + while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0)) + temp--; +#endif + + /* Chip errata, clear enable. + */ + i2c->i2c_i2mod = 0; +} diff -Nru a/arch/ppc/boot/mbx/m8260_tty.c b/arch/ppc/boot/mbx/m8260_tty.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/mbx/m8260_tty.c Mon May 21 17:07:04 2001 @@ -0,0 +1,312 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ + + +/* Minimal serial functions needed to send messages out the serial + * port on SMC1. + */ +#include +#include +#include + +uint no_print; +extern char *params[]; +extern int nparams; +static u_char cons_hold[128], *sgptr; +static int cons_hold_cnt; + +/* If defined, enables serial console. The value (1 through 4) + * should designate which SCC is used, but this isn't complete. Only + * SCC1 is known to work at this time. + */ +#ifdef CONFIG_SCC_CONSOLE +#define SCC_CONSOLE 1 +#endif + +void +serial_init(bd_t *bd) +{ + volatile smc_t *sp; + volatile smc_uart_t *up; + volatile scc_t *sccp; + volatile scc_uart_t *sup; + volatile cbd_t *tbdf, *rbdf; + volatile immap_t *ip; + volatile iop8260_t *io; + volatile cpm8260_t *cp; + uint dpaddr, memaddr; + + ip = (immap_t *)IMAP_ADDR; + cp = &ip->im_cpm; + io = &ip->im_ioport; + + /* Perform a reset. + */ + cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG); + + /* Wait for it. + */ + while (cp->cp_cpcr & CPM_CR_FLG); + +#ifdef CONFIG_ADS8260 + /* Enable the RS-232 transceivers. + */ + *(volatile uint *)(BCSR_ADDR + 4) &= + ~(BCSR1_RS232_EN1 | BCSR1_RS232_EN2); +#endif + +#ifdef SCC_CONSOLE + sccp = (scc_t *)&(ip->im_scc[SCC_CONSOLE-1]); + sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; + sccp->scc_sccm &= ~(UART_SCCM_TX | UART_SCCM_RX); + sccp->scc_gsmrl &= ~(SCC_GSMRL_ENR | SCC_GSMRL_ENT); + + /* Use Port D for SCC1 instead of other functions. + */ + io->iop_ppard |= 0x00000003; + io->iop_psord &= ~0x00000001; /* Rx */ + io->iop_psord |= 0x00000002; /* Tx */ + io->iop_pdird &= ~0x00000001; /* Rx */ + io->iop_pdird |= 0x00000002; /* Tx */ + +#else + sp = (smc_t*)&(ip->im_smc[0]); + *(ushort *)(&ip->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1; + up = (smc_uart_t *)&ip->im_dprambase[PROFF_SMC1]; + + /* Disable transmitter/receiver. + */ + sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); + + /* Use Port D for SMC1 instead of other functions. + */ + io->iop_ppard |= 0x00c00000; + io->iop_pdird |= 0x00400000; + io->iop_pdird &= ~0x00800000; + io->iop_psord &= ~0x00c00000; +#endif + + /* Allocate space for two buffer descriptors in the DP ram. + * For now, this address seems OK, but it may have to + * change with newer versions of the firmware. + */ + dpaddr = 0x0800; + + /* Grab a few bytes from the top of memory. + */ + memaddr = (bd->bi_memsize - 256) & ~15; + + /* Set the physical address of the host memory buffers in + * the buffer descriptors. + */ + rbdf = (cbd_t *)&ip->im_dprambase[dpaddr]; + rbdf->cbd_bufaddr = memaddr; + rbdf->cbd_sc = 0; + tbdf = rbdf + 1; + tbdf->cbd_bufaddr = memaddr+128; + tbdf->cbd_sc = 0; + + /* Set up the uart parameters in the parameter ram. + */ +#ifdef SCC_CONSOLE + sup->scc_genscc.scc_rbase = dpaddr; + sup->scc_genscc.scc_tbase = dpaddr + sizeof(cbd_t); + + /* Set up the uart parameters in the + * parameter ram. + */ + sup->scc_genscc.scc_rfcr = CPMFCR_GBL | CPMFCR_EB; + sup->scc_genscc.scc_tfcr = CPMFCR_GBL | CPMFCR_EB; + + sup->scc_genscc.scc_mrblr = 128; + sup->scc_maxidl = 8; + sup->scc_brkcr = 1; + sup->scc_parec = 0; + sup->scc_frmec = 0; + sup->scc_nosec = 0; + sup->scc_brkec = 0; + sup->scc_uaddr1 = 0; + sup->scc_uaddr2 = 0; + sup->scc_toseq = 0; + sup->scc_char1 = 0x8000; + sup->scc_char2 = 0x8000; + sup->scc_char3 = 0x8000; + sup->scc_char4 = 0x8000; + sup->scc_char5 = 0x8000; + sup->scc_char6 = 0x8000; + sup->scc_char7 = 0x8000; + sup->scc_char8 = 0x8000; + sup->scc_rccm = 0xc0ff; + + /* Send the CPM an initialize command. + */ + cp->cp_cpcr = mk_cr_cmd(CPM_CR_SCC1_PAGE, CPM_CR_SCC1_SBLOCK, 0, + CPM_CR_INIT_TRX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + + /* Set UART mode, 8 bit, no parity, one stop. + * Enable receive and transmit. + */ + sccp->scc_gsmrh = 0; + sccp->scc_gsmrl = + (SCC_GSMRL_MODE_UART | SCC_GSMRL_TDCR_16 | SCC_GSMRL_RDCR_16); + + /* Disable all interrupts and clear all pending + * events. + */ + sccp->scc_sccm = 0; + sccp->scc_scce = 0xffff; + sccp->scc_dsr = 0x7e7e; + sccp->scc_pmsr = 0x3000; + + /* Wire BRG1 to SCC1. The console driver will take care of + * others. + */ + ip->im_cpmux.cmx_scr = 0; +#else + up->smc_rbase = dpaddr; + up->smc_tbase = dpaddr+sizeof(cbd_t); + up->smc_rfcr = CPMFCR_EB; + up->smc_tfcr = CPMFCR_EB; + up->smc_brklen = 0; + up->smc_brkec = 0; + up->smc_brkcr = 0; + up->smc_mrblr = 128; + up->smc_maxidl = 8; + + /* Set UART mode, 8 bit, no parity, one stop. + * Enable receive and transmit. + */ + sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; + + /* Mask all interrupts and remove anything pending. + */ + sp->smc_smcm = 0; + sp->smc_smce = 0xff; + + /* Set up the baud rate generator. + */ + ip->im_cpmux.cmx_smr = 0; +#endif + + /* The baud rate divisor needs to be coordinated with clk_8260(). + */ + ip->im_brgc1 = + (((bd->bi_brgfreq/16) / bd->bi_baudrate) << 1) | + CPM_BRG_EN; + + /* Make the first buffer the only buffer. + */ + tbdf->cbd_sc |= BD_SC_WRAP; + rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; + + /* Initialize Tx/Rx parameters. + */ +#ifdef SCC_CONSOLE + sccp->scc_gsmrl |= (SCC_GSMRL_ENR | SCC_GSMRL_ENT); +#else + cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + + /* Enable transmitter/receiver. + */ + sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; +#endif +} + +void +serial_putc(void *ignored, const char c) +{ + volatile cbd_t *tbdf; + volatile char *buf; + volatile smc_uart_t *up; + volatile scc_uart_t *sup; + volatile immap_t *ip; + extern bd_t *board_info; + + ip = (immap_t *)IMAP_ADDR; +#ifdef SCC_CONSOLE + sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; + tbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_tbase]; +#else + up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); + tbdf = (cbd_t *)&ip->im_dprambase[up->smc_tbase]; +#endif + + /* Wait for last character to go. + */ + buf = (char *)tbdf->cbd_bufaddr; + while (tbdf->cbd_sc & BD_SC_READY); + + *buf = c; + tbdf->cbd_datlen = 1; + tbdf->cbd_sc |= BD_SC_READY; +} + +char +serial_getc(void *ignored) +{ + char c; + + if (cons_hold_cnt <= 0) { + cons_hold_cnt = serial_readbuf(cons_hold); + sgptr = cons_hold; + } + c = *sgptr++; + cons_hold_cnt--; + + return(c); +} + +int +serial_readbuf(u_char *cbuf) +{ + volatile cbd_t *rbdf; + volatile char *buf; + volatile smc_uart_t *up; + volatile scc_uart_t *sup; + volatile immap_t *ip; + int i, nc; + + ip = (immap_t *)IMAP_ADDR; + +#ifdef SCC_CONSOLE + sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; + rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; +#else + up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); + rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; +#endif + + /* Wait for character to show up. + */ + buf = (char *)rbdf->cbd_bufaddr; + while (rbdf->cbd_sc & BD_SC_EMPTY); + nc = rbdf->cbd_datlen; + for (i=0; icbd_sc |= BD_SC_EMPTY; + + return(nc); +} + +int +serial_tstc(void *ignored) +{ + volatile cbd_t *rbdf; + volatile smc_uart_t *up; + volatile scc_uart_t *sup; + volatile immap_t *ip; + + ip = (immap_t *)IMAP_ADDR; +#ifdef SCC_CONSOLE + sup = (scc_uart_t *)&ip->im_dprambase[PROFF_SCC1 + ((SCC_CONSOLE-1) << 8)]; + rbdf = (cbd_t *)&ip->im_dprambase[sup->scc_genscc.scc_rbase]; +#else + up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); + rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; +#endif + + return(!(rbdf->cbd_sc & BD_SC_EMPTY)); +} diff -Nru a/arch/ppc/boot/mbx/m8xx_tty.c b/arch/ppc/boot/mbx/m8xx_tty.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/mbx/m8xx_tty.c Mon May 21 17:07:04 2001 @@ -0,0 +1,288 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ + + +/* Minimal serial functions needed to send messages out the serial + * port on the MBX console. + * + * The MBX uxes SMC1 for the serial port. We reset the port and use + * only the first BD that EPPC-Bug set up as a character FIFO. + * + * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug + * use COM1 instead of SMC1 as the console port. This kinda sucks + * for the rest of the kernel, so here we force the use of SMC1 again. + */ +#include +#include +#include +#include +#include "../../8xx_io/commproc.h" + +#ifdef CONFIG_MBX +#define MBX_CSR1 ((volatile u_char *)0xfa100000) +#define CSR1_COMEN (u_char)0x02 +#endif + +#ifdef TQM_SMC2_CONSOLE +#define PROFF_CONS PROFF_SMC2 +#define CPM_CR_CH_CONS CPM_CR_CH_SMC2 +#define SMC_INDEX 1 +static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport); +#else +#define PROFF_CONS PROFF_SMC1 +#define CPM_CR_CH_CONS CPM_CR_CH_SMC1 +#define SMC_INDEX 0 +#endif + +static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); + +void +serial_init(bd_t *bd) +{ + volatile smc_t *sp; + volatile smc_uart_t *up; + volatile cbd_t *tbdf, *rbdf; + volatile cpm8xx_t *cp; + uint dpaddr, memaddr, ui; + + cp = cpmp; + sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]); + up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS]; + + /* Disable transmitter/receiver. + */ + sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); + +#ifdef CONFIG_FADS + /* Enable SMC1/2 transceivers. + */ + *((volatile uint *)BCSR1) &= ~(BCSR1_RS232EN_1|BCSR1_RS232EN_2); +#endif + +#ifndef CONFIG_MBX + { + /* Initialize SMCx and use it for the console port. + */ + + /* Enable SDMA. + */ + ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; + +#ifdef TQM_SMC2_CONSOLE + /* Use Port A for SMC2 instead of other functions. + */ + iopp->iop_papar |= 0x00c0; + iopp->iop_padir &= ~0x00c0; + iopp->iop_paodr &= ~0x00c0; +#else + /* Use Port B for SMCs instead of other functions. + */ + cp->cp_pbpar |= 0x00000cc0; + cp->cp_pbdir &= ~0x00000cc0; + cp->cp_pbodr &= ~0x00000cc0; +#endif + + /* Allocate space for two buffer descriptors in the DP ram. + * For now, this address seems OK, but it may have to + * change with newer versions of the firmware. + */ + dpaddr = 0x0800; + + /* Grab a few bytes from the top of memory for SMC FIFOs. + */ + memaddr = (bd->bi_memsize - 32) & ~15; + + /* Set the physical address of the host memory buffers in + * the buffer descriptors. + */ + rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; + rbdf->cbd_bufaddr = memaddr; + rbdf->cbd_sc = 0; + tbdf = rbdf + 1; + tbdf->cbd_bufaddr = memaddr+4; + tbdf->cbd_sc = 0; + + /* Set up the uart parameters in the parameter ram. + */ + up->smc_rbase = dpaddr; + up->smc_tbase = dpaddr+sizeof(cbd_t); + up->smc_rfcr = SMC_EB; + up->smc_tfcr = SMC_EB; + + /* Set UART mode, 8 bit, no parity, one stop. + * Enable receive and transmit. + */ + sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; + + /* Mask all interrupts and remove anything pending. + */ + sp->smc_smcm = 0; + sp->smc_smce = 0xff; + + /* Set up the baud rate generator. + * See 8xx_io/commproc.c for details. + * This wires BRG1 to SMC1 and BRG2 to SMC2; + */ + cp->cp_simode = 0x10000000; + ui = bd->bi_intfreq / 16 / bd->bi_baudrate; +#ifdef TQM_SMC2_CONSOLE + cp->cp_brgc2 = +#else + cp->cp_brgc1 = +#endif + ((ui - 1) < 4096) + ? (((ui - 1) << 1) | CPM_BRG_EN) + : ((((ui / 16) - 1) << 1) | CPM_BRG_EN | CPM_BRG_DIV16); + +#else /* CONFIG_MBX */ + if (*MBX_CSR1 & CSR1_COMEN) { + /* COM1 is enabled. Initialize SMC1 and use it for + * the console port. + */ + + /* Enable SDMA. + */ + ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; + + /* Use Port B for SMCs instead of other functions. + */ + cp->cp_pbpar |= 0x00000cc0; + cp->cp_pbdir &= ~0x00000cc0; + cp->cp_pbodr &= ~0x00000cc0; + + /* Allocate space for two buffer descriptors in the DP ram. + * For now, this address seems OK, but it may have to + * change with newer versions of the firmware. + */ + dpaddr = 0x0800; + + /* Grab a few bytes from the top of memory. EPPC-Bug isn't + * running any more, so we can do this. + */ + memaddr = (bd->bi_memsize - 32) & ~15; + + /* Set the physical address of the host memory buffers in + * the buffer descriptors. + */ + rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; + rbdf->cbd_bufaddr = memaddr; + rbdf->cbd_sc = 0; + tbdf = rbdf + 1; + tbdf->cbd_bufaddr = memaddr+4; + tbdf->cbd_sc = 0; + + /* Set up the uart parameters in the parameter ram. + */ + up->smc_rbase = dpaddr; + up->smc_tbase = dpaddr+sizeof(cbd_t); + up->smc_rfcr = SMC_EB; + up->smc_tfcr = SMC_EB; + + /* Set UART mode, 8 bit, no parity, one stop. + * Enable receive and transmit. + */ + sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; + + /* Mask all interrupts and remove anything pending. + */ + sp->smc_smcm = 0; + sp->smc_smce = 0xff; + + /* Set up the baud rate generator. + * See 8xx_io/commproc.c for details. + */ + cp->cp_simode = 0x10000000; + cp->cp_brgc1 = + (((bd->bi_intfreq/16) / 9600) << 1) | CPM_BRG_EN; + + /* Enable SMC1 for console output. + */ + *MBX_CSR1 &= ~CSR1_COMEN; + } + else { +#endif /* ndef CONFIG_MBX */ + /* SMCx is used as console port. + */ + tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase]; + rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase]; + + /* Issue a stop transmit, and wait for it. + */ + cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, + CPM_CR_STOP_TX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + } + + /* Make the first buffer the only buffer. + */ + tbdf->cbd_sc |= BD_SC_WRAP; + rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; + + /* Single character receive. + */ + up->smc_mrblr = 1; + up->smc_maxidl = 0; + + /* Initialize Tx/Rx parameters. + */ + cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG; + while (cp->cp_cpcr & CPM_CR_FLG); + + /* Enable transmitter/receiver. + */ + sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; +} + +void +serial_putc(void *ignored, const char c) +{ + volatile cbd_t *tbdf; + volatile char *buf; + volatile smc_uart_t *up; + + up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; + tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; + + /* Wait for last character to go. + */ + buf = (char *)tbdf->cbd_bufaddr; + while (tbdf->cbd_sc & BD_SC_READY); + + *buf = c; + tbdf->cbd_datlen = 1; + tbdf->cbd_sc |= BD_SC_READY; +} + +char +serial_getc(void *ignored) +{ + volatile cbd_t *rbdf; + volatile char *buf; + volatile smc_uart_t *up; + char c; + + up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; + rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; + + /* Wait for character to show up. + */ + buf = (char *)rbdf->cbd_bufaddr; + while (rbdf->cbd_sc & BD_SC_EMPTY); + c = *buf; + rbdf->cbd_sc |= BD_SC_EMPTY; + + return(c); +} + +int +serial_tstc(void *ignored) +{ + volatile cbd_t *rbdf; + volatile smc_uart_t *up; + + up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; + rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; + + return(!(rbdf->cbd_sc & BD_SC_EMPTY)); +} diff -Nru a/arch/ppc/boot/mbx/misc.c b/arch/ppc/boot/mbx/misc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/mbx/misc.c Mon May 21 17:07:04 2001 @@ -0,0 +1,296 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Adapted for PowerPC by Gary Thomas + * + * Rewritten by Cort Dougan (cort@cs.nmt.edu) + * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort + */ + +#include +#include +#include "zlib.h" +#include +#include +#include +#include +#include +#ifdef CONFIG_8xx +#include +#endif +#ifdef CONFIG_8260 +#include +#endif + +/* + * The following references are needed to cause the linker to pull in the + * gzimage.o and rdimage.o files. These object files are special, + * since they get placed into the .gzimage and .rdimage ELF sections + * of the zvmlinux and zvmlinux.initrd files. + */ +extern char dummy_for_gzimage; +extern char dummy_for_rdimage; + +/* + * Please send me load/board info and such data for hardware not + * listed here so I can keep track since things are getting tricky + * with the different load addrs with different firmware. This will + * help to avoid breaking the load/boot process. + * -- Cort + */ +char *avail_ram; +char *end_avail; + +/* See comment below..... +*/ +unsigned int initrd_offset, initrd_size; + +/* Because of the limited amount of memory on embedded, it presents + * loading problems. The biggest is that we load this boot program + * into a relatively low memory address, and the Linux kernel Bss often + * extends into this space when it get loaded. When the kernel starts + * and zeros the BSS space, it also writes over the information we + * save here and pass to the kernel (command line and board info). + * On these boards, we grab some known memory holes to hold this information. + */ +char cmd_buf[256]; +char *cmd_line = cmd_buf; + +/* This is the default cmdline that will be given to the user at boot time.. + * If none was specified at compile time, we'll give it one that should work. + * -- Tom */ +#ifdef CONFIG_CMDLINE_BOOL +char compiled_string[] = CONFIG_CMDLINE; +#endif +char ramroot_string[] = "root=/dev/ram"; +char netroot_string[] = "root=/dev/nfs rw"; + +bd_t hold_resid_buf; +bd_t *hold_residual = &hold_resid_buf; +unsigned long initrd_start = 0, initrd_end = 0; +char *zimage_start; +int zimage_size; + +extern void puts(const char *); +extern void putc(const char c); +extern void udelay(long x); +extern void puthex(unsigned long val); +extern void * memcpy(void * __dest, __const void * __src, __kernel_size_t __n); +extern void gunzip(void *, int, unsigned char *, int *); +extern int tstc(void); +extern int getc(void); + +unsigned long +decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp) +{ + int timer; + extern unsigned long start; + char *cp, ch; + +#ifdef CONFIG_8260 + /* I don't know why I didn't do it this way on the 8xx....... + */ + embed_config(&bp); + serial_init(bp); +#endif + + /* These values must be variables. If not, the compiler optimizer + * will remove some code, causing the size of the code to vary + * when these values are zero. This is bad because we first + * compile with these zero to determine the size and offsets + * in an image, than compile again with these set to the proper + * discovered value.....Ya know, we used to read these from the + * header a long time ago..... + */ + initrd_offset = INITRD_OFFSET; + initrd_size = INITRD_SIZE; + + /* Grab some space for the command line and board info. Since + * we no longer use the ELF header, but it was loaded, grab + * that space. + */ +#ifdef CONFIG_MBX + cmd_line = (char *)(load_addr - 0x10000); + + /* To be like everyone else, we need one too, although this + * board information is passed from the boot rom. + */ + bp->bi_baudrate = 9600; +#else + cmd_line = (char *)(0x200000); +#endif + hold_residual = (bd_t *)(cmd_line + sizeof(cmd_buf)); + /* copy board data */ + if (bp) + memcpy(hold_residual,bp,sizeof(bd_t)); + + /* Set end of memory available to us. It is always the highest + * memory address provided by the board information. + */ + end_avail = (char *)(bp->bi_memsize); + + puts("loaded at: "); puthex(load_addr); + puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); + if ( (unsigned long)load_addr != (unsigned long)&start ) + { + puts("relocated to: "); puthex((unsigned long)&start); + puts(" "); + puthex((unsigned long)((unsigned long)&start + (4*num_words))); + puts("\n"); + } + + if ( bp ) + { + puts("board data at: "); puthex((unsigned long)bp); + puts(" "); + puthex((unsigned long)((unsigned long)bp + sizeof(bd_t))); + puts("\n"); + puts("relocated to: "); + puthex((unsigned long)hold_residual); + puts(" "); + puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t))); + puts("\n"); + } + + /* we have to subtract 0x10000 here to correct for objdump including the + size of the elf header which we strip -- Cort */ + zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET); + zimage_size = ZIMAGE_SIZE; + + if ( initrd_offset ) + initrd_start = load_addr - 0x10000 + initrd_offset; + else + initrd_start = 0; + initrd_end = initrd_size + initrd_start; + + /* + * setup avail_ram - this is the first part of ram usable + * by the uncompress code. -- Cort + */ + avail_ram = (char *)PAGE_ALIGN((unsigned long)zimage_start+zimage_size); + if ( ((load_addr+(num_words*4)) > (unsigned long) avail_ram) + && (load_addr <= 0x01000000) ) + avail_ram = (char *)(load_addr+(num_words*4)); + if ( (((unsigned long)&start+(num_words*4)) > (unsigned long) avail_ram) + && (load_addr <= 0x01000000) ) + avail_ram = (char *)((unsigned long)&start+(num_words*4)); + + /* relocate zimage */ + puts("zimage at: "); puthex((unsigned long)zimage_start); + puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n"); + /* + * There is no reason (yet) to relocate zImage for embedded boards. + * To support boot from flash rom on 8xx embedded boards, I + * assume if zimage start is over 16M we are booting from flash. + * In this case, avilable ram will start just above the space we + * have allocated for the command buffer and board information. + */ + if ((unsigned long)zimage_start > 0x01000000) + avail_ram = (char *)PAGE_ALIGN((unsigned long)hold_residual + sizeof(bd_t)); + + /* relocate initrd */ + if ( initrd_start ) + { + puts("initrd at: "); puthex(initrd_start); + puts(" "); puthex(initrd_end); puts("\n"); + + /* We only have to relocate initrd if we find it is in Flash + * rom. This is because the kernel thinks it can toss the + * pages into the free memory pool after it is done. Use + * the same 16M test. + */ + if ((unsigned long)initrd_start > 0x01000000) { + memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE), + (void *)initrd_start, + initrd_size ); + initrd_start = PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE); + initrd_end = initrd_start + initrd_size; + end_avail = (char *)initrd_start; + puts("relocated to: "); puthex(initrd_start); + puts(" "); puthex(initrd_end); puts("\n"); + } + else { + avail_ram = (char *)PAGE_ALIGN((unsigned long)initrd_end); + } + } + + + puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); + puthex((unsigned long)end_avail); puts("\n"); + puts("\nLinux/PPC load: "); + timer = 0; + cp = cmd_line; + /* This is where we try and pick the right command line for booting. + * If we were given one at compile time, use it. It Is Right. + * If we weren't, see if we have a ramdisk. If so, thats root. + * When in doubt, give them the netroot (root=/dev/nfs rw) -- Tom */ +#ifdef CONFIG_CMDLINE_BOOL + memcpy (cmd_line, compiled_string, sizeof(compiled_string)); +#else + if (initrd_start) + memcpy (cmd_line, ramroot_string, sizeof(ramroot_string)); + else + memcpy (cmd_line, netroot_string, sizeof(netroot_string)); +#endif + while ( *cp ) putc(*cp++); + while (timer++ < 5*1000) { + if (tstc()) { + while ((ch = getc()) != '\n' && ch != '\r') { + if (ch == '\b' || ch == '\177') { + if (cp != cmd_line) { + cp--; + puts("\b \b"); + } + } else if (ch == '\030' /* ^x */ + || ch == '\025') { /* ^u */ + while (cp != cmd_line) { + cp--; + puts("\b \b"); + } + } else { + *cp++ = ch; + putc(ch); + } + } + break; /* Exit 'timer' loop */ + } + udelay(1000); /* 1 msec */ + } + *cp = 0; + puts("\nUncompressing Linux..."); + + gunzip(0, 0x400000, zimage_start, &zimage_size); + puts("done.\n"); + puts("Now booting the kernel\n"); + return (unsigned long)hold_residual; +} + +/* + * PCI/ISA I/O support + */ + +volatile unsigned char *ISA_io = (unsigned char *)0x80000000; +volatile unsigned char *ISA_mem = (unsigned char *)0xC0000000; + +void +outb(int port, char val) +{ + /* Ensure I/O operations complete */ + __asm__ volatile("eieio"); + ISA_io[port] = val; +} + +unsigned char +inb(int port) +{ + /* Ensure I/O operations complete */ + __asm__ volatile("eieio"); + return (ISA_io[port]); +} + +unsigned long +local_to_PCI(unsigned long addr) +{ + return ((addr & 0x7FFFFFFF) | 0x80000000); +} diff -Nru a/arch/ppc/boot/mbx/pci.c b/arch/ppc/boot/mbx/pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/mbx/pci.c Mon May 21 17:07:04 2001 @@ -0,0 +1,255 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* Stand alone funtions for QSpan Tundra support. + */ +#include +#include +#include +#include + +/* To map PCI devices, you first write 0xffffffff into the device + * base address registers. When the register is read back, the + * number of most significant '1' bits describes the amount of address + * space needed for mapping. If the most significant bit is not set, + * either the device does not use that address register, or it has + * a fixed address that we can't change. After the address is assigned, + * the command register has to be written to enable the card. + */ +typedef struct { + u_char pci_bus; + u_char pci_devfn; + ushort pci_command; + uint pci_addrs[6]; +} pci_map_t; + +/* We should probably dynamically allocate these structures. +*/ +#define MAX_PCI_DEVS 32 +int pci_dev_cnt; +pci_map_t pci_map[MAX_PCI_DEVS]; + +void pci_conf_write(int bus, int device, int func, int reg, uint writeval); +void pci_conf_read(int bus, int device, int func, int reg, void *readval); +void probe_addresses(int bus, int devfn); +void map_pci_addrs(void); + +/* This is a really stripped version of PCI bus scan. All we are + * looking for are devices that exist. + */ +pci_scanner(int addr_probe) +{ + unsigned int devfn, l, max, class, bus_number; + unsigned char cmd, irq, tmp, hdr_type, is_multi; + int reg; + + is_multi = 0; + bus_number = 0; + for (devfn = 0; devfn < 0xff; ++devfn) { + /* The device numbers are comprised of upper 5 bits of + * device number and lower 3 bits of multi-function number. + */ + if ((devfn & 7) && !is_multi) { + /* Don't scan multifunction addresses if this is + * not a multifunction device. + */ + continue; + } + + /* Read the header to determine card type. + */ + qs_pci_read_config_byte(bus_number, devfn, PCI_HEADER_TYPE, + &hdr_type); + + /* If this is a base device number, check the header to + * determine if it is mulifunction. + */ + if ((devfn & 7) == 0) + is_multi = hdr_type & 0x80; + + /* Check to see if the board is really in the slot. + */ + qs_pci_read_config_dword(bus_number, devfn, PCI_VENDOR_ID, &l); + /* some broken boards return 0 if a slot is empty: */ + if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || + l == 0xffff0000) { + /* Nothing there. + */ + is_multi = 0; + continue; + } + + /* If we are not performing an address probe, + * just simply print out some information. + */ + if (!addr_probe) { + qs_pci_read_config_dword(bus_number, devfn, + PCI_CLASS_REVISION, &class); + + class >>= 8; /* upper 3 bytes */ + +#if 0 + printf("Found (%3d:%d): vendor 0x%04x, device 0x%04x, class 0x%06x\n", + (devfn >> 3), (devfn & 7), + (l & 0xffff), (l >> 16) & 0xffff, class); +#else + puts("Found ("); puthex(devfn >> 3); + puts(":"); puthex(devfn & 7); + puts("): vendor "); puthex(l & 0xffff); + puts(", device "); puthex((l >> 16) & 0xffff); + puts(", class "); puthex(class); puts("\n"); +#endif + } + else { + /* If this is a "normal" device, build address list. + */ + if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_NORMAL) + probe_addresses(bus_number, devfn); + } + } + + /* Now map the boards. + */ + if (addr_probe) + map_pci_addrs(); +} + +/* Probe addresses for the specified device. This is a destructive + * operation because it writes the registers. + */ +void +probe_addresses(bus, devfn) +{ + int i; + uint pciaddr; + ushort pcicmd; + pci_map_t *pm; + + if (pci_dev_cnt >= MAX_PCI_DEVS) { + puts("Too many PCI devices\n"); + return; + } + + pm = &pci_map[pci_dev_cnt++]; + + pm->pci_bus = bus; + pm->pci_devfn = devfn; + + for (i=0; i<6; i++) { + qs_pci_write_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), -1); + qs_pci_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), + &pciaddr); + pm->pci_addrs[i] = pciaddr; + qs_pci_read_config_word(bus, devfn, PCI_COMMAND, &pcicmd); + pm->pci_command = pcicmd; + } +} + +/* Map the cards into the PCI space. The PCI has separate memory + * and I/O spaces. In addition, some memory devices require mapping + * below 1M. The least significant 4 bits of the address register + * provide information. If this is an I/O device, only the LS bit + * is used to indicate that, so I/O devices can be mapped to a two byte + * boundard. Memory addresses can be mapped to a 32 byte boundary. + * The QSpan implementations usually have a 1Gbyte space for each + * memory and I/O spaces. + * + * This isn't a terribly fancy algorithm. I just map the spaces from + * the top starting with the largest address space. When finished, + * the registers are written and the card enabled. + * + * While the Tundra can map a large address space on most boards, we + * need to be careful because it may overlap other devices (like IMMR). + */ +#define MEMORY_SPACE_SIZE 0x20000000 +#define IO_SPACE_SIZE 0x20000000 + +void +map_pci_addrs() +{ + uint pci_mem_top, pci_mem_low; + uint pci_io_top; + uint addr_mask, reg_addr, space; + int i, j; + pci_map_t *pm; + + pci_mem_top = MEMORY_SPACE_SIZE; + pci_io_top = IO_SPACE_SIZE; + pci_mem_low = (1 * 1024 * 1024); /* Below one meg addresses */ + + /* We can't map anything more than the maximum space, but test + * for it anyway to catch devices out of range. + */ + addr_mask = 0x80000000; + + do { + space = (~addr_mask) + 1; /* Size of the space */ + for (i=0; ipci_addrs[j]; + if ((reg_addr & 0x80000000) == 0) + continue; + if (reg_addr & PCI_BASE_ADDRESS_SPACE_IO) { + if ((reg_addr & PCI_BASE_ADDRESS_IO_MASK) != addr_mask) + continue; + if (pci_io_top < space) { + puts("Out of PCI I/O space\n"); + } + else { + pci_io_top -= space; + pm->pci_addrs[j] = pci_io_top; + pm->pci_command |= PCI_COMMAND_IO; + } + } + else { + if ((reg_addr & PCI_BASE_ADDRESS_MEM_MASK) != addr_mask) + continue; + + /* Memory space. Test if below 1M. + */ + if (reg_addr & PCI_BASE_ADDRESS_MEM_TYPE_1M) { + if (pci_mem_low < space) { + puts("Out of PCI 1M space\n"); + } + else { + pci_mem_low -= space; + pm->pci_addrs[j] = pci_mem_low; + } + } + else { + if (pci_mem_top < space) { + puts("Out of PCI Mem space\n"); + } + else { + pci_mem_top -= space; + pm->pci_addrs[j] = pci_mem_top; + } + } + pm->pci_command |= PCI_COMMAND_MEMORY; + } + } + } + addr_mask >>= 1; + addr_mask |= 0x80000000; + } while (addr_mask != 0xfffffffe); + + /* Now, run the list one more time and map everything. + */ + for (i=0; ipci_bus, pm->pci_devfn, + PCI_BASE_ADDRESS_0 + (j * 4), pm->pci_addrs[j]); + } + + /* Enable memory or address mapping. + */ + qs_pci_write_config_word(pm->pci_bus, pm->pci_devfn, PCI_COMMAND, + pm->pci_command); + } +} + diff -Nru a/arch/ppc/boot/mbx/qspan_pci.c b/arch/ppc/boot/mbx/qspan_pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/mbx/qspan_pci.c Mon May 21 17:07:04 2001 @@ -0,0 +1,271 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * LinuxPPC arch/ppc/kernel/qspan_pci.c Dan Malek (dmalek@jlc.net) + * + * QSpan Motorola bus to PCI bridge. The config address register + * is located 0x500 from the base of the bridge control/status registers. + * The data register is located at 0x504. + * This is a two step operation. First, the address register is written, + * then the data register is read/written as required. + * I don't know what to do about interrupts (yet). + */ + +#include +#include +#include +#include + +/* + * When reading the configuration space, if something does not respond + * the bus times out and we get a machine check interrupt. So, the + * good ol' exception tables come to mind to trap it and return some + * value. + * + * On an error we just return a -1, since that is what the caller wants + * returned if nothing is present. I copied this from __get_user_asm, + * with the only difference of returning -1 instead of EFAULT. + * There is an associated hack in the machine check trap code. + * + * The QSPAN is also a big endian device, that is it makes the PCI + * look big endian to us. This presents a problem for the Linux PCI + * functions, which assume little endian. For example, we see the + * first 32-bit word like this: + * ------------------------ + * | Device ID | Vendor ID | + * ------------------------ + * If we read/write as a double word, that's OK. But in our world, + * when read as a word, device ID is at location 0, not location 2 as + * the little endian PCI would believe. We have to switch bits in + * the PCI addresses given to us to get the data to/from the correct + * byte lanes. + * + * The QSPAN only supports 4 bits of "slot" in the dev_fn instead of 5. + * It always forces the MS bit to zero. Therefore, dev_fn values + * greater than 128 are returned as "no device found" errors. + * + * The QSPAN can only perform long word (32-bit) configuration cycles. + * The "offset" must have the two LS bits set to zero. Read operations + * require we read the entire word and then sort out what should be + * returned. Write operations other than long word require that we + * read the long word, update the proper word or byte, then write the + * entire long word back. + * + * PCI Bridge hack. We assume (correctly) that bus 0 is the primary + * PCI bus from the QSPAN. If we are called with a bus number other + * than zero, we create a Type 1 configuration access that a downstream + * PCI bridge will interpret. + */ + +#define __get_pci_config(x, addr, op) \ + __asm__ __volatile__( \ + "1: "op" %0,0(%1)\n" \ + " eieio\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: li %0,-1\n" \ + " b 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 2\n" \ + " .long 1b,3b\n" \ + ".text" \ + : "=r"(x) : "r"(addr)) + +#define QS_CONFIG_ADDR ((volatile uint *)(PCI_CSR_ADDR + 0x500)) +#define QS_CONFIG_DATA ((volatile uint *)(PCI_CSR_ADDR + 0x504)) + +#define mk_config_addr(bus, dev, offset) \ + (((bus)<<16) | ((dev)<<8) | (offset & 0xfc)) + +#define mk_config_type1(bus, dev, offset) \ + mk_config_addr(bus, dev, offset) | 1; + +/* Initialize the QSpan device registers after power up. +*/ +qspan_init() +{ + uint *qptr; + + + + qptr = (uint *)PCI_CSR_ADDR; + + /* PCI Configuration/status. Upper bits written to clear + * pending interrupt or status. Lower bits enable QSPAN as + * PCI master, enable memory and I/O cycles, and enable PCI + * parity error checking. + * IMPORTANT: The last two bits of this word enable PCI + * master cycles into the QBus. The QSpan is broken and can't + * meet the timing specs of the PQ bus for this to work. Therefore, + * if you don't have external bus arbitration, you can't use + * this function. + */ +#ifdef EXTERNAL_PQ_ARB + qptr[1] = 0xf9000147; +#else + qptr[1] = 0xf9000144; +#endif + + /* PCI Misc configuration. Set PCI latency timer resolution + * of 8 cycles, set cache size to 4 x 32. + */ + qptr[3] = 0; + + /* Set up PCI Target address mapping. Enable, Posted writes, + * 2Gbyte space (processor memory controller determines actual size). + */ + qptr[64] = 0x8f000080; + + /* Map processor 0x80000000 to PCI 0x00000000. + * Processor address bit 1 determines I/O type access (0x80000000) + * or memory type access (0xc0000000). + */ + qptr[65] = 0x80000000; + + /* Enable error logging and clear any pending error status. + */ + qptr[80] = 0x90000000; + + qptr[512] = 0x000c0003; + + /* Set up Qbus slave image. + */ + qptr[960] = 0x01000000; + qptr[961] = 0x000000d1; + qptr[964] = 0x00000000; + qptr[965] = 0x000000d1; + +} + +/* Functions to support PCI bios-like features to read/write configuration + * space. If the function fails for any reason, a -1 (0xffffffff) value + * must be returned. + */ +#define DEVICE_NOT_FOUND (-1) +#define SUCCESSFUL 0 + +int qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned char *val) +{ + uint temp; + u_char *cp; + + if ((bus > 7) || (dev_fn > 127)) { + *val = 0xff; + return DEVICE_NOT_FOUND; + } + + if (bus == 0) + *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); + else + *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); + __get_pci_config(temp, QS_CONFIG_DATA, "lwz"); + + offset ^= 0x03; + cp = ((u_char *)&temp) + (offset & 0x03); + *val = *cp; + return SUCCESSFUL; +} + +int qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned short *val) +{ + uint temp; + ushort *sp; + + if ((bus > 7) || (dev_fn > 127)) { + *val = 0xffff; + return DEVICE_NOT_FOUND; + } + + if (bus == 0) + *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); + else + *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); + __get_pci_config(temp, QS_CONFIG_DATA, "lwz"); + offset ^= 0x02; + + sp = ((ushort *)&temp) + ((offset >> 1) & 1); + *val = *sp; + return SUCCESSFUL; +} + +int qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned int *val) +{ + if ((bus > 7) || (dev_fn > 127)) { + *val = 0xffffffff; + return DEVICE_NOT_FOUND; + } + if (bus == 0) + *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); + else + *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); + __get_pci_config(*val, QS_CONFIG_DATA, "lwz"); + return SUCCESSFUL; +} + +int qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned char val) +{ + uint temp; + u_char *cp; + + if ((bus > 7) || (dev_fn > 127)) + return DEVICE_NOT_FOUND; + + qs_pci_read_config_dword(bus, dev_fn, offset, &temp); + + offset ^= 0x03; + cp = ((u_char *)&temp) + (offset & 0x03); + *cp = val; + + if (bus == 0) + *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); + else + *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); + *QS_CONFIG_DATA = temp; + + return SUCCESSFUL; +} + +int qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned short val) +{ + uint temp; + ushort *sp; + + if ((bus > 7) || (dev_fn > 127)) + return DEVICE_NOT_FOUND; + + qs_pci_read_config_dword(bus, dev_fn, offset, &temp); + + offset ^= 0x02; + sp = ((ushort *)&temp) + ((offset >> 1) & 1); + *sp = val; + + if (bus == 0) + *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); + else + *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); + *QS_CONFIG_DATA = temp; + + return SUCCESSFUL; +} + +int qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn, + unsigned char offset, unsigned int val) +{ + if ((bus > 7) || (dev_fn > 127)) + return DEVICE_NOT_FOUND; + + if (bus == 0) + *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); + else + *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); + *(unsigned int *)QS_CONFIG_DATA = val; + + return SUCCESSFUL; +} + diff -Nru a/arch/ppc/boot/mbx/rdimage.c b/arch/ppc/boot/mbx/rdimage.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/mbx/rdimage.c Mon May 21 17:07:03 2001 @@ -0,0 +1,11 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * rdimage.c + * + * Dummy file to allow a compressed initrd to be added + * into a linker section, accessed by the boot coode + */ + +char dummy_for_rdimage; 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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/misc.c b/arch/ppc/boot/misc.c --- a/arch/ppc/boot/misc.c Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,845 +0,0 @@ -/* - * misc.c - * - * $Id: misc.c,v 1.68 1999/10/20 22:08:08 cort Exp $ - * - * Adapted for PowerPC by Gary Thomas - * - * Rewritten by Cort Dougan (cort@cs.nmt.edu) - * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort - */ - -#include -#include "../coffboot/zlib.h" -#include "asm/residual.h" -#include -#include -#include -#include -#include -#include -#if defined(CONFIG_SERIAL_CONSOLE) -#include "ns16550.h" -struct NS16550 *com_port; -#endif /* CONFIG_SERIAL_CONSOLE */ - -/* - * Please send me load/board info and such data for hardware not - * listed here so I can keep track since things are getting tricky - * with the different load addrs with different firmware. This will - * help to avoid breaking the load/boot process. - * -- Cort - */ -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; - -int keyb_present = 1; /* keyboard controller is present by default */ -RESIDUAL hold_resid_buf; -RESIDUAL *hold_residual = &hold_resid_buf; -unsigned long initrd_start = 0, initrd_end = 0; -char *zimage_start; -int zimage_size; - -char *vidmem = (char *)0xC00B8000; -int lines, cols; -int orig_x, orig_y; - -void puts(const char *); -void putc(const char c); -void puthex(unsigned long val); -void _bcopy(char *src, char *dst, int len); -void * memcpy(void * __dest, __const void * __src, - int __n); -void gunzip(void *, int, unsigned char *, int *); -static int _cvt(unsigned long val, char *buf, long radix, char *digits); -unsigned char inb(int); - -void pause() -{ - puts("pause\n"); -} - -void exit() -{ - puts("exit\n"); - while(1); -} - -static void clear_screen() -{ - int i, j; - for (i = 0; i < lines; i++) { - for (j = 0; j < cols; j++) { - vidmem[((i*cols)+j)*2] = ' '; - vidmem[((i*cols)+j)*2+1] = 0x07; - } - } -} - -static void scroll() -{ - int i; - - memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 ); - for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 ) - vidmem[i] = ' '; -} - -tstc(void) -{ -#if defined(CONFIG_SERIAL_CONSOLE) - if (keyb_present) - return (CRT_tstc() || NS16550_tstc(com_port)); - else - NS16550_tstc(com_port); -#else - return (CRT_tstc() ); -#endif /* CONFIG_SERIAL_CONSOLE */ -} - -getc(void) -{ - while (1) { -#if defined(CONFIG_SERIAL_CONSOLE) - if (NS16550_tstc(com_port)) return (NS16550_getc(com_port)); -#endif /* CONFIG_SERIAL_CONSOLE */ - if (keyb_present) - if (CRT_tstc()) return (CRT_getc()); - } -} - -void -putc(const char c) -{ - int x,y; - -#if defined(CONFIG_SERIAL_CONSOLE) - NS16550_putc(com_port, c); - if ( c == '\n' ) NS16550_putc(com_port, '\r'); -#endif /* CONFIG_SERIAL_CONSOLE */ - - x = orig_x; - y = orig_y; - - if ( c == '\n' ) { - x = 0; - if ( ++y >= lines ) { - scroll(); - y--; - } - } else if (c == '\r') { - x = 0; - } else if (c == '\b') { - if (x > 0) { - x--; - } - } else { - vidmem [ ( x + cols * y ) * 2 ] = c; - if ( ++x >= cols ) { - x = 0; - if ( ++y >= lines ) { - scroll(); - y--; - } - } - } - - cursor(x, y); - - orig_x = x; - orig_y = y; -} - -void puts(const char *s) -{ - int x,y; - char c; - - x = orig_x; - y = orig_y; - - while ( ( c = *s++ ) != '\0' ) { -#if defined(CONFIG_SERIAL_CONSOLE) - NS16550_putc(com_port, c); - if ( c == '\n' ) NS16550_putc(com_port, '\r'); -#endif /* CONFIG_SERIAL_CONSOLE */ - - if ( c == '\n' ) { - x = 0; - if ( ++y >= lines ) { - scroll(); - y--; - } - } else if (c == '\b') { - if (x > 0) { - x--; - } - } else { - vidmem [ ( x + cols * y ) * 2 ] = c; - if ( ++x >= cols ) { - x = 0; - if ( ++y >= lines ) { - scroll(); - y--; - } - } - } - } - - cursor(x, y); - - orig_x = x; - orig_y = y; -} - -void * memcpy(void * __dest, __const void * __src, - int __n) -{ - int i; - char *d = (char *)__dest, *s = (char *)__src; - - for (i=0;i<__n;i++) d[i] = s[i]; -} - -int memcmp(__const void * __dest, __const void * __src, - int __n) -{ - int i; - char *d = (char *)__dest, *s = (char *)__src; - - for (i=0;i<__n;i++, d++, s++) - { - if (*d != *s) - { - return (*s - *d); - } - } - return (0); -} - -void error(char *x) -{ - puts("\n\n"); - puts(x); - puts("\n\n -- System halted"); - - while(1); /* Halt */ -} - -void *zalloc(void *x, unsigned items, unsigned size) -{ - void *p = avail_ram; - - size *= items; - size = (size + 7) & -8; - avail_ram += size; - if (avail_ram > end_avail) { - puts("oops... out of memory\n"); - pause(); - } - return p; -} - -void zfree(void *x, void *addr, unsigned nb) -{ -} - -#define HEAD_CRC 2 -#define EXTRA_FIELD 4 -#define ORIG_NAME 8 -#define COMMENT 0x10 -#define RESERVED 0xe0 - -#define DEFLATED 8 - - -void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) -{ - z_stream s; - int r, i, flags; - - /* skip header */ - i = 10; - flags = src[3]; - if (src[2] != DEFLATED || (flags & RESERVED) != 0) { - puts("bad gzipped data\n"); - exit(); - } - if ((flags & EXTRA_FIELD) != 0) - i = 12 + src[10] + (src[11] << 8); - if ((flags & ORIG_NAME) != 0) - while (src[i++] != 0) - ; - if ((flags & COMMENT) != 0) - while (src[i++] != 0) - ; - if ((flags & HEAD_CRC) != 0) - i += 2; - if (i >= *lenp) { - puts("gunzip: ran out of data in header\n"); - exit(); - } - - s.zalloc = zalloc; - s.zfree = zfree; - r = inflateInit2(&s, -MAX_WBITS); - if (r != Z_OK) { - puts("inflateInit2 returned %d\n"); - exit(); - } - s.next_in = src + i; - s.avail_in = *lenp - i; - s.next_out = dst; - s.avail_out = dstlen; - r = inflate(&s, Z_FINISH); - if (r != Z_OK && r != Z_STREAM_END) { - puts("inflate returned %d\n"); - exit(); - } - *lenp = s.next_out - (unsigned char *) dst; - inflateEnd(&s); -} - -unsigned long -decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, - RESIDUAL *residual, void *OFW_interface) -{ - int timer; - extern unsigned long start; - char *cp, ch; - unsigned long i; - BATU *u; - BATL *l; - unsigned long TotalMemory; - unsigned long orig_MSR; - int dev_handle; - int mem_info[2]; - int res, size; - unsigned char board_type; - unsigned char base_mod; - - lines = 25; - cols = 80; - orig_x = 0; - orig_y = 24; - - /* - * IBM's have the MMU on, so we have to disable it or - * things get really unhappy in the kernel when - * trying to setup the BATs with the MMU on - * -- Cort - */ - flush_instruction_cache(); - _put_HID0(_get_HID0() & ~0x0000C000); - _put_MSR((orig_MSR = _get_MSR()) & ~0x0030); - -#if defined(CONFIG_SERIAL_CONSOLE) - com_port = (struct NS16550 *)NS16550_init(0); -#endif /* CONFIG_SERIAL_CONSOLE */ - vga_init(0xC0000000); - - if (residual) - { - /* Is this Motorola PPCBug? */ - if ((1 & residual->VitalProductData.FirmwareSupports) && - (1 == residual->VitalProductData.FirmwareSupplier)) { - board_type = inb(0x800) & 0xF0; - - /* If this is genesis 2 board then check for no - * keyboard controller and more than one processor. - */ - if (board_type == 0xe0) { - base_mod = inb(0x803); - /* if a MVME2300/2400 or a Sitka then no keyboard */ - if((base_mod == 0xFA) || (base_mod == 0xF9) || - (base_mod == 0xE1)) { - keyb_present = 0; /* no keyboard */ - } - } - } - memcpy(hold_residual,residual,sizeof(RESIDUAL)); - } else { - /* Assume 32M in the absence of more info... */ - TotalMemory = 0x02000000; - /* - * This is a 'best guess' check. We want to make sure - * we don't try this on a PReP box without OF - * -- Cort - */ - while (OFW_interface && ((unsigned long)OFW_interface < 0x10000000) ) - { - /* The MMU needs to be on when we call OFW */ - _put_MSR(orig_MSR); - of_init(OFW_interface); - - /* get handle to memory description */ - res = of_finddevice("/memory@0", - &dev_handle); - // puthex(res); puts("\n"); - if (res) break; - - /* get the info */ - // puts("get info = "); - res = of_getprop(dev_handle, - "reg", - mem_info, - sizeof(mem_info), - &size); - // puthex(res); puts(", info = "); puthex(mem_info[0]); - // puts(" "); puthex(mem_info[1]); puts("\n"); - if (res) break; - - TotalMemory = mem_info[1]; - break; - } - hold_residual->TotalMemory = TotalMemory; - residual = hold_residual; - /* Turn MMU back off */ - _put_MSR(orig_MSR & ~0x0030); - } - - /* assume the chunk below 8M is free */ - end_avail = (char *)0x00800000; - - /* tell the user where we were loaded at and where we - * were relocated to for debugging this process - */ - puts("loaded at: "); puthex(load_addr); - puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); - if ( (unsigned long)load_addr != (unsigned long)&start ) - { - puts("relocated to: "); puthex((unsigned long)&start); - puts(" "); - puthex((unsigned long)((unsigned long)&start + (4*num_words))); - puts("\n"); - } - - if ( residual ) - { - puts("board data at: "); puthex((unsigned long)residual); - puts(" "); - puthex((unsigned long)((unsigned long)residual + sizeof(RESIDUAL))); - puts("\n"); - puts("relocated to: "); - puthex((unsigned long)hold_residual); - puts(" "); - puthex((unsigned long)((unsigned long)hold_residual + sizeof(RESIDUAL))); - puts("\n"); - } - - /* we have to subtract 0x10000 here to correct for objdump including the - size of the elf header which we strip -- Cort */ - zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET); - zimage_size = ZIMAGE_SIZE; - - if ( INITRD_OFFSET ) - initrd_start = load_addr - 0x10000 + INITRD_OFFSET; - else - initrd_start = 0; - initrd_end = INITRD_SIZE + initrd_start; - - /* - * Find a place to stick the zimage and initrd and - * relocate them if we have to. -- Cort - */ - avail_ram = (char *)PAGE_ALIGN((unsigned long)_end); - puts("zimage at: "); puthex((unsigned long)zimage_start); - puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n"); - if ( (unsigned long)zimage_start <= 0x00800000 ) - { - memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size ); - zimage_start = (char *)avail_ram; - puts("relocated to: "); puthex((unsigned long)zimage_start); - puts(" "); - puthex((unsigned long)zimage_size+(unsigned long)zimage_start); - puts("\n"); - avail_ram += zimage_size; - } - - /* relocate initrd */ - if ( initrd_start ) - { - puts("initrd at: "); puthex(initrd_start); - puts(" "); puthex(initrd_end); puts("\n"); - if ( (unsigned long)initrd_start <= 0x00800000 ) - { - memcpy( (void *)avail_ram, - (void *)initrd_start, initrd_end-initrd_start ); - puts("relocated to: "); - initrd_end = (unsigned long) avail_ram + (initrd_end-initrd_start); - initrd_start = (unsigned long)avail_ram; - puthex((unsigned long)initrd_start); - puts(" "); - puthex((unsigned long)initrd_end); - puts("\n"); - } - avail_ram = (char *)PAGE_ALIGN((unsigned long)initrd_end); - } - - avail_ram = (char *)0x00400000; - end_avail = (char *)0x00800000; - puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); - puthex((unsigned long)end_avail); puts("\n"); - - if (keyb_present) - CRT_tstc(); /* Forces keyboard to be initialized */ - - 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 *)PAGE_ALIGN(zimage_size); - - rec->tag = BI_FIRST; - rec->size = sizeof(struct bi_record); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_BOOTLOADER_ID; - memcpy( (void *)rec->data, "prepboot", 9); - rec->size = sizeof(struct bi_record) + 8 + 1; - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_MACHTYPE; - rec->data[0] = _MACH_prep; - rec->data[1] = 1; - rec->size = sizeof(struct bi_record) + sizeof(unsigned long); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_CMD_LINE; - memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); - rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; - rec = (struct bi_record *)((ulong)rec + rec->size); - - rec->tag = BI_LAST; - rec->size = sizeof(struct bi_record); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - } - puts("Now booting the kernel\n"); - return (unsigned long)hold_residual; -} - -void puthex(unsigned long val) -{ - unsigned char buf[10]; - int i; - for (i = 7; i >= 0; i--) - { - buf[i] = "0123456789ABCDEF"[val & 0x0F]; - val >>= 4; - } - buf[8] = '\0'; - puts(buf); -} - -/* - * PCI/ISA I/O support - */ - -volatile unsigned char *ISA_io = (unsigned char *)0x80000000; -volatile unsigned char *ISA_mem = (unsigned char *)0xC0000000; - -void -outb(int port, char val) -{ - /* Ensure I/O operations complete */ - __asm__ volatile("eieio"); - ISA_io[port] = val; -} - -unsigned char -inb(int port) -{ - /* Ensure I/O operations complete */ - __asm__ volatile("eieio"); - return (ISA_io[port]); -} - -unsigned long -local_to_PCI(unsigned long addr) -{ - return ((addr & 0x7FFFFFFF) | 0x80000000); -} - -void -_bcopy(char *src, char *dst, int len) -{ - while (len--) *dst++ = *src++; -} - - -#define FALSE 0 -#define TRUE 1 -#include - -int -strlen(char *s) -{ - int len = 0; - while (*s++) len++; - return len; -} - -_printk(char const *fmt, ...) -{ - int ret; - va_list ap; - - va_start(ap, fmt); - ret = _vprintk(putc, fmt, ap); - va_end(ap); - return (ret); -} - -#define is_digit(c) ((c >= '0') && (c <= '9')) - -int -_vprintk(putc, fmt0, ap) -int (*putc)(); -const char *fmt0; -va_list ap; -{ - char c, sign, *cp; - int left_prec, right_prec, zero_fill, length, pad, pad_on_right; - char buf[32]; - long val; - while (c = *fmt0++) - { - if (c == '%') - { - c = *fmt0++; - left_prec = right_prec = pad_on_right = 0; - if (c == '-') - { - c = *fmt0++; - pad_on_right++; - } - if (c == '0') - { - zero_fill = TRUE; - c = *fmt0++; - } else - { - zero_fill = FALSE; - } - while (is_digit(c)) - { - left_prec = (left_prec * 10) + (c - '0'); - c = *fmt0++; - } - if (c == '.') - { - c = *fmt0++; - zero_fill++; - while (is_digit(c)) - { - right_prec = (right_prec * 10) + (c - '0'); - c = *fmt0++; - } - } else - { - right_prec = left_prec; - } - sign = '\0'; - switch (c) - { - case 'd': - case 'x': - case 'X': - val = va_arg(ap, long); - switch (c) - { - case 'd': - if (val < 0) - { - sign = '-'; - val = -val; - } - length = _cvt(val, buf, 10, "0123456789"); - break; - case 'x': - length = _cvt(val, buf, 16, "0123456789abcdef"); - break; - case 'X': - length = _cvt(val, buf, 16, "0123456789ABCDEF"); - break; - } - cp = buf; - break; - case 's': - cp = va_arg(ap, char *); - length = strlen(cp); - break; - case 'c': - c = va_arg(ap, long /*char*/); - (*putc)(c); - continue; - default: - (*putc)('?'); - } - pad = left_prec - length; - if (sign != '\0') - { - pad--; - } - if (zero_fill) - { - c = '0'; - if (sign != '\0') - { - (*putc)(sign); - sign = '\0'; - } - } else - { - c = ' '; - } - if (!pad_on_right) - { - while (pad-- > 0) - { - (*putc)(c); - } - } - if (sign != '\0') - { - (*putc)(sign); - } - while (length-- > 0) - { - (*putc)(c = *cp++); - if (c == '\n') - { - (*putc)('\r'); - } - } - if (pad_on_right) - { - while (pad-- > 0) - { - (*putc)(c); - } - } - } else - { - (*putc)(c); - if (c == '\n') - { - (*putc)('\r'); - } - } - } -} - -int _cvt(unsigned long val, char *buf, long radix, char *digits) -{ - char temp[80]; - char *cp = temp; - int length = 0; - if (val == 0) - { /* Special case */ - *cp++ = '0'; - } else - while (val) - { - *cp++ = digits[val % radix]; - val /= radix; - } - while (cp != temp) - { - *buf++ = *--cp; - length++; - } - *buf = '\0'; - return (length); -} - -_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base) -{ - int i, c; - if ((unsigned int)s > (unsigned int)p) - { - s = (unsigned int)s - (unsigned int)p; - } - while (s > 0) - { - if (base) - { - _printk("%06X: ", (int)p - (int)base); - } else - { - _printk("%06X: ", p); - } - for (i = 0; i < 16; i++) - { - if (i < s) - { - _printk("%02X", p[i] & 0xFF); - } else - { - _printk(" "); - } - if ((i % 2) == 1) _printk(" "); - if ((i % 8) == 7) _printk(" "); - } - _printk(" |"); - for (i = 0; i < 16; i++) - { - if (i < s) - { - c = p[i] & 0xFF; - if ((c < 0x20) || (c >= 0x7F)) c = '.'; - } else - { - c = ' '; - } - _printk("%c", c); - } - _printk("|\n"); - s -= 16; - p += 16; - } -} - -_dump_buf(unsigned char *p, int s) -{ - _printk("\n"); - _dump_buf_with_offset(p, s, 0); -} diff -Nru a/arch/ppc/boot/mkprep.c b/arch/ppc/boot/mkprep.c --- a/arch/ppc/boot/mkprep.c Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,287 +0,0 @@ -/* - * Makes a prep bootable image which can be dd'd onto - * a disk device to make a bootdisk. Will take - * as input a elf executable, strip off the header - * and write out a boot image as: - * 1) default - strips elf header - * suitable as a network boot image - * 2) -pbp - strips elf header and writes out prep boot partition image - * cat or dd onto disk for booting - * 3) -asm - strips elf header and writes out as asm data - * useful for generating data for a compressed image - * -- Cort - * - * Modified for x86 hosted builds by Matt Porter - */ - -#include -#include -#include -#include - -#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)); -} - -#define cpu_to_be32(x) (x) -#define be32_to_cpu(x) (x) -#define cpu_to_be16(x) (x) -#define be16_to_cpu(x) (x) - -/* size of read buffer */ -#define SIZE 0x1000 - - -typedef unsigned long dword_t; -typedef unsigned short word_t; -typedef unsigned char byte_t; -typedef byte_t block_t[512]; -typedef byte_t page_t[4096]; - - -/* - * Partition table entry - * - from the PReP spec - */ -typedef struct partition_entry { - byte_t boot_indicator; - byte_t starting_head; - byte_t starting_sector; - byte_t starting_cylinder; - - byte_t system_indicator; - byte_t ending_head; - byte_t ending_sector; - byte_t ending_cylinder; - - dword_t beginning_sector; - dword_t number_of_sectors; -} partition_entry_t; - -#define BootActive 0x80 -#define SystemPrep 0x41 - -void copy_image(int , int); -void write_prep_partition(int , int ); -void write_asm_data( int in, int out ); - -unsigned int elfhdr_size = 65536; - -int main(int argc, char *argv[]) -{ - int in_fd, out_fd; - int argptr = 1; - unsigned int prep = 0; - unsigned int asmoutput = 0; - - if ( (argc < 3) || (argc > 4) ) - { - fprintf(stderr, "usage: %s [-pbp] [-asm] \n",argv[0]); - exit(-1); - } - - /* needs to handle args more elegantly -- but this is a small/simple program */ - - /* check for -pbp */ - if ( !strcmp( argv[argptr], "-pbp" ) ) - { - prep = 1; - argptr++; - } - - /* check for -asm */ - if ( !strcmp( argv[argptr], "-asm" ) ) - { - asmoutput = 1; - argptr++; - } - - /* input file */ - if ( !strcmp( argv[argptr], "-" ) ) - in_fd = 0; /* stdin */ - else - if ((in_fd = open( argv[argptr] , 0)) < 0) - exit(-1); - argptr++; - - /* output file */ - if ( !strcmp( argv[argptr], "-" ) ) - out_fd = 1; /* stdout */ - else - if ((out_fd = creat( argv[argptr] , 0755)) < 0) - exit(-1); - argptr++; - - /* skip elf header in input file */ - /*if ( !prep )*/ - lseek(in_fd, elfhdr_size, SEEK_SET); - - /* write prep partition if necessary */ - if ( prep ) - write_prep_partition( in_fd, out_fd ); - - /* write input image to bootimage */ - if ( asmoutput ) - write_asm_data( in_fd, out_fd ); - else - copy_image(in_fd, out_fd); - - return 0; -} - -void write_prep_partition(int in, int out) -{ - unsigned char block[512]; - partition_entry_t *pe = (partition_entry_t *)&block[0x1BE]; - dword_t *entry = (dword_t *)&block[0]; - dword_t *length = (dword_t *)&block[sizeof(long)]; - struct stat info; - - if (fstat(in, &info) < 0) - { - fprintf(stderr,"info failed\n"); - exit(-1); - } - - bzero( block, sizeof block ); - - /* set entry point and boot image size skipping over elf header */ -#ifdef __i386__ - *entry = 0x400/*+65536*/; - *length = info.st_size-elfhdr_size+0x400; -#else - *entry = cpu_to_le32(0x400/*+65536*/); - *length = cpu_to_le32(info.st_size-elfhdr_size+0x400); -#endif /* __i386__ */ - - /* sets magic number for msdos partition (used by linux) */ - block[510] = 0x55; - block[511] = 0xAA; - - /* - * Build a "PReP" partition table entry in the boot record - * - "PReP" may only look at the system_indicator - */ - pe->boot_indicator = BootActive; - pe->system_indicator = SystemPrep; - /* - * The first block of the diskette is used by this "boot record" which - * actually contains the partition table. (The first block of the - * partition contains the boot image, but I digress...) We'll set up - * one partition on the diskette and it shall contain the rest of the - * diskette. - */ - pe->starting_head = 0; /* zero-based */ - pe->starting_sector = 2; /* one-based */ - pe->starting_cylinder = 0; /* zero-based */ - pe->ending_head = 1; /* assumes two heads */ - pe->ending_sector = 18; /* assumes 18 sectors/track */ - pe->ending_cylinder = 79; /* assumes 80 cylinders/diskette */ - - /* - * The "PReP" software ignores the above fields and just looks at - * the next two. - * - size of the diskette is (assumed to be) - * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette) - * - unlike the above sector numbers, the beginning sector is zero-based! - */ -#if 0 - pe->beginning_sector = cpu_to_le32(1); -#else - /* This has to be 0 on the PowerStack? */ -#ifdef __i386__ - pe->beginning_sector = 0; -#else - pe->beginning_sector = cpu_to_le32(0); -#endif /* __i386__ */ -#endif - -#ifdef __i386__ - pe->number_of_sectors = 2*18*80-1; -#else - pe->number_of_sectors = cpu_to_le32(2*18*80-1); -#endif /* __i386__ */ - - write( out, block, sizeof(block) ); - write( out, entry, sizeof(*entry) ); - write( out, length, sizeof(*length) ); - /* set file position to 2nd sector where image will be written */ - lseek( out, 0x400, SEEK_SET ); -} - - - -void -copy_image(int in, int out) -{ - char buf[SIZE]; - int n; - - while ( (n = read(in, buf, SIZE)) > 0 ) - write(out, buf, n); -} - - -void -write_asm_data( int in, int out ) -{ - int i, cnt, pos, len; - unsigned int cksum, val; - unsigned char *lp; - unsigned char buf[SIZE]; - unsigned char str[256]; - - write( out, "\t.data\n\t.globl input_data\ninput_data:\n", - strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) ); - pos = 0; - cksum = 0; - while ((len = read(in, buf, sizeof(buf))) > 0) - { - cnt = 0; - lp = (unsigned char *)buf; - len = (len + 3) & ~3; /* Round up to longwords */ - for (i = 0; i < len; i += 4) - { - if (cnt == 0) - { - write( out, "\t.long\t", strlen( "\t.long\t" ) ); - } - sprintf( str, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); - write( out, str, strlen(str) ); - val = *(unsigned long *)lp; - cksum ^= val; - lp += 4; - if (++cnt == 4) - { - cnt = 0; - sprintf( str, " # %x \n", pos+i-12); - write( out, str, strlen(str) ); - } else - { - write( out, ",", 1 ); - } - } - if (cnt) - { - write( out, "0\n", 2 ); - } - pos += len; - } - sprintf(str, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos); - write( out, str, strlen(str) ); - - fprintf(stderr, "cksum = %x\n", cksum); -} diff -Nru a/arch/ppc/boot/mksimage.c b/arch/ppc/boot/mksimage.c --- a/arch/ppc/boot/mksimage.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,124 +0,0 @@ -/* - * - * - * - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - - -#define SIZE 1024 -#define BLOCK_ALIGN(x) (((x)+SIZE-1)&(~(SIZE-1))) - -static void -die(const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - vfprintf(stderr, fmt, args); - fputc('\n', stderr); - exit(1); -} - -static void -usage(void) -{ - printf("Usage: mkbinimg -o \n"); - exit(1); -} - -static int -copy_blocks(int ifd, int ofd, unsigned long *offset, unsigned long *size) -{ - off_t cur; - int amt; - unsigned long len = 0; - char buffer[SIZE]; - - cur = lseek(ofd, 0, SEEK_CUR); - - if (cur % SIZE) { - cur = BLOCK_ALIGN(cur); - cur = lseek(ofd, cur, SEEK_SET); - } - - *offset = (unsigned long) cur; - while((amt = read(ifd, buffer, SIZE)) > 0) { - write(ofd, buffer, amt); - len += amt; - } - *size = len; - return 0; -} - - -int -main(int argc, char *argv[]) -{ - char *kernel, *loader, *rdimage = NULL; - unsigned long ld_off, kern_off, rd_off; - unsigned long ld_size, kern_size, rd_size; - int fd, ofd, len; - char buffer[500]; - - if (argc < 5 && !strcmp(argv[argc-2], "-o")) - usage(); - - if (argc > 5) - rdimage = argv[3]; - - kernel = argv[2]; - loader = argv[1]; - - ofd = open(argv[argc-1], (O_RDWR|O_CREAT), 0755); - if (ofd < 0) { - die("can't open %s: %s", argv[5], strerror(errno)); - } - - ld_off = kern_off = rd_off = 0; - ld_size = kern_size = rd_size = 0; - memset(buffer, 0, 500); - len = 0; - - fd = open(loader, O_RDONLY); - if (fd < 0) - die("can't open loader: %s", strerror(errno)); - - copy_blocks(fd, ofd, &ld_off, &ld_size); - len = sprintf(buffer, "bootloader: %x %x\n", ld_off, ld_size); - close(fd); - - fd = open(kernel, O_RDONLY); - if (fd < 0) - die("can't open kernel: %s", strerror(errno)); - - copy_blocks(fd, ofd, &kern_off, &kern_size); - len += sprintf(buffer+len, "zimage: %x %x\n", kern_off, kern_size); - close(fd); - - if (rdimage) { - fd = open(rdimage, O_RDONLY); - if (fd < 0) - die("can't get ramdisk: %s", strerror(errno)); - - copy_blocks(fd, ofd, &rd_off, &rd_size); - close(fd); - } - - len += sprintf(buffer+len, "initrd: %x %x", rd_off, rd_size); - - close(ofd); - - printf("%s\n", buffer); - - return 0; -} - diff -Nru a/arch/ppc/boot/ns16550.c b/arch/ppc/boot/ns16550.c --- a/arch/ppc/boot/ns16550.c Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,56 +0,0 @@ -/* - * COM1 NS16550 support - */ - -#include "ns16550.h" -typedef struct NS16550 *NS16550_t; - -const NS16550_t COM_PORTS[] = { (NS16550_t) COM1, - (NS16550_t) COM2, - (NS16550_t) COM3, - (NS16550_t) COM4 }; - -volatile struct NS16550 * -NS16550_init(int chan) -{ - volatile struct NS16550 *com_port; - volatile unsigned char xx; - com_port = (struct NS16550 *) COM_PORTS[chan]; - /* See if port is present */ - com_port->lcr = 0x00; - com_port->ier = 0xFF; -#if 0 - if (com_port->ier != 0x0F) return ((struct NS16550 *)0); -#endif - com_port->ier = 0x00; - com_port->lcr = 0x80; /* Access baud rate */ - com_port->dll = 0xc; /* 9600 baud */ - com_port->dlm = 0xc >> 8; - com_port->lcr = 0x03; /* 8 data, 1 stop, no parity */ - com_port->mcr = 0x03; /* RTS/DTR */ - com_port->fcr = 0x07; /* Clear & enable FIFOs */ - return (com_port); -} - - -NS16550_putc(volatile struct NS16550 *com_port, unsigned char c) -{ - volatile int i; - while ((com_port->lsr & LSR_THRE) == 0) ; - com_port->thr = c; -} - -unsigned char -NS16550_getc(volatile struct NS16550 *com_port) -{ - while ((com_port->lsr & LSR_DR) == 0) ; - return (com_port->rbr); -} - -NS16550_tstc(volatile struct NS16550 *com_port) -{ - return ((com_port->lsr & LSR_DR) != 0); -} - - - diff -Nru a/arch/ppc/boot/ns16550.h b/arch/ppc/boot/ns16550.h --- a/arch/ppc/boot/ns16550.h Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,34 +0,0 @@ -/* - * NS16550 Serial Port - */ - -struct NS16550 - { - unsigned char rbr; /* 0 */ - unsigned char ier; /* 1 */ - unsigned char fcr; /* 2 */ - unsigned char lcr; /* 3 */ - unsigned char mcr; /* 4 */ - unsigned char lsr; /* 5 */ - unsigned char msr; /* 6 */ - unsigned char scr; /* 7 */ - }; - -#define thr rbr -#define iir fcr -#define dll rbr -#define dlm ier - -#define LSR_DR 0x01 /* Data ready */ -#define LSR_OE 0x02 /* Overrun */ -#define LSR_PE 0x04 /* Parity error */ -#define LSR_FE 0x08 /* Framing error */ -#define LSR_BI 0x10 /* Break */ -#define LSR_THRE 0x20 /* Xmit holding register empty */ -#define LSR_TEMT 0x40 /* Xmitter empty */ -#define LSR_ERR 0x80 /* Error */ - -#define COM1 0x800003F8 -#define COM2 0x800002F8 -#define COM3 0x800003F8 -#define COM4 0x80000388 diff -Nru a/arch/ppc/boot/of1275.c b/arch/ppc/boot/of1275.c --- a/arch/ppc/boot/of1275.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,427 +0,0 @@ -/* Open Firmware Client Interface */ - - -#include "of1275.h" - - -static int (*of_server)(void *) = (int(*)(void*))-1; - -void -of_init(void *handler) -{ - of_server = (int(*)(void*))handler; -} - - -/* 6.3.2.1 Client interface */ - - -int -of_test(const char *name, int *missing) -{ - int result; - static of_test_service s; - s.service = "test"; - s.n_args = 1; - s.n_returns = 1; - s.name = name; - result = of_server(&s); - *missing = s.missing; - return result; -} - - -/* 6.3.2.2 Device tree */ - - -int -of_peer(int phandle, int *sibling_phandle) -{ - int result; - static of_peer_service s; - s.service = "peer"; - s.n_args = 1; - s.n_returns = 1; - s.phandle = phandle; - result = of_server(&s); - *sibling_phandle = s.sibling_phandle; - return result; -} - -int -of_child(int phandle, int *child_phandle) -{ - int result; - static of_child_service s; - s.service = "child"; - s.n_args = 1; - s.n_returns = 1; - s.phandle = phandle; - result = of_server(&s); - *child_phandle = s.child_phandle; - return result; -} - -int -of_parent(int phandle, int *parent_phandle) -{ - int result; - static of_parent_service s; - s.service = "parent"; - s.n_args = 1; - s.n_returns = 1; - s.phandle = phandle; - result = of_server(&s); - *parent_phandle = s.parent_phandle; - return result; -} - -int -of_instance_to_package(int ihandle, int *phandle) -{ - int result; - static of_instance_to_package_service s; - s.service = "instance-to-package"; - s.n_args = 1; - s.n_returns = 1; - s.ihandle = ihandle; - result = of_server(&s); - *phandle = s.phandle; - return result; -} - -int -of_getproplen(int phandle, const char *name, int *proplen) -{ - int result; - static of_getproplen_service s; - s.service = "getproplen"; - s.n_args = 2; - s.n_returns = 1; - s.phandle = phandle; - s.name = name; - result = of_server(&s); - *proplen = s.proplen; - return result; -} - -int -of_getprop(int phandle, const char *name, void *buf, int buflen, int *size) -{ - int result; - static of_getprop_service s; - s.service = "getprop"; - s.n_args = 4; - s.n_returns = 1; - s.phandle = phandle; - s.name = name; - s.buf = buf; - s.buflen = buflen; - result = of_server(&s); - *size = s.size; - return result; -} - -int -of_nextprop(int phandle, const char *previous, void *buf, int *flag) -{ - int result; - static of_nextprop_service s; - s.service = "nextprop"; - s.n_args = 3; - s.n_returns = 1; - s.phandle = phandle; - s.previous = previous; - s.buf = buf; - result = of_server(&s); - *flag = s.flag; - return result; -} - -int -of_setprop(int phandle, const char *name, void *buf, int len, int *size) -{ - int result; - static of_setprop_service s; - s.service = "setprop"; - s.n_args = 4; - s.n_returns = 1; - s.phandle = phandle; - s.name = name; - s.buf = buf; - s.len = len; - result = of_server(&s); - *size = s.size; - return result; -} - -int -of_canon(const char *device_specifier, void *buf, int buflen, int *length) -{ - int result; - static of_canon_service s; - s.service = "canon"; - s.n_args = 3; - s.n_returns = 1; - s.device_specifier = device_specifier; - s.buf = buf; - s.buflen = buflen; - result = of_server(&s); - *length = s.length; - return result; -} - -int -of_finddevice(const char *device_specifier, int *phandle) -{ - int result; - static of_finddevice_service s; - s.service = "finddevice"; - s.n_args = 1; - s.n_returns = 1; - s.device_specifier = device_specifier; - result = of_server(&s); - *phandle = s.phandle; - return result; -} - -int -of_instance_to_path(int ihandle, void *buf, int buflen, int *length) -{ - int result; - static of_instance_to_path_service s; - s.service = "instance-to-path"; - s.n_args = 3; - s.n_returns = 1; - s.ihandle = ihandle; - s.buf = buf; - s.buflen = buflen; - result = of_server(&s); - *length = s.length; - return result; -} - -int -of_package_to_path(int phandle, void *buf, int buflen, int *length) -{ - int result; - static of_package_to_path_service s; - s.service = "package-to-path"; - s.n_args = 3; - s.n_returns = 1; - s.phandle = phandle; - s.buf = buf; - s.buflen = buflen; - result = of_server(&s); - *length = s.length; - return result; -} - -/* int of_call_method(const char *method, int ihandle, ...); */ - - -/* 6.3.2.3 Device I/O */ - - -int -of_open(const char *device_specifier, int *ihandle) -{ - int result; - static of_open_service s; - s.service = "open"; - s.n_args = 1; - s.n_returns = 1; - s.device_specifier = device_specifier; - result = of_server(&s); - *ihandle = s.ihandle; - return result; -} - -int -of_close(int ihandle) -{ - int result; - static of_close_service s; - s.service = "close"; - s.n_args = 1; - s.n_returns = 0; - s.ihandle = ihandle; - result = of_server(&s); - return result; -} - -int -of_read(int ihandle, void *addr, int len, int *actual) -{ - int result; - static of_read_service s; - s.service = "read"; - s.n_args = 3; - s.n_returns = 1; - s.ihandle = ihandle; - s.addr = addr; - s.len = len; - result = of_server(&s); - *actual = s.actual; - return result; -} - -int -of_write(int ihandle, void *addr, int len, int *actual) -{ - int result; - static of_write_service s; - s.service = "write"; - s.n_args = 3; - s.n_returns = 1; - s.ihandle = ihandle; - s.addr = addr; - s.len = len; - result = of_server(&s); - *actual = s.actual; - return result; -} - -int -of_seek(int ihandle, int pos_hi, int pos_lo, int *status) -{ - int result; - static of_seek_service s; - s.service = "seek"; - s.n_args = 3; - s.n_returns = 1; - s.ihandle = ihandle; - s.pos_hi = pos_hi; - s.pos_lo = pos_lo; - result = of_server(&s); - *status = s.status; - return result; -} - - -/* 6.3.2.4 Memory */ - - -int -of_claim(void *virt, int size, int align, void **baseaddr) -{ - int result; - static of_claim_service s; - s.service = "claim"; - s.n_args = 3; - s.n_returns = 1; - s.virt = virt; - s.size = size; - s.align = align; - result = of_server(&s); - *baseaddr = s.baseaddr; - return result; -} - -int -of_release(void *virt, int size) -{ - int result; - static of_release_service s; - s.service = "release"; - s.n_args = 2; - s.n_returns = 0; - s.virt = virt; - s.size = size; - result = of_server(&s); - return result; -} - - -/* 6.3.2.5 Control transfer */ - - -int -of_boot(const char *bootspec) -{ - int result; - static of_boot_service s; - s.service = "boot"; - s.n_args = 1; - s.n_returns = 0; - s.bootspec = bootspec; - result = of_server(&s); - return result; -} - -int -of_enter(void) -{ - int result; - static of_enter_service s; - s.service = "enter"; - s.n_args = 0; - s.n_returns = 0; - result = of_server(&s); - return result; -} - -int -of_exit(void) -{ - int result; - static of_exit_service s; - s.service = "exit"; - s.n_args = 0; - s.n_returns = 0; - result = of_server(&s); - return result; -} - -/* int of_chain(void *virt, int size, void *entry, void *args, int len); */ - - -/* 6.3.2.6 User interface */ - - -/* int of_interpret(const char *arg, ...); */ - -int -of_set_callback(void *newfunc, void **oldfunc) -{ - int result; - static of_set_callback_service s; - s.service = "set-callback"; - s.n_args = 1; - s.n_returns = 1; - s.newfunc = newfunc; - result = of_server(&s); - *oldfunc = s.oldfunc; - return result; -} - -int -of_set_symbol_lookup(void *sym_to_value, void *value_to_sym) -{ - int result; - static of_set_symbol_lookup_service s; - s.service = "set-symbol-lookup"; - s.n_args = 2; - s.n_returns = 0; - s.sym_to_value = sym_to_value; - s.value_to_sym = s.value_to_sym; - result = of_server(&s); - return result; -} - - -/* 6.3.2.7 Time */ - - -int -of_milliseconds(int *ms) -{ - int result; - static of_milliseconds_service s; - s.service = "milliseconds"; - s.n_args = 0; - s.n_returns = 1; - result = of_server(&s); - *ms = s.ms; - return result; -} diff -Nru a/arch/ppc/boot/of1275.h b/arch/ppc/boot/of1275.h --- a/arch/ppc/boot/of1275.h Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,421 +0,0 @@ -/* 6.3.2.1 Client interface */ - - -typedef struct _of_test_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *name; - /*out*/ - int missing; -} of_test_service; - -int of_test(const char *name, int *missing); - - -/* 6.3.2.2 Device tree */ - - -typedef struct _of_peer_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - /*out*/ - int sibling_phandle; -} of_peer_service; - -int of_peer(int phandle, int *sibling_phandle); - - -typedef struct _of_child_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - /*out*/ - int child_phandle; -} of_child_service; - -int of_child(int phandle, int *child_phandle); - - -typedef struct _of_parent_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - /*out*/ - int parent_phandle; -} of_parent_service; - -int of_child(int phandle, int *parent_phandle); - - -typedef struct _of_instance_to_package_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - /*out*/ - int phandle; -} of_instance_to_package_service; - -int of_instance_to_package(int ihandle, int *phandle); - - -typedef struct _of_getproplen_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - const char *name; - /*out*/ - int proplen; -} of_getproplen_service; - -int of_getproplen(int phandle, const char *name, int *proplen); - - -typedef struct _of_getprop_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - const char *name; - void *buf; - int buflen; - /*out*/ - int size; -} of_getprop_service; - -int of_getprop(int phandle, const char *name, void *buf, int buflen, - int *size); - - -typedef struct _of_nextprop_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - const char *previous; - void *buf; - /*out*/ - int flag; -} of_nextprop_service; - -int of_nextprop(int phandle, const char *previous, void *buf, int *flag); - - -typedef struct _of_setprop_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - const char *name; - void *buf; - int len; - /*out*/ - int size; -} of_setprop_service; - -int of_setprop(int phandle, const char *name, void *buf, int len, int *size); - - -typedef struct _of_canon_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *device_specifier; - void *buf; - int buflen; - /*out*/ - int length; -} of_canon_service; - -int of_canon(const char *device_specifier, void *buf, int buflen, int *length); - - -typedef struct _of_finddevice_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *device_specifier; - /*out*/ - int phandle; -} of_finddevice_service; - -int of_finddevice(const char *device_specifier, int *phandle); - - -typedef struct _of_instance_to_path_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - void *buf; - int buflen; - /*out*/ - int length; -} of_instance_to_path_service; - -int of_instance_to_path(int ihandle, void *buf, int buflen, int *length); - - -typedef struct _of_package_to_path_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int phandle; - void *buf; - int buflen; - /*out*/ - int length; -} of_package_to_path_service; - -int of_package_to_path(int phandle, void *buf, int buflen, int *length); - - -typedef struct _of_call_method_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *method; - int ihandle; - /*...*/ - int args[0]; -} of_call_method_service; - -int of_call_method(const char *method, int ihandle, ...); - - -/* 6.3.2.3 Device I/O */ - - -typedef struct _of_open_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *device_specifier; - /*out*/ - int ihandle; -} of_open_service; - -int of_open(const char *device_specifier, - int *ihandle); - - -typedef struct _of_close_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - /*out*/ -} of_close_service; - -int of_close(int ihandle); - - -typedef struct _of_read_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - void *addr; - int len; - /*out*/ - int actual; -} of_read_service; - -int of_read(int ihandle, void *addr, int len, int *actual); - - -typedef struct _of_write_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - void *addr; - int len; - /*out*/ - int actual; -} of_write_service; - -int of_write(int ihandle, void *addr, int len, int *actual); - - -typedef struct _of_seek_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - int ihandle; - int pos_hi; - int pos_lo; - /*out*/ - int status; -} of_seek_service; - -int of_seek(int ihandle, int pos_hi, int pos_lo, int *status); - - -/* 6.3.2.4 Memory */ - - -typedef struct _of_claim_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *virt; - int size; - int align; - /*out*/ - void *baseaddr; -} of_claim_service; - -int of_claim(void *virt, int size, int align, void **baseaddr); - - -typedef struct _of_release_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *virt; - int size; - int align; - /*out*/ -} of_release_service; - -int of_release(void *virt, int size); - - -/* 6.3.2.5 Control transfer */ - - -typedef struct _of_boot_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *bootspec; - /*out*/ -} of_boot_service; - -int of_boot(const char *bootspec); - - -typedef struct _of_enter_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - /*out*/ -} of_enter_service; - -int of_enter(void); - - -typedef struct _of_exit_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - /*out*/ -} of_exit_service; - -int of_exit(void); - - -typedef struct _of_chain_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *virt; - int size; - void *entry; - void *args; - int len; - /*out*/ -} of_chain_service; - -int of_chain(void *virt, int size, void *entry, void *args, int len); - - -/* 6.3.2.6 User interface */ - - -typedef struct _of_interpret_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - const char *cmd; - int args[0]; - /*...*/ - /*out*/ - /*...*/ -} of_interpret_service; - -int of_interpret(const char *arg, ...); - - -typedef struct _of_set_callback_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *newfunc; - /*out*/ - void *oldfunc; -} of_set_callback_service; - -int of_set_callback(void *newfunc, void **oldfunc); - - -typedef struct _of_set_symbol_lookup_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - void *sym_to_value; - void *value_to_sym; - /*out*/ -} of_set_symbol_lookup_service; - -int of_set_symbol_lookup(void *sym_to_value, void *value_to_sym); - - -/* 6.3.2.7 Time */ - - -typedef struct _of_milliseconds_service { - const char *service; - int n_args; - int n_returns; - /*in*/ - /*out*/ - int ms; -} of_milliseconds_service; - -int of_milliseconds(int *ms); diff -Nru a/arch/ppc/boot/offset b/arch/ppc/boot/offset --- a/arch/ppc/boot/offset Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,4 +0,0 @@ -#!/bin/bash - -OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux| awk '{print $6}'` -echo "0x"$OFFSET 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pmac/Makefile Mon May 21 17:07:04 2001 @@ -0,0 +1,115 @@ +# BK Id: %F% %I% %G% %U% %#% +# +# Makefile for making XCOFF bootable images for booting on PowerMacs +# using Open Firmware. +# +# Paul Mackerras January 1997 +# +# Cleaned up, moved into arch/ppc/boot/pmac +# Tom Rini January 2001 + +OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment +COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic +CHRP_LD_ARGS = -Ttext 0x01000000 + +COMMONOBJS = start.o misc.o ../common/string.o image.o +COFFOBJS = ../common/coffcrt0.o $(COMMONOBJS) coffmain.o +CHRPOBJS = ../common/crt0.o $(COMMONOBJS) chrpmain.o +LIBS = $(TOPDIR)/lib/lib.a ../lib/zlib.a + +MKNOTE := ../utils/mknote +SIZE := ../utils/size +OFFSET := ../utils/offset +PIGGYBACK := ../utils/piggyback +HACKCOFF := ../utils/hack-coff + +ifeq ($(CONFIG_PPC64BRIDGE),y) +MSIZE=.64 +else +MSIZE= +endif + +ifeq ($(CONFIG_SMP),y) +TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE) +else +TFTPIMAGE=/tftpboot/zImage.pmac$(MSIZE) +endif + +../common/crt0.o: + $(MAKE) -C ../common crt0.o + +../common/coffcrt0.o: + $(MAKE) -C ../common coffcrt0.o + +chrpmain.o: chrpmain.c + $(CC) $(CFLAGS) -DSYSMAP_OFFSET=0 -DSYSMAP_SIZE=0 -c chrpmain.c + +znetboot: vmlinux.coff vmlinux.elf-pmac zImage + cp ../images/vmlinux.coff $(TFTPIMAGE) + cp ../images/vmlinux.elf-pmac $(TFTPIMAGE).elf + +znetboot.initrd: vmlinux.coff.initrd vmlinux.initrd.elf-pmac + cp ../images/vmlinux.coff.initrd $(TFTPIMAGE) + cp ../images/vmlinux.elf.pmac.initrd $(TFTPIMAGE).elf + +#floppy: zImage +# mount -t hfs /dev/fd0 /mnt +# cp vmlinux.coff /mnt +# umount /mnt + +miboot.image: dummy.o ../images/vmlinux.gz + $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=image=../images/vmlinux.gz \ + dummy.o ../images/$@ + +miboot.image.initrd: miboot.image ../images/ramdisk.image.gz + $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=../images/ramdisk.image.gz \ + ../images/miboot.image $@ + +coffboot: $(COFFOBJS) $(LIBS) ../common/no_initrd.o ld.script ../images/vmlinux.gz + $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) ../common/no_initrd.o $(LIBS) + +coffboot.initrd: $(COFFOBJS) $(LIBS) initrd.o ld.script ../images/vmlinux.gz + $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) initrd.o $(LIBS) + +image.o: $(PIGGYBACK) ../images/vmlinux.gz + $(PIGGYBACK) image < ../images/vmlinux.gz | $(AS) -o $@ + +initrd.o: ../images/ramdisk.image.gz $(PIGGYBACK) + $(PIGGYBACK) initrd < ../images/ramdisk.image.gz | $(AS) -o $@ + +vmlinux.coff: coffboot $(HACKCOFF) + $(OBJCOPY) $(OBJCOPY_ARGS) coffboot ../images/$@ + $(HACKCOFF) ../images/$@ + rm -f coffboot + ln -sf vmlinux.coff ../images/zImage.pmac + +vmlinux.coff.initrd: coffboot.initrd $(HACKCOFF) + $(OBJCOPY) $(OBJCOPY_ARGS) coffboot.initrd ../images/$@ + $(HACKCOFF) ../images/$@ + rm -f coffboot.initrd + ln -sf vmlinux.coff.initrd ../images/zImage.initrd.pmac + +vmlinux.elf-pmac: $(CHRPOBJS) $(LIBS) ../common/no_initrd.o $(MKNOTE) ../images/vmlinux.gz + $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) ../common/no_initrd.o $(LIBS) + $(MKNOTE) > note + $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \ + --add-section=sysmap=$(TOPDIR)/System.map -R .comment + $(CC) $(CFLAGS) chrpmain.c -c -o chrpmain.o \ + -DSYSMAP_OFFSET=`sh $(OFFSET) $(OBJDUMP) ../images/$@ sysmap` \ + -DSYSMAP_SIZE=`sh $(SIZE) $(OBJDUMP) ../images/$@ sysmap` + $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) ../common/no_initrd.o $(LIBS) + $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note \ + --add-section=sysmap=$(TOPDIR)/System.map -R .comment + rm -f note + +vmlinux.initrd.elf-pmac: $(CHRPOBJS) $(LIBS) initrd.o $(MKNOTE) ../images/vmlinux.gz + $(LD) $(CHRP_LD_ARGS) -o ../images/$@ $(CHRPOBJS) initrd.o $(LIBS) + $(MKNOTE) > note + $(OBJCOPY) ../images/$@ ../images/$@ --add-section=.note=note -R .comment + rm -f note + +zImage: vmlinux.coff vmlinux.elf-pmac miboot.image + +zImage.initrd: vmlinux.coff.initrd vmlinux.initrd.elf-pmac miboot.image.initrd + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/pmac/chrpmain.c b/arch/ppc/boot/pmac/chrpmain.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pmac/chrpmain.c Mon May 21 17:07:04 2001 @@ -0,0 +1,312 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include "nonstdio.h" +#include "zlib.h" +#include +#include +#include + +extern void *finddevice(const char *); +extern int getprop(void *, const char *, void *, int); +extern void *claim(unsigned int, unsigned int, unsigned int); +extern void release(void *ptr, unsigned int len); +void make_bi_recs(unsigned long); +void gunzip(void *, int, unsigned char *, int *); +void stop_imac_ethernet(void); +void stop_imac_usb(void); + +#define get_16be(x) (*(unsigned short *)(x)) +#define get_32be(x) (*(unsigned *)(x)) + +#define RAM_END (16 << 20) + +#define PROG_START 0x00010000 +#define PROG_SIZE 0x003f0000 + +#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; +unsigned int heap_use; +unsigned int heap_max; + +extern char _end[]; +extern char image_data[]; +extern int image_len; +extern char initrd_data[]; +extern int initrd_len; + + +boot(int a1, int a2, void *prom) +{ + int ns, oh, i; + unsigned sa, len; + void *dst; + unsigned char *im; + unsigned initrd_start, initrd_size; + extern char _start; + + printf("chrpboot starting: loaded at 0x%x\n", &_start); + if (initrd_len) { + initrd_size = initrd_len; + initrd_start = (RAM_END - initrd_size) & ~0xFFF; + a1 = initrd_start; + a2 = initrd_size; + claim(initrd_start, RAM_END - initrd_start, 0); + printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", initrd_start, + initrd_data,initrd_size); + memcpy((char *)initrd_start, initrd_data, initrd_size); + } + im = image_data; + len = image_len; + /* claim 3MB starting at PROG_START */ + claim(PROG_START, PROG_SIZE, 0); + dst = (void *) PROG_START; + if (im[0] == 0x1f && im[1] == 0x8b) { + /* claim some memory for scratch space */ + avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10); + begin_avail = avail_high = avail_ram; + end_avail = avail_ram + SCRATCH_SIZE; + printf("heap at 0x%x\n", avail_ram); + printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); + gunzip(dst, PROG_SIZE, im, &len); + printf("done %u bytes\n", len); + printf("%u bytes of heap consumed, max in use %u\n", + avail_high - begin_avail, heap_max); + release(begin_avail, SCRATCH_SIZE); + } else { + memmove(dst, im, len); + } + + flush_cache(dst, len); + memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); + make_bi_recs((unsigned long) dst + len); + + sa = (unsigned long)PROG_START; + printf("start address = 0x%x\n", sa); + + (*(void (*)())sa)(a1, a2, prom); + + printf("returned?\n"); + + pause(); +} + +void make_bi_recs(unsigned long addr) +{ + struct bi_record *rec; + + /* leave a 1MB gap then align to the next 1MB boundary */ + addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); + if (addr >= PROG_START + PROG_SIZE) + claim(addr, 0x1000, 0); + + rec = (struct bi_record *)addr; + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + sprintf( (char *)rec->data, "coffboot"); + rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = _MACH_Pmac; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_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); + +#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 = (struct bi_record *)((unsigned long)rec + rec->size); +#endif /* SYSMAP_OFFSET */ + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); +} + +#if 0 +#define eieio() asm volatile("eieio"); + +void stop_imac_ethernet(void) +{ + void *macio, *enet; + unsigned int macio_addr[5], enet_reg[6]; + int len; + volatile unsigned int *dbdma; + + macio = finddevice("/pci/mac-io"); + enet = finddevice("/pci/mac-io/ethernet"); + if (macio == NULL || enet == NULL) + return; + len = getprop(macio, "assigned-addresses", macio_addr, sizeof(macio_addr)); + if (len != sizeof(macio_addr)) + return; + len = getprop(enet, "reg", enet_reg, sizeof(enet_reg)); + if (len != sizeof(enet_reg)) + return; + printf("macio base %x, dma at %x & %x\n", + macio_addr[2], enet_reg[2], enet_reg[4]); + + /* hope this is mapped... */ + dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[2]); + *dbdma = 0x80; /* clear the RUN bit */ + eieio(); + dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[4]); + *dbdma = 0x80; /* clear the RUN bit */ + eieio(); +} + +void stop_imac_usb(void) +{ + void *usb; + unsigned int usb_addr[5]; + int len; + volatile unsigned int *usb_ctrl; + + usb = finddevice("/pci/usb"); + if (usb == NULL) + return; + len = getprop(usb, "assigned-addresses", usb_addr, sizeof(usb_addr)); + if (len != sizeof(usb_addr)) + return; + printf("usb base %x\n", usb_addr[2]); + + usb_ctrl = (volatile unsigned int *) (usb_addr[2] + 8); + *usb_ctrl = 0x01000000; /* cpu_to_le32(1) */ + eieio(); +} +#endif + +struct memchunk { + unsigned int size; + struct memchunk *next; +}; + +static struct memchunk *freechunks; + +void *zalloc(void *x, unsigned items, unsigned size) +{ + void *p; + struct memchunk **mpp, *mp; + + size *= items; + size = (size + 7) & -8; + heap_use += size; + if (heap_use > heap_max) + heap_max = heap_use; + for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { + if (mp->size == size) { + *mpp = mp->next; + return mp; + } + } + p = avail_ram; + avail_ram += size; + if (avail_ram > avail_high) + avail_high = avail_ram; + if (avail_ram > end_avail) { + printf("oops... out of memory\n"); + pause(); + } + return p; +} + +void zfree(void *x, void *addr, unsigned nb) +{ + struct memchunk *mp = addr; + + nb = (nb + 7) & -8; + heap_use -= nb; + if (avail_ram == addr + nb) { + avail_ram = addr; + return; + } + mp->size = nb; + mp->next = freechunks; + freechunks = mp; +} + +#define HEAD_CRC 2 +#define EXTRA_FIELD 4 +#define ORIG_NAME 8 +#define COMMENT 0x10 +#define RESERVED 0xe0 + +#define DEFLATED 8 + +void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) +{ + z_stream s; + int r, i, flags; + + /* skip header */ + i = 10; + flags = src[3]; + if (src[2] != DEFLATED || (flags & RESERVED) != 0) { + printf("bad gzipped data\n"); + exit(); + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << 8); + if ((flags & ORIG_NAME) != 0) + while (src[i++] != 0) + ; + if ((flags & COMMENT) != 0) + while (src[i++] != 0) + ; + if ((flags & HEAD_CRC) != 0) + i += 2; + if (i >= *lenp) { + printf("gunzip: ran out of data in header\n"); + exit(); + } + + s.zalloc = zalloc; + s.zfree = zfree; + r = inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf("inflateInit2 returned %d\n", r); + exit(); + } + s.next_in = src + i; + s.avail_in = *lenp - i; + s.next_out = dst; + s.avail_out = dstlen; + r = inflate(&s, Z_FINISH); + if (r != Z_OK && r != Z_STREAM_END) { + printf("inflate returned %d msg: %s\n", r, s.msg); + exit(); + } + *lenp = s.next_out - (unsigned char *) dst; + inflateEnd(&s); +} diff -Nru a/arch/ppc/boot/pmac/coffmain.c b/arch/ppc/boot/pmac/coffmain.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pmac/coffmain.c Mon May 21 17:07:04 2001 @@ -0,0 +1,249 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include "nonstdio.h" +#include "zlib.h" +#include +#include +#include + +extern void *finddevice(const char *); +extern int getprop(void *, const char *, void *, int); +extern char *claim(unsigned, unsigned, unsigned); +void make_bi_recs(unsigned long); +void gunzip(void *, int, unsigned char *, int *); + +#define get_16be(x) (*(unsigned short *)(x)) +#define get_32be(x) (*(unsigned *)(x)) + +#define RAM_START 0xc0000000 +#define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */ + +#define PROG_START RAM_START +#define PROG_SIZE 0x00400000 + +#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; +unsigned int heap_use; +unsigned int heap_max; + +extern char _start[], _end[]; +extern char image_data[]; +extern int image_len; +extern char initrd_data[]; +extern int initrd_len; + +char heap[SCRATCH_SIZE]; + +boot(int a1, int a2, void *prom) +{ + int ns, oh, i; + unsigned sa, len; + void *dst; + unsigned char *im; + unsigned initrd_start, initrd_size; + + printf("coffboot starting: loaded at 0x%x\n", _start); + setup_bats(RAM_START); + if (initrd_len) { + initrd_size = initrd_len; + initrd_start = (RAM_END - initrd_size) & ~0xFFF; + a1 = initrd_start; + a2 = initrd_size; + claim(initrd_start - RAM_START, RAM_END - initrd_start, 0); + printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", + initrd_start, initrd_data, initrd_size); + memcpy((char *)initrd_start, initrd_data, initrd_size); + } + im = image_data; + len = image_len; + /* claim 3MB starting at 0 */ + claim(0, PROG_SIZE, 0); + dst = (void *) RAM_START; + if (im[0] == 0x1f && im[1] == 0x8b) { + /* claim some memory for scratch space */ + begin_avail = avail_high = avail_ram = heap; + end_avail = heap + sizeof(heap); + printf("heap at 0x%x\n", avail_ram); + printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); + gunzip(dst, PROG_SIZE, im, &len); + printf("done %u bytes\n", len); + printf("%u bytes of heap consumed, max in use %u\n", + avail_high - begin_avail, heap_max); + } else { + memmove(dst, im, len); + } + + flush_cache(dst, len); + memcpy (cmd_line, cmd_preset, sizeof(cmd_preset)); + make_bi_recs((unsigned long)dst + len); + + sa = (unsigned long)PROG_START; + printf("start address = 0x%x\n", sa); + + (*(void (*)())sa)(a1, a2, prom); + + printf("returned?\n"); + + pause(); +} + +void make_bi_recs(unsigned long addr) +{ + struct bi_record *rec; + + addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); +#if 0 + if (addr >= PROG_START + PROG_SIZE) + claim(addr, 0x1000, 0); +#endif + + rec = (struct bi_record *)addr; + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + sprintf( (char *)rec->data, "coffboot"); + rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = _MACH_Pmac; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_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); +} + +struct memchunk { + unsigned int size; + struct memchunk *next; +}; + +static struct memchunk *freechunks; + +void *zalloc(void *x, unsigned items, unsigned size) +{ + void *p; + struct memchunk **mpp, *mp; + + size *= items; + size = (size + 7) & -8; + heap_use += size; + if (heap_use > heap_max) + heap_max = heap_use; + for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { + if (mp->size == size) { + *mpp = mp->next; + return mp; + } + } + p = avail_ram; + avail_ram += size; + if (avail_ram > avail_high) + avail_high = avail_ram; + if (avail_ram > end_avail) { + printf("oops... out of memory\n"); + pause(); + } + return p; +} + +void zfree(void *x, void *addr, unsigned nb) +{ + struct memchunk *mp = addr; + + nb = (nb + 7) & -8; + heap_use -= nb; + if (avail_ram == addr + nb) { + avail_ram = addr; + return; + } + mp->size = nb; + mp->next = freechunks; + freechunks = mp; +} + +#define HEAD_CRC 2 +#define EXTRA_FIELD 4 +#define ORIG_NAME 8 +#define COMMENT 0x10 +#define RESERVED 0xe0 + +#define DEFLATED 8 + +void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) +{ + z_stream s; + int r, i, flags; + + /* skip header */ + i = 10; + flags = src[3]; + if (src[2] != DEFLATED || (flags & RESERVED) != 0) { + printf("bad gzipped data\n"); + exit(); + } + if ((flags & EXTRA_FIELD) != 0) + i = 12 + src[10] + (src[11] << 8); + if ((flags & ORIG_NAME) != 0) + while (src[i++] != 0) + ; + if ((flags & COMMENT) != 0) + while (src[i++] != 0) + ; + if ((flags & HEAD_CRC) != 0) + i += 2; + if (i >= *lenp) { + printf("gunzip: ran out of data in header\n"); + exit(); + } + + s.zalloc = zalloc; + s.zfree = zfree; + r = inflateInit2(&s, -MAX_WBITS); + if (r != Z_OK) { + printf("inflateInit2 returned %d\n", r); + exit(); + } + s.next_in = src + i; + s.avail_in = *lenp - i; + s.next_out = dst; + s.avail_out = dstlen; + r = inflate(&s, Z_FINISH); + if (r != Z_OK && r != Z_STREAM_END) { + printf("inflate returned %d msg: %s\n", r, s.msg); + exit(); + } + *lenp = s.next_out - (unsigned char *) dst; + inflateEnd(&s); +} diff -Nru a/arch/ppc/boot/pmac/dummy.c b/arch/ppc/boot/pmac/dummy.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pmac/dummy.c Mon May 21 17:07:04 2001 @@ -0,0 +1,7 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +int main(void) +{ + return 0; +} diff -Nru a/arch/ppc/boot/pmac/ld.script b/arch/ppc/boot/pmac/ld.script --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pmac/ld.script Mon May 21 17:07:04 2001 @@ -0,0 +1,68 @@ +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0 + .plt : { *(.plt) } + .text : + { + *(.text) + *(.rodata) + *(.rodata1) + *(.got1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + _etext = .; + PROVIDE (etext = .); + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.got.plt) *(.got) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} + diff -Nru a/arch/ppc/boot/pmac/misc.S b/arch/ppc/boot/pmac/misc.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pmac/misc.S Mon May 21 17:07:04 2001 @@ -0,0 +1,60 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + .text + +/* + * Use the BAT3 registers to map the 1st 8MB of RAM to + * the address given as the 1st argument. + */ + .globl setup_bats +setup_bats: + mfpvr 5 + rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */ + cmpi 0,5,1 + li 0,0 + bne 4f + mtibatl 3,0 /* invalidate BAT first */ + ori 3,3,4 /* set up BAT registers for 601 */ + li 4,0x7f + mtibatu 3,3 + mtibatl 3,4 + b 5f +4: mtdbatu 3,0 /* invalidate BATs first */ + mtibatu 3,0 + ori 3,3,0xff /* set up BAT registers for 604 */ + li 4,2 + mtdbatl 3,4 + mtdbatu 3,3 + mtibatl 3,4 + mtibatu 3,3 +5: sync + isync + blr + +/* + * Flush the dcache and invalidate the icache for a range of addresses. + * + * flush_cache(addr, len) + */ + .global flush_cache +flush_cache: + addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ + rlwinm. 4,4,27,5,31 + mtctr 4 + beqlr +1: dcbf 0,3 + icbi 0,3 + addi 3,3,0x20 + bdnz 1b + sync + isync + blr diff -Nru a/arch/ppc/boot/pmac/start.c b/arch/ppc/boot/pmac/start.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/pmac/start.c Mon May 21 17:07:05 2001 @@ -0,0 +1,343 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include + +int (*prom)(); + +void *chosen_handle; +void *stdin; +void *stdout; +void *stderr; + +void exit(void); +void *finddevice(const char *name); +int getprop(void *phandle, const char *name, void *buf, int buflen); +void printk(char *fmt, ...); + +void +start(int a1, int a2, void *promptr) +{ + prom = (int (*)()) promptr; + chosen_handle = finddevice("/chosen"); + if (chosen_handle == (void *) -1) + exit(); + if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) + exit(); + stderr = stdout; + if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) + exit(); + + boot(a1, a2, promptr); + for (;;) + exit(); +} + +int +write(void *handle, void *ptr, int nb) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *ihandle; + void *addr; + int len; + int actual; + } args; + + args.service = "write"; + args.nargs = 3; + args.nret = 1; + args.ihandle = handle; + args.addr = ptr; + args.len = nb; + args.actual = -1; + (*prom)(&args); + return args.actual; +} + +int writestring(void *f, char *ptr, int nb) +{ + int w = 0, i; + char *ret = "\r"; + + for (i = 0; i < nb; ++i) { + if (ptr[i] == '\n') { + if (i > w) { + write(f, ptr + w, i - w); + w = i; + } + write(f, ret, 1); + } + } + if (w < nb) + write(f, ptr + w, nb - w); + return nb; +} + +int +read(void *handle, void *ptr, int nb) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *ihandle; + void *addr; + int len; + int actual; + } args; + + args.service = "read"; + args.nargs = 3; + args.nret = 1; + args.ihandle = handle; + args.addr = ptr; + args.len = nb; + args.actual = -1; + (*prom)(&args); + return args.actual; +} + +void +exit() +{ + struct prom_args { + char *service; + } args; + + for (;;) { + args.service = "exit"; + (*prom)(&args); + } +} + +void +pause() +{ + struct prom_args { + char *service; + } args; + + args.service = "enter"; + (*prom)(&args); +} + +void * +finddevice(const char *name) +{ + struct prom_args { + char *service; + int nargs; + int nret; + const char *devspec; + void *phandle; + } args; + + args.service = "finddevice"; + args.nargs = 1; + args.nret = 1; + args.devspec = name; + args.phandle = (void *) -1; + (*prom)(&args); + return args.phandle; +} + +void * +claim(unsigned int virt, unsigned int size, unsigned int align) +{ + struct prom_args { + char *service; + int nargs; + int nret; + unsigned int virt; + unsigned int size; + unsigned int align; + void *ret; + } args; + + args.service = "claim"; + args.nargs = 3; + args.nret = 1; + args.virt = virt; + args.size = size; + args.align = align; + (*prom)(&args); + return args.ret; +} + +void +release(void *virt, unsigned int size) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *virt; + unsigned int size; + } args; + + args.service = "release"; + args.nargs = 2; + args.nret = 0; + args.virt = virt; + args.size = size; + (*prom)(&args); +} + +int +getprop(void *phandle, const char *name, void *buf, int buflen) +{ + struct prom_args { + char *service; + int nargs; + int nret; + void *phandle; + const char *name; + void *buf; + int buflen; + int size; + } args; + + args.service = "getprop"; + args.nargs = 4; + args.nret = 1; + args.phandle = phandle; + args.name = name; + args.buf = buf; + args.buflen = buflen; + args.size = -1; + (*prom)(&args); + return args.size; +} + +int +putc(int c, void *f) +{ + char ch = c; + + return writestring(f, &ch, 1) == 1? c: -1; +} + +int +putchar(int c) +{ + return putc(c, stdout); +} + +int +fputs(char *str, void *f) +{ + int n = strlen(str); + + return writestring(f, str, n) == n? 0: -1; +} + +int +readchar() +{ + char ch; + + for (;;) { + switch (read(stdin, &ch, 1)) { + case 1: + return ch; + case -1: + printk("read(stdin) returned -1\n"); + return -1; + } + } +} + +static char line[256]; +static char *lineptr; +static int lineleft; + +int +getchar() +{ + int c; + + if (lineleft == 0) { + lineptr = line; + for (;;) { + c = readchar(); + if (c == -1 || c == 4) + break; + if (c == '\r' || c == '\n') { + *lineptr++ = '\n'; + putchar('\n'); + break; + } + switch (c) { + case 0177: + case '\b': + if (lineptr > line) { + putchar('\b'); + putchar(' '); + putchar('\b'); + --lineptr; + } + break; + case 'U' & 0x1F: + while (lineptr > line) { + putchar('\b'); + putchar(' '); + putchar('\b'); + --lineptr; + } + break; + default: + if (lineptr >= &line[sizeof(line) - 1]) + putchar('\a'); + else { + putchar(c); + *lineptr++ = c; + } + } + } + lineleft = lineptr - line; + lineptr = line; + } + if (lineleft == 0) + return -1; + --lineleft; + return *lineptr++; +} + +extern int vsprintf(char *buf, const char *fmt, va_list args); +static char sprint_buf[1024]; + +void +printk(char *fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vsprintf(sprint_buf, fmt, args); + va_end(args); + writestring(stdout, sprint_buf, n); +} + +int +printf(char *fmt, ...) +{ + va_list args; + int n; + + va_start(args, fmt); + n = vsprintf(sprint_buf, fmt, args); + va_end(args); + writestring(stdout, sprint_buf, n); + return n; +} 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/prep/Makefile Mon May 21 17:07:05 2001 @@ -0,0 +1,114 @@ +# BK Id: %F% %I% %G% %U% %#% +# +# arch/ppc/boot/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. +# +# Tom Rini January 2001 +# +# Originally: +# arch/ppc/boot/Makefile +# Copyright (C) 1994 by Linus Torvalds +# Adapted for PowerPC by Gary Thomas +# modified by Cort (cort@cs.nmt.edu) +# + +.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 $< + +ifeq ($(CONFIG_SMP),y) +TFTPIMAGE=/tftpboot/zImage.prep.smp +else +TFTPIMAGE=/tftpboot/zImage.prep +endif + +ZLINKFLAGS = -T $(TOPDIR)/arch/$(ARCH)/vmlinux.lds -Ttext 0x00800000 +OBJECTS := head.o misc.o vreset.o kbd.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 + +# Tools +MKPREP := ../utils/mkprep +SIZE := ../utils/size +OFFSET := ../utils/offset + +all: zImage + +misc.o: misc.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: zvmlinux ../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 misc.o misc.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) + $(MKPREP) -pbp zvmlinux ../images/zImage.prep + rm -f zvmlinux + +zImage.initrd: zvmlinux.initrd $(MKPREP) + $(MKPREP) -pbp zvmlinux.initrd ../images/zImage.prep.initrd + 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 zvmlinux.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz zvmlinux.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) zvmlinux image` \ + -DZIMAGE_SIZE=`sh $(SIZE) $(OBJDUMP) zvmlinux image` \ + -c -o misc.o misc.c + $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) $(LIBS) + $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ + --add-section=image=../images/vmlinux.gz zvmlinux.tmp $@ + rm zvmlinux.tmp + +floppy: zImage + dd if=../images/zImage.prep of=/dev/fd0H1440 bs=64b + +znetboot : zImage + cp ../images/zImage.prep $(TFTPIMAGE) + +znetboot.initrd : zImage.initrd + cp ../images/zImage.prep.initrd $(TFTPIMAGE) + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/prep/head.S b/arch/ppc/boot/prep/head.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/prep/head.S Mon May 21 17:07:03 2001 @@ -0,0 +1,248 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +#include "../../kernel/ppc_defs.h" +#include "../../kernel/ppc_asm.tmpl" +#include +#include + + .text + +/* + * Boot loader philosophy: + * ROM loads us to some arbitrary location + * Move the boot code to the link address (8M) + * Call decompress_kernel() + * Relocate the initrd, zimage and residual data to 8M + * Decompress the kernel to 0 + * Jump to the kernel entry + * -- Cort + */ + .globl start +start: + bl start_ +start_: + mr r11,r3 /* Save pointer to residual/board data */ + mr r25,r5 /* Save OFW pointer */ + li r3,MSR_IP /* Establish default MSR value */ + mtmsr r3 + +/* 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 */ + 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 +/* Run loader */ + mr r3,r8 /* Load point */ + mr r4,r7 /* Program length */ + mr r5,r6 /* Checksum */ + mr r6,r11 /* Residual data */ + mr r7,r25 /* OFW interfaces */ + bl decompress_kernel + + /* changed to use r3 (as firmware does) for kernel + as ptr to residual -- Cort*/ + 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) + + + /* tell kernel we're prep */ + /* + * get start address of kernel code which is stored as a coff + * entry. see boot/head.S -- Cort + */ + li r9,0x4 + mtlr r9 + lis r10,0xdeadc0de@h + ori r10,r10,0xdeadc0de@l + li r9,0 + stw r10,0(r9) +/* + * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2 + * so disable BATs before setting this to avoid a clash + */ + li r8,0 + mtspr DBAT0U,r8 + mtspr DBAT1U,r8 + mtspr DBAT2U,r8 + mtspr DBAT3U,r8 + mtspr IBAT0U,r8 + mtspr IBAT1U,r8 + mtspr IBAT2U,r8 + mtspr IBAT3U,r8 + + 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/iso_font.h b/arch/ppc/boot/prep/iso_font.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/prep/iso_font.h Mon May 21 17:07:04 2001 @@ -0,0 +1,260 @@ +/* + * 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, +/* 0x01 */ 0x00,0x00,0x7E,0x81,0xA5,0x81,0x81,0xBD,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00, +/* 0x02 */ 0x00,0x00,0x7E,0xFF,0xDB,0xFF,0xFF,0xC3,0xC3,0xE7,0xFF,0x7E,0x00,0x00,0x00,0x00, +/* 0x03 */ 0x00,0x00,0x00,0x00,0x6C,0xFE,0xFE,0xFE,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00, +/* 0x04 */ 0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00, +/* 0x05 */ 0x00,0x00,0x00,0x18,0x3C,0x3C,0xE7,0xE7,0xE7,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, +/* 0x06 */ 0x00,0x00,0x00,0x18,0x3C,0x7E,0xFF,0xFF,0x7E,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, +/* 0x07 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x08 */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +/* 0x09 */ 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00,0x00,0x00,0x00,0x00, +/* 0x0A */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF, +/* 0x0B */ 0x00,0x00,0x3E,0x0E,0x1A,0x32,0x78,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00, +/* 0x0C */ 0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00, +/* 0x0D */ 0x00,0x00,0x30,0x38,0x3C,0x36,0x33,0x30,0x30,0x70,0xF0,0xE0,0x00,0x00,0x00,0x00, +/* 0x0E */ 0x00,0x00,0x7F,0x63,0x7F,0x63,0x63,0x63,0x63,0x67,0xE7,0xE6,0xC0,0x00,0x00,0x00, +/* 0x0F */ 0x00,0x00,0x00,0x18,0x18,0xDB,0x3C,0xE7,0x3C,0xDB,0x18,0x18,0x00,0x00,0x00,0x00, +/* 0x10 */ 0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00, +/* 0x11 */ 0x00,0x02,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x02,0x00,0x00,0x00,0x00, +/* 0x12 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00, +/* 0x13 */ 0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00, +/* 0x14 */ 0x00,0x00,0x7F,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00, +/* 0x15 */ 0x00,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00, +/* 0x16 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00, +/* 0x17 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x7E,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00, +/* 0x18 */ 0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +/* 0x19 */ 0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00, +/* 0x1A */ 0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x1B */ 0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x1C */ 0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x1D */ 0x00,0x00,0x00,0x00,0x00,0x28,0x6C,0xFE,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x1E */ 0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00, +/* 0x1F */ 0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00, +/* 0x20 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x21 */ 0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, +/* 0x22 */ 0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x23 */ 0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00, +/* 0x24 */ 0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00, +/* 0x25 */ 0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00, +/* 0x26 */ 0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0x27 */ 0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x28 */ 0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00, +/* 0x29 */ 0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00, +/* 0x2A */ 0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x2B */ 0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x2C */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00, +/* 0x2D */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x2E */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, +/* 0x2F */ 0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00, +/* 0x30 */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00, +/* 0x31 */ 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00, +/* 0x32 */ 0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00, +/* 0x33 */ 0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x34 */ 0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00, +/* 0x35 */ 0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x36 */ 0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x37 */ 0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00, +/* 0x38 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x39 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00, +/* 0x3A */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, +/* 0x3B */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00, +/* 0x3C */ 0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00, +/* 0x3D */ 0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x3E */ 0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00, +/* 0x3F */ 0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, +/* 0x40 */ 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00, +/* 0x41 */ 0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, +/* 0x42 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00, +/* 0x43 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00, +/* 0x44 */ 0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00, +/* 0x45 */ 0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00, +/* 0x46 */ 0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, +/* 0x47 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00, +/* 0x48 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, +/* 0x49 */ 0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, +/* 0x4A */ 0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00, +/* 0x4B */ 0x00,0x00,0xE6,0x66,0x66,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00, +/* 0x4C */ 0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00, +/* 0x4D */ 0x00,0x00,0xC6,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, +/* 0x4E */ 0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, +/* 0x4F */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x50 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, +/* 0x51 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00, +/* 0x52 */ 0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00, +/* 0x53 */ 0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x54 */ 0x00,0x00,0x7E,0x7E,0x5A,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, +/* 0x55 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x56 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00, +/* 0x57 */ 0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00, +/* 0x58 */ 0x00,0x00,0xC6,0xC6,0x6C,0x7C,0x38,0x38,0x7C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00, +/* 0x59 */ 0x00,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, +/* 0x5A */ 0x00,0x00,0xFE,0xC6,0x86,0x0C,0x18,0x30,0x60,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00, +/* 0x5B */ 0x00,0x00,0x3C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3C,0x00,0x00,0x00,0x00, +/* 0x5C */ 0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x06,0x02,0x00,0x00,0x00,0x00, +/* 0x5D */ 0x00,0x00,0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00,0x00,0x00,0x00, +/* 0x5E */ 0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x5F */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, +/* 0x60 */ 0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x61 */ 0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0x62 */ 0x00,0x00,0xE0,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00, +/* 0x63 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x64 */ 0x00,0x00,0x1C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0x65 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x66 */ 0x00,0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, +/* 0x67 */ 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x06,0x66,0x3C,0x00, +/* 0x68 */ 0x00,0x00,0xE0,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00, +/* 0x69 */ 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, +/* 0x6A */ 0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00, +/* 0x6B */ 0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00, +/* 0x6C */ 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, +/* 0x6D */ 0x00,0x00,0x00,0x00,0x00,0x6C,0xFE,0xD6,0xD6,0xD6,0xC6,0xC6,0x00,0x00,0x00,0x00, +/* 0x6E */ 0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, +/* 0x6F */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x70 */ 0x00,0x00,0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00, +/* 0x71 */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00, +/* 0x72 */ 0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x66,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00, +/* 0x73 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x74 */ 0x00,0x00,0x10,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00, +/* 0x75 */ 0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0x76 */ 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00, +/* 0x77 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x00,0x00,0x00,0x00, +/* 0x78 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00, +/* 0x79 */ 0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00, +/* 0x7A */ 0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00, +/* 0x7B */ 0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00, +/* 0x7C */ 0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +/* 0x7D */ 0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00, +/* 0x7E */ 0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0x7F */ 0x00,0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00, +/* 0x80 */ 0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x0C,0x06,0x7C,0x00,0x00, +/* 0x81 */ 0x00,0x00,0xCC,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0x82 */ 0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x83 */ 0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0x84 */ 0x00,0x00,0xCC,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0x85 */ 0x00,0x60,0x30,0x18,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0x86 */ 0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0x87 */ 0x00,0x00,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x0C,0x06,0x3C,0x00,0x00,0x00, +/* 0x88 */ 0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x89 */ 0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x8A */ 0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x8B */ 0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, +/* 0x8C */ 0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, +/* 0x8D */ 0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, +/* 0x8E */ 0x00,0xC6,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, +/* 0x8F */ 0x38,0x6C,0x38,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, +/* 0x90 */ 0x18,0x30,0x60,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00, +/* 0x91 */ 0x00,0x00,0x00,0x00,0x00,0xCC,0x76,0x36,0x7E,0xD8,0xD8,0x6E,0x00,0x00,0x00,0x00, +/* 0x92 */ 0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00, +/* 0x93 */ 0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x94 */ 0x00,0x00,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x95 */ 0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x96 */ 0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0x97 */ 0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0x98 */ 0x00,0x00,0xC6,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00, +/* 0x99 */ 0x00,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x9A */ 0x00,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0x9B */ 0x00,0x18,0x18,0x3C,0x66,0x60,0x60,0x60,0x66,0x3C,0x18,0x18,0x00,0x00,0x00,0x00, +/* 0x9C */ 0x00,0x38,0x6C,0x64,0x60,0xF8,0x60,0x60,0x60,0x60,0xE6,0xFC,0x00,0x00,0x00,0x00, +/* 0x9D */ 0x00,0x00,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +/* 0x9E */ 0x00,0xF8,0xCC,0xCC,0xF8,0xC4,0xCC,0xDE,0xCC,0xCC,0xCC,0xC6,0x00,0x00,0x00,0x00, +/* 0x9F */ 0x00,0x0E,0x1B,0x18,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x18,0xD8,0x70,0x00,0x00, +/* 0xA0 */ 0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0xA1 */ 0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00, +/* 0xA2 */ 0x00,0x18,0x30,0x60,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0xA3 */ 0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00, +/* 0xA4 */ 0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, +/* 0xA5 */ 0x76,0xDC,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, +/* 0xA6 */ 0x00,0x3C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xA7 */ 0x00,0x38,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xA8 */ 0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xC0,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00, +/* 0xA9 */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00, +/* 0xAA */ 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00, +/* 0xAB */ 0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x60,0xDC,0x86,0x0C,0x18,0x3E,0x00,0x00, +/* 0xAC */ 0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x66,0xCE,0x9E,0x3E,0x06,0x06,0x00,0x00, +/* 0xAD */ 0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00, +/* 0xAE */ 0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xAF */ 0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xB0 */ 0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44, +/* 0xB1 */ 0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA, +/* 0xB2 */ 0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77, +/* 0xB3 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xB4 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xB5 */ 0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xB6 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xB7 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xB8 */ 0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xB9 */ 0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xBA */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xBB */ 0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xBC */ 0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xBD */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xBE */ 0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xBF */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xC0 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xC1 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xC2 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xC3 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xC4 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xC5 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xC6 */ 0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xC7 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xC8 */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xC9 */ 0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xCA */ 0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xCB */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xCC */ 0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xCD */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xCE */ 0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xCF */ 0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xD0 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xD1 */ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xD2 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xD3 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xD4 */ 0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xD5 */ 0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xD6 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xD7 */ 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +/* 0xD8 */ 0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xD9 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xDA */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xDB */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +/* 0xDC */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, +/* 0xDD */ 0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0, +/* 0xDE */ 0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F, +/* 0xDF */ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xE0 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0xD8,0xD8,0xD8,0xDC,0x76,0x00,0x00,0x00,0x00, +/* 0xE1 */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xFC,0xC6,0xC6,0xC6,0xC6,0xDC,0xC0,0xC0,0x00,0x00, +/* 0xE2 */ 0x00,0x00,0xFE,0xC6,0xC6,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00, +/* 0xE3 */ 0x00,0x00,0x00,0x00,0x00,0xFE,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00, +/* 0xE4 */ 0x00,0x00,0xFE,0xC6,0x60,0x30,0x18,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00, +/* 0xE5 */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00, +/* 0xE6 */ 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0xC0,0x00,0x00,0x00, +/* 0xE7 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +/* 0xE8 */ 0x00,0x00,0x7E,0x18,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00, +/* 0xE9 */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00, +/* 0xEA */ 0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x6C,0x6C,0x6C,0xEE,0x00,0x00,0x00,0x00, +/* 0xEB */ 0x00,0x00,0x1E,0x30,0x18,0x0C,0x3E,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00, +/* 0xEC */ 0x00,0x00,0x00,0x00,0x00,0x7E,0xDB,0xDB,0xDB,0x7E,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xED */ 0x00,0x00,0x00,0x03,0x06,0x7E,0xDB,0xDB,0xF3,0x7E,0x60,0xC0,0x00,0x00,0x00,0x00, +/* 0xEE */ 0x00,0x00,0x1C,0x30,0x60,0x60,0x7C,0x60,0x60,0x60,0x30,0x1C,0x00,0x00,0x00,0x00, +/* 0xEF */ 0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00, +/* 0xF0 */ 0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00, +/* 0xF1 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0xFF,0x00,0x00,0x00,0x00, +/* 0xF2 */ 0x00,0x00,0x00,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00,0x7E,0x00,0x00,0x00,0x00, +/* 0xF3 */ 0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00,0x7E,0x00,0x00,0x00,0x00, +/* 0xF4 */ 0x00,0x0E,0x1B,0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +/* 0xF5 */ 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00, +/* 0xF6 */ 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7E,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, +/* 0xF7 */ 0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xF8 */ 0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xF9 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xFA */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xFB */ 0x00,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0xEC,0x6C,0x6C,0x3C,0x1C,0x00,0x00,0x00,0x00, +/* 0xFC */ 0x00,0xD8,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xFD */ 0x00,0x70,0xD8,0x30,0x60,0xC8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +/* 0xFE */ 0x00,0x00,0x00,0x00,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x00,0x00,0x00,0x00,0x00, +}; diff -Nru a/arch/ppc/boot/prep/kbd.c b/arch/ppc/boot/prep/kbd.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/prep/kbd.c Mon May 21 17:07:04 2001 @@ -0,0 +1,218 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +#include + +#include <../drivers/char/defkeymap.c> /* yeah I know it's bad -- Cort */ + + +unsigned char shfts, ctls, alts, caps; + +#define KBDATAP 0x60 /* kbd data port */ +#define KBSTATUSPORT 0x61 /* kbd status */ +#define KBSTATP 0x64 /* kbd status port */ +#define KBINRDY 0x01 +#define KBOUTRDY 0x02 + +extern unsigned char inb(int port); +extern void outb(int port, char val); +extern void puts(const char *); +extern void puthex(unsigned long val); +extern void udelay(long x); + +static int kbd(int noblock) +{ + unsigned char dt, brk, val; + unsigned code; +loop: + if (noblock) { + if ((inb(KBSTATP) & KBINRDY) == 0) + return (-1); + } else while((inb(KBSTATP) & KBINRDY) == 0) ; + + dt = inb(KBDATAP); + + brk = dt & 0x80; /* brk == 1 on key release */ + dt = dt & 0x7f; /* keycode */ + + if (shfts) + code = shift_map[dt]; + else if (ctls) + code = ctrl_map[dt]; + else + code = plain_map[dt]; + + val = KVAL(code); + switch (KTYP(code) & 0x0f) { + case KT_LATIN: + if (brk) + break; + if (alts) + val |= 0x80; + if (val == 0x7f) /* map delete to backspace */ + val = '\b'; + return val; + + case KT_LETTER: + if (brk) + break; + if (caps) + val -= 'a'-'A'; + return val; + + case KT_SPEC: + if (brk) + break; + if (val == KVAL(K_CAPS)) + caps = !caps; + else if (val == KVAL(K_ENTER)) { +enter: /* Wait for key up */ + while (1) { + while((inb(KBSTATP) & KBINRDY) == 0) ; + dt = inb(KBDATAP); + if (dt & 0x80) /* key up */ break; + } + return 10; + } + break; + + case KT_PAD: + if (brk) + break; + if (val < 10) + return val; + if (val == KVAL(K_PENTER)) + goto enter; + break; + + case KT_SHIFT: + switch (val) { + case KG_SHIFT: + case KG_SHIFTL: + case KG_SHIFTR: + shfts = brk ? 0 : 1; + break; + case KG_ALT: + case KG_ALTGR: + alts = brk ? 0 : 1; + break; + case KG_CTRL: + case KG_CTRLL: + case KG_CTRLR: + ctls = brk ? 0 : 1; + break; + } + break; + + case KT_LOCK: + switch (val) { + case KG_SHIFT: + case KG_SHIFTL: + case KG_SHIFTR: + if (brk) + shfts = !shfts; + break; + case KG_ALT: + case KG_ALTGR: + if (brk) + alts = !alts; + break; + case KG_CTRL: + case KG_CTRLL: + case KG_CTRLR: + if (brk) + ctls = !ctls; + break; + } + break; + } + if (brk) return (-1); /* Ignore initial 'key up' codes */ + goto loop; +} + +static void kbdreset(void) +{ + unsigned char c; + int i; + + /* flush input queue */ + while ((inb(KBSTATP) & KBINRDY)) + { + (void)inb(KBDATAP); + } + /* Send self-test */ + while (inb(KBSTATP) & KBOUTRDY) ; + outb(KBSTATP,0xAA); + while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */ + if ((c = inb(KBDATAP)) != 0x55) + { + puts("Keyboard self test failed - result:"); + puthex(c); + puts("\n"); + } + /* Enable interrupts and keyboard controller */ + while (inb(KBSTATP) & KBOUTRDY) ; + outb(KBSTATP,0x60); + while (inb(KBSTATP) & KBOUTRDY) ; + outb(KBDATAP,0x45); + for (i = 0; i < 10000; i++) udelay(1); + + while (inb(KBSTATP) & KBOUTRDY) ; + outb(KBSTATP,0x20); + while ((inb(KBSTATP) & KBINRDY) == 0) ; /* wait input ready */ + if (! (inb(KBDATAP) & 0x40)) { + /* + * Quote from PS/2 System Reference Manual: + * + * "Address hex 0060 and address hex 0064 should be + * written only when the input-buffer-full bit and + * output-buffer-full bit in the Controller Status + * register are set 0." (KBINRDY and KBOUTRDY) + */ + + while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ; + outb(KBDATAP,0xF0); + while (inb(KBSTATP) & (KBINRDY | KBOUTRDY)) ; + outb(KBDATAP,0x01); + } + + while (inb(KBSTATP) & KBOUTRDY) ; + outb(KBSTATP,0xAE); +} + +/* We have to actually read the keyboard when CRT_tstc is called, + * since the pending data might be a key release code, and therefore + * not valid data. In this case, kbd() will return -1, even though there's + * data to be read. Of course, we might actually read a valid key press, + * in which case it gets queued into key_pending for use by CRT_getc. + */ + +static int kbd_reset = 0; + +static int key_pending = -1; + +int CRT_getc(void) +{ + int c; + if (!kbd_reset) {kbdreset(); kbd_reset++; } + + if (key_pending != -1) { + c = key_pending; + key_pending = -1; + return c; + } else { + while ((c = kbd(0)) == 0) ; + return c; + } +} + +int CRT_tstc(void) +{ + if (!kbd_reset) {kbdreset(); kbd_reset++; } + + while (key_pending == -1 && ((inb(KBSTATP) & KBINRDY) != 0)) { + key_pending = kbd(1); + } + + return (key_pending != -1); +} diff -Nru a/arch/ppc/boot/prep/misc.c b/arch/ppc/boot/prep/misc.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/prep/misc.c Mon May 21 17:07:03 2001 @@ -0,0 +1,453 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * misc.c + * + * Adapted for PowerPC by Gary Thomas + * + * Rewritten by Cort Dougan (cort@cs.nmt.edu) + * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort + */ + +#include +#include "zlib.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(CONFIG_SERIAL_CONSOLE) +unsigned long com_port; +#endif /* CONFIG_SERIAL_CONSOLE */ + +/* + * Please send me load/board info and such data for hardware not + * listed here so I can keep track since things are getting tricky + * with the different load addrs with different firmware. This will + * help to avoid breaking the load/boot process. + * -- Cort + */ +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; + +int keyb_present = 1; /* keyboard controller is present by default */ +RESIDUAL hold_resid_buf; +RESIDUAL *hold_residual = &hold_resid_buf; +unsigned long initrd_start = 0, initrd_end = 0; +char *zimage_start; +int zimage_size; + +char *vidmem = (char *)0xC00B8000; +int lines, cols; +int orig_x, orig_y; + +extern void puts(const char *); +extern void putc(const char c); +extern int tstc(void); +extern int getc(void); +extern void puthex(unsigned long val); +extern void * memcpy(void * __dest, __const void * __src, __kernel_size_t __n); +extern int CRT_tstc(void); +extern void of_init(void *handler); +extern int of_finddevice(const char *device_specifier, int *phandle); +extern int of_getprop(int phandle, const char *name, void *buf, int buflen, + int *size); +extern __kernel_size_t strlen(const char *s); +extern int vga_init(unsigned char *ISA_mem); +extern void udelay(long x); +void gunzip(void *, int, unsigned char *, int *); +unsigned char inb(int); + +void +writel(unsigned int val, unsigned int address) +{ + /* Ensure I/O operations complete */ + __asm__ volatile("eieio"); + *(unsigned int *)address = cpu_to_le32(val); +} + +unsigned int +readl(unsigned int address) +{ + /* Ensure I/O operations complete */ + __asm__ volatile("eieio"); + return le32_to_cpu(*(unsigned int *)address); +} + +#define PCI_CFG_ADDR(dev,off) ((0x80<<24) | (dev<<8) | (off&0xfc)) +#define PCI_CFG_DATA(off) (0x80000cfc+(off&3)) + +static void +pci_read_config_32(unsigned char devfn, + unsigned char offset, + unsigned int *val) +{ + writel(PCI_CFG_ADDR(devfn,offset), 0x80000cf8); + *val = readl(PCI_CFG_DATA(offset)); + return; +} + +void +scroll() +{ + int i; + + memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 ); + for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 ) + vidmem[i] = ' '; +} + +/* + * This routine is used to control the second processor on the + * Motorola dual processor platforms. + */ +void +park_cpus() +{ + volatile void (*go)(RESIDUAL *, int, int, char *, int); + unsigned int i; + volatile unsigned long *smp_iar = &(hold_residual->VitalProductData.SmpIar); + + /* Wait for indication to continue. If the kernel + was not compiled with SMP support then the second + processor will spin forever here makeing the kernel + multiprocessor safe. */ + while (*smp_iar == 0) { + for (i=0; i < 512; i++); + } + + (unsigned long)go = hold_residual->VitalProductData.SmpIar; + go(hold_residual, 0, 0, cmd_line, sizeof(cmd_preset)); +} + +unsigned long +decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, + RESIDUAL *residual, void *OFW_interface) +{ + int timer; + extern unsigned long start; + char *cp, ch; + unsigned long TotalMemory; + unsigned long orig_MSR; + int dev_handle; + int mem_info[2]; + int res, size; + unsigned char board_type; + unsigned char base_mod; + int start_multi = 0; + unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base; + + lines = 25; + cols = 80; + orig_x = 0; + orig_y = 24; + + /* + * IBM's have the MMU on, so we have to disable it or + * things get really unhappy in the kernel when + * trying to setup the BATs with the MMU on + * -- Cort + */ + flush_instruction_cache(); + _put_HID0(_get_HID0() & ~0x0000C000); + _put_MSR((orig_MSR = _get_MSR()) & ~0x0030); + +#if defined(CONFIG_SERIAL_CONSOLE) + com_port = serial_init(0); +#endif /* CONFIG_SERIAL_CONSOLE */ + vga_init((char)0xC0000000); + + if (residual) + { + /* Is this Motorola PPCBug? */ + if ((1 & residual->VitalProductData.FirmwareSupports) && + (1 == residual->VitalProductData.FirmwareSupplier)) { + board_type = inb(0x800) & 0xF0; + + /* + * Reset the onboard 21x4x Ethernet + * Motorola Ethernet is at IDSEL 14 (devfn 0x70) + */ + pci_read_config_32(0x70, 0x00, &pci_viddid); + pci_did = (pci_viddid & 0xffff0000) >> 16; + /* Be sure we've really found a 21x4x chip */ + if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_DEC) && + ((pci_did == PCI_DEVICE_ID_DEC_TULIP_FAST) || + (pci_did == PCI_DEVICE_ID_DEC_TULIP) || + (pci_did == PCI_DEVICE_ID_DEC_TULIP_PLUS) || + (pci_did == PCI_DEVICE_ID_DEC_21142))) + { + pci_read_config_32(0x70, + 0x10, + &tulip_pci_base); + /* Get the physical base address */ + tulip_base = + (tulip_pci_base & ~0x03UL) + 0x80000000; + /* Strobe the 21x4x reset bit in CSR0 */ + writel(0x1, tulip_base); + } + + /* If this is genesis 2 board then check for no + * keyboard controller and more than one processor. + */ + if (board_type == 0xe0) { + base_mod = inb(0x803); + /* if a MVME2300/2400 or a Sitka then no keyboard */ + if((base_mod == 0xFA) || (base_mod == 0xF9) || + (base_mod == 0xE1)) { + keyb_present = 0; /* no keyboard */ + } + } + /* If this is a multiprocessor system then + * park the other processor so that the + * kernel knows where to find them. + */ + if (residual->MaxNumCpus > 1) { + start_multi = 1; + } + } + memcpy(hold_residual,residual,sizeof(RESIDUAL)); + } else { + /* Assume 32M in the absence of more info... */ + TotalMemory = 0x02000000; + /* + * This is a 'best guess' check. We want to make sure + * we don't try this on a PReP box without OF + * -- Cort + */ + while (OFW_interface && ((unsigned long)OFW_interface < 0x10000000) ) + { + /* The MMU needs to be on when we call OFW */ + _put_MSR(orig_MSR); + of_init(OFW_interface); + + /* get handle to memory description */ + res = of_finddevice("/memory@0", + &dev_handle); + // puthex(res); puts("\n"); + if (res) break; + + /* get the info */ + // puts("get info = "); + res = of_getprop(dev_handle, + "reg", + mem_info, + sizeof(mem_info), + &size); + // puthex(res); puts(", info = "); puthex(mem_info[0]); + // puts(" "); puthex(mem_info[1]); puts("\n"); + if (res) break; + + TotalMemory = mem_info[1]; + break; + } + hold_residual->TotalMemory = TotalMemory; + residual = hold_residual; + /* Turn MMU back off */ + _put_MSR(orig_MSR & ~0x0030); + } + + if (start_multi) { + hold_residual->VitalProductData.SmpIar = 0; + hold_residual->Cpus[1].CpuState = CPU_GOOD_FW; + residual->VitalProductData.SmpIar = (unsigned long)park_cpus; + residual->Cpus[1].CpuState = CPU_GOOD; + hold_residual->VitalProductData.Reserved5 = 0xdeadbeef; + } + + /* assume the chunk below 8M is free */ + end_avail = (char *)0x00800000; + + /* tell the user where we were loaded at and where we + * were relocated to for debugging this process + */ + puts("loaded at: "); puthex(load_addr); + puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); + if ( (unsigned long)load_addr != (unsigned long)&start ) + { + puts("relocated to: "); puthex((unsigned long)&start); + puts(" "); + puthex((unsigned long)((unsigned long)&start + (4*num_words))); + puts("\n"); + } + + if ( residual ) + { + puts("board data at: "); puthex((unsigned long)residual); + puts(" "); + puthex((unsigned long)((unsigned long)residual + sizeof(RESIDUAL))); + puts("\n"); + puts("relocated to: "); + puthex((unsigned long)hold_residual); + puts(" "); + puthex((unsigned long)((unsigned long)hold_residual + sizeof(RESIDUAL))); + puts("\n"); + } + + /* we have to subtract 0x10000 here to correct for objdump including the + size of the elf header which we strip -- Cort */ + zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET); + zimage_size = ZIMAGE_SIZE; + + if ( INITRD_OFFSET ) + initrd_start = load_addr - 0x10000 + INITRD_OFFSET; + else + initrd_start = 0; + initrd_end = INITRD_SIZE + initrd_start; + + /* + * Find a place to stick the zimage and initrd and + * relocate them if we have to. -- Cort + */ + avail_ram = (char *)PAGE_ALIGN((unsigned long)_end); + puts("zimage at: "); puthex((unsigned long)zimage_start); + puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n"); + if ( (unsigned long)zimage_start <= 0x00800000 ) + { + memcpy( (void *)avail_ram, (void *)zimage_start, zimage_size ); + zimage_start = (char *)avail_ram; + puts("relocated to: "); puthex((unsigned long)zimage_start); + puts(" "); + puthex((unsigned long)zimage_size+(unsigned long)zimage_start); + puts("\n"); + + /* relocate initrd */ + if ( initrd_start ) + { + puts("initrd at: "); puthex(initrd_start); + puts(" "); puthex(initrd_end); puts("\n"); + avail_ram = (char *)PAGE_ALIGN( + (unsigned long)zimage_size+(unsigned long)zimage_start); + memcpy ((void *)avail_ram, (void *)initrd_start, INITRD_SIZE ); + initrd_start = (unsigned long)avail_ram; + initrd_end = initrd_start + INITRD_SIZE; + puts("relocated to: "); puthex(initrd_start); + puts(" "); puthex(initrd_end); puts("\n"); + } + } else 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"); + + if (keyb_present) + CRT_tstc(); /* Forces keyboard to be initialized */ + + 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"); + + /* mappings on early boot can only handle 16M */ + if ( (int)(cmd_line[0]) > (16<<20)) + puts("cmd_line located > 16M\n"); + if ( (int)hold_residual > (16<<20)) + puts("hold_residual located > 16M\n"); + if ( initrd_start > (16<<20)) + puts("initrd_start located > 16M\n"); + + puts("Uncompressing Linux..."); + + gunzip(0, 0x400000, zimage_start, &zimage_size); + puts("done.\n"); + + { + struct bi_record *rec; + + rec = (struct bi_record *)PAGE_ALIGN(zimage_size); + + rec->tag = BI_FIRST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_BOOTLOADER_ID; + memcpy( (void *)rec->data, "prepboot", 9); + rec->size = sizeof(struct bi_record) + 8 + 1; + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_MACHTYPE; + rec->data[0] = _MACH_prep; + rec->data[1] = 1; + rec->size = sizeof(struct bi_record) + sizeof(unsigned long); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + + rec->tag = BI_CMD_LINE; + memcpy( (char *)rec->data, cmd_line, strlen(cmd_line)+1); + rec->size = sizeof(struct bi_record) + strlen(cmd_line) + 1; + rec = (struct bi_record *)((ulong)rec + rec->size); + + rec->tag = BI_LAST; + rec->size = sizeof(struct bi_record); + rec = (struct bi_record *)((unsigned long)rec + rec->size); + } + puts("Now booting the kernel\n"); + return (unsigned long)hold_residual; +} + +/* + * PCI/ISA I/O support + */ + +volatile unsigned char *ISA_io = (unsigned char *)0x80000000; +volatile unsigned char *ISA_mem = (unsigned char *)0xC0000000; + +void +outb(int port, char val) +{ + /* Ensure I/O operations complete */ + __asm__ volatile("eieio"); + ISA_io[port] = val; +} + +unsigned char +inb(int port) +{ + /* Ensure I/O operations complete */ + __asm__ volatile("eieio"); + return (ISA_io[port]); +} + +unsigned long +local_to_PCI(unsigned long addr) +{ + return ((addr & 0x7FFFFFFF) | 0x80000000); +} diff -Nru a/arch/ppc/boot/prep/of1275.c b/arch/ppc/boot/prep/of1275.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/prep/of1275.c Mon May 21 17:07:04 2001 @@ -0,0 +1,430 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* Open Firmware Client Interface */ + + +#include "of1275.h" + + +static int (*of_server)(void *) = (int(*)(void*))-1; + +void +of_init(void *handler) +{ + of_server = (int(*)(void*))handler; +} + + +/* 6.3.2.1 Client interface */ + + +int +of_test(const char *name, int *missing) +{ + int result; + static of_test_service s; + s.service = "test"; + s.n_args = 1; + s.n_returns = 1; + s.name = name; + result = of_server(&s); + *missing = s.missing; + return result; +} + + +/* 6.3.2.2 Device tree */ + + +int +of_peer(int phandle, int *sibling_phandle) +{ + int result; + static of_peer_service s; + s.service = "peer"; + s.n_args = 1; + s.n_returns = 1; + s.phandle = phandle; + result = of_server(&s); + *sibling_phandle = s.sibling_phandle; + return result; +} + +int +of_child(int phandle, int *child_phandle) +{ + int result; + static of_child_service s; + s.service = "child"; + s.n_args = 1; + s.n_returns = 1; + s.phandle = phandle; + result = of_server(&s); + *child_phandle = s.child_phandle; + return result; +} + +int +of_parent(int phandle, int *parent_phandle) +{ + int result; + static of_parent_service s; + s.service = "parent"; + s.n_args = 1; + s.n_returns = 1; + s.phandle = phandle; + result = of_server(&s); + *parent_phandle = s.parent_phandle; + return result; +} + +int +of_instance_to_package(int ihandle, int *phandle) +{ + int result; + static of_instance_to_package_service s; + s.service = "instance-to-package"; + s.n_args = 1; + s.n_returns = 1; + s.ihandle = ihandle; + result = of_server(&s); + *phandle = s.phandle; + return result; +} + +int +of_getproplen(int phandle, const char *name, int *proplen) +{ + int result; + static of_getproplen_service s; + s.service = "getproplen"; + s.n_args = 2; + s.n_returns = 1; + s.phandle = phandle; + s.name = name; + result = of_server(&s); + *proplen = s.proplen; + return result; +} + +int +of_getprop(int phandle, const char *name, void *buf, int buflen, int *size) +{ + int result; + static of_getprop_service s; + s.service = "getprop"; + s.n_args = 4; + s.n_returns = 1; + s.phandle = phandle; + s.name = name; + s.buf = buf; + s.buflen = buflen; + result = of_server(&s); + *size = s.size; + return result; +} + +int +of_nextprop(int phandle, const char *previous, void *buf, int *flag) +{ + int result; + static of_nextprop_service s; + s.service = "nextprop"; + s.n_args = 3; + s.n_returns = 1; + s.phandle = phandle; + s.previous = previous; + s.buf = buf; + result = of_server(&s); + *flag = s.flag; + return result; +} + +int +of_setprop(int phandle, const char *name, void *buf, int len, int *size) +{ + int result; + static of_setprop_service s; + s.service = "setprop"; + s.n_args = 4; + s.n_returns = 1; + s.phandle = phandle; + s.name = name; + s.buf = buf; + s.len = len; + result = of_server(&s); + *size = s.size; + return result; +} + +int +of_canon(const char *device_specifier, void *buf, int buflen, int *length) +{ + int result; + static of_canon_service s; + s.service = "canon"; + s.n_args = 3; + s.n_returns = 1; + s.device_specifier = device_specifier; + s.buf = buf; + s.buflen = buflen; + result = of_server(&s); + *length = s.length; + return result; +} + +int +of_finddevice(const char *device_specifier, int *phandle) +{ + int result; + static of_finddevice_service s; + s.service = "finddevice"; + s.n_args = 1; + s.n_returns = 1; + s.device_specifier = device_specifier; + result = of_server(&s); + *phandle = s.phandle; + return result; +} + +int +of_instance_to_path(int ihandle, void *buf, int buflen, int *length) +{ + int result; + static of_instance_to_path_service s; + s.service = "instance-to-path"; + s.n_args = 3; + s.n_returns = 1; + s.ihandle = ihandle; + s.buf = buf; + s.buflen = buflen; + result = of_server(&s); + *length = s.length; + return result; +} + +int +of_package_to_path(int phandle, void *buf, int buflen, int *length) +{ + int result; + static of_package_to_path_service s; + s.service = "package-to-path"; + s.n_args = 3; + s.n_returns = 1; + s.phandle = phandle; + s.buf = buf; + s.buflen = buflen; + result = of_server(&s); + *length = s.length; + return result; +} + +/* int of_call_method(const char *method, int ihandle, ...); */ + + +/* 6.3.2.3 Device I/O */ + + +int +of_open(const char *device_specifier, int *ihandle) +{ + int result; + static of_open_service s; + s.service = "open"; + s.n_args = 1; + s.n_returns = 1; + s.device_specifier = device_specifier; + result = of_server(&s); + *ihandle = s.ihandle; + return result; +} + +int +of_close(int ihandle) +{ + int result; + static of_close_service s; + s.service = "close"; + s.n_args = 1; + s.n_returns = 0; + s.ihandle = ihandle; + result = of_server(&s); + return result; +} + +int +of_read(int ihandle, void *addr, int len, int *actual) +{ + int result; + static of_read_service s; + s.service = "read"; + s.n_args = 3; + s.n_returns = 1; + s.ihandle = ihandle; + s.addr = addr; + s.len = len; + result = of_server(&s); + *actual = s.actual; + return result; +} + +int +of_write(int ihandle, void *addr, int len, int *actual) +{ + int result; + static of_write_service s; + s.service = "write"; + s.n_args = 3; + s.n_returns = 1; + s.ihandle = ihandle; + s.addr = addr; + s.len = len; + result = of_server(&s); + *actual = s.actual; + return result; +} + +int +of_seek(int ihandle, int pos_hi, int pos_lo, int *status) +{ + int result; + static of_seek_service s; + s.service = "seek"; + s.n_args = 3; + s.n_returns = 1; + s.ihandle = ihandle; + s.pos_hi = pos_hi; + s.pos_lo = pos_lo; + result = of_server(&s); + *status = s.status; + return result; +} + + +/* 6.3.2.4 Memory */ + + +int +of_claim(void *virt, int size, int align, void **baseaddr) +{ + int result; + static of_claim_service s; + s.service = "claim"; + s.n_args = 3; + s.n_returns = 1; + s.virt = virt; + s.size = size; + s.align = align; + result = of_server(&s); + *baseaddr = s.baseaddr; + return result; +} + +int +of_release(void *virt, int size) +{ + int result; + static of_release_service s; + s.service = "release"; + s.n_args = 2; + s.n_returns = 0; + s.virt = virt; + s.size = size; + result = of_server(&s); + return result; +} + + +/* 6.3.2.5 Control transfer */ + + +int +of_boot(const char *bootspec) +{ + int result; + static of_boot_service s; + s.service = "boot"; + s.n_args = 1; + s.n_returns = 0; + s.bootspec = bootspec; + result = of_server(&s); + return result; +} + +int +of_enter(void) +{ + int result; + static of_enter_service s; + s.service = "enter"; + s.n_args = 0; + s.n_returns = 0; + result = of_server(&s); + return result; +} + +int +of_exit(void) +{ + int result; + static of_exit_service s; + s.service = "exit"; + s.n_args = 0; + s.n_returns = 0; + result = of_server(&s); + return result; +} + +/* int of_chain(void *virt, int size, void *entry, void *args, int len); */ + + +/* 6.3.2.6 User interface */ + + +/* int of_interpret(const char *arg, ...); */ + +int +of_set_callback(void *newfunc, void **oldfunc) +{ + int result; + static of_set_callback_service s; + s.service = "set-callback"; + s.n_args = 1; + s.n_returns = 1; + s.newfunc = newfunc; + result = of_server(&s); + *oldfunc = s.oldfunc; + return result; +} + +int +of_set_symbol_lookup(void *sym_to_value, void *value_to_sym) +{ + int result; + static of_set_symbol_lookup_service s; + s.service = "set-symbol-lookup"; + s.n_args = 2; + s.n_returns = 0; + s.sym_to_value = sym_to_value; + s.value_to_sym = s.value_to_sym; + result = of_server(&s); + return result; +} + + +/* 6.3.2.7 Time */ + + +int +of_milliseconds(int *ms) +{ + int result; + static of_milliseconds_service s; + s.service = "milliseconds"; + s.n_args = 0; + s.n_returns = 1; + result = of_server(&s); + *ms = s.ms; + return result; +} diff -Nru a/arch/ppc/boot/prep/of1275.h b/arch/ppc/boot/prep/of1275.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/prep/of1275.h Mon May 21 17:07:04 2001 @@ -0,0 +1,424 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* 6.3.2.1 Client interface */ + + +typedef struct _of_test_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *name; + /*out*/ + int missing; +} of_test_service; + +int of_test(const char *name, int *missing); + + +/* 6.3.2.2 Device tree */ + + +typedef struct _of_peer_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + /*out*/ + int sibling_phandle; +} of_peer_service; + +int of_peer(int phandle, int *sibling_phandle); + + +typedef struct _of_child_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + /*out*/ + int child_phandle; +} of_child_service; + +int of_child(int phandle, int *child_phandle); + + +typedef struct _of_parent_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + /*out*/ + int parent_phandle; +} of_parent_service; + +int of_child(int phandle, int *parent_phandle); + + +typedef struct _of_instance_to_package_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int ihandle; + /*out*/ + int phandle; +} of_instance_to_package_service; + +int of_instance_to_package(int ihandle, int *phandle); + + +typedef struct _of_getproplen_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + const char *name; + /*out*/ + int proplen; +} of_getproplen_service; + +int of_getproplen(int phandle, const char *name, int *proplen); + + +typedef struct _of_getprop_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + const char *name; + void *buf; + int buflen; + /*out*/ + int size; +} of_getprop_service; + +int of_getprop(int phandle, const char *name, void *buf, int buflen, + int *size); + + +typedef struct _of_nextprop_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + const char *previous; + void *buf; + /*out*/ + int flag; +} of_nextprop_service; + +int of_nextprop(int phandle, const char *previous, void *buf, int *flag); + + +typedef struct _of_setprop_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + const char *name; + void *buf; + int len; + /*out*/ + int size; +} of_setprop_service; + +int of_setprop(int phandle, const char *name, void *buf, int len, int *size); + + +typedef struct _of_canon_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *device_specifier; + void *buf; + int buflen; + /*out*/ + int length; +} of_canon_service; + +int of_canon(const char *device_specifier, void *buf, int buflen, int *length); + + +typedef struct _of_finddevice_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *device_specifier; + /*out*/ + int phandle; +} of_finddevice_service; + +int of_finddevice(const char *device_specifier, int *phandle); + + +typedef struct _of_instance_to_path_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int ihandle; + void *buf; + int buflen; + /*out*/ + int length; +} of_instance_to_path_service; + +int of_instance_to_path(int ihandle, void *buf, int buflen, int *length); + + +typedef struct _of_package_to_path_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int phandle; + void *buf; + int buflen; + /*out*/ + int length; +} of_package_to_path_service; + +int of_package_to_path(int phandle, void *buf, int buflen, int *length); + + +typedef struct _of_call_method_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *method; + int ihandle; + /*...*/ + int args[0]; +} of_call_method_service; + +int of_call_method(const char *method, int ihandle, ...); + + +/* 6.3.2.3 Device I/O */ + + +typedef struct _of_open_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *device_specifier; + /*out*/ + int ihandle; +} of_open_service; + +int of_open(const char *device_specifier, + int *ihandle); + + +typedef struct _of_close_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int ihandle; + /*out*/ +} of_close_service; + +int of_close(int ihandle); + + +typedef struct _of_read_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int ihandle; + void *addr; + int len; + /*out*/ + int actual; +} of_read_service; + +int of_read(int ihandle, void *addr, int len, int *actual); + + +typedef struct _of_write_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int ihandle; + void *addr; + int len; + /*out*/ + int actual; +} of_write_service; + +int of_write(int ihandle, void *addr, int len, int *actual); + + +typedef struct _of_seek_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + int ihandle; + int pos_hi; + int pos_lo; + /*out*/ + int status; +} of_seek_service; + +int of_seek(int ihandle, int pos_hi, int pos_lo, int *status); + + +/* 6.3.2.4 Memory */ + + +typedef struct _of_claim_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + void *virt; + int size; + int align; + /*out*/ + void *baseaddr; +} of_claim_service; + +int of_claim(void *virt, int size, int align, void **baseaddr); + + +typedef struct _of_release_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + void *virt; + int size; + int align; + /*out*/ +} of_release_service; + +int of_release(void *virt, int size); + + +/* 6.3.2.5 Control transfer */ + + +typedef struct _of_boot_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *bootspec; + /*out*/ +} of_boot_service; + +int of_boot(const char *bootspec); + + +typedef struct _of_enter_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + /*out*/ +} of_enter_service; + +int of_enter(void); + + +typedef struct _of_exit_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + /*out*/ +} of_exit_service; + +int of_exit(void); + + +typedef struct _of_chain_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + void *virt; + int size; + void *entry; + void *args; + int len; + /*out*/ +} of_chain_service; + +int of_chain(void *virt, int size, void *entry, void *args, int len); + + +/* 6.3.2.6 User interface */ + + +typedef struct _of_interpret_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + const char *cmd; + int args[0]; + /*...*/ + /*out*/ + /*...*/ +} of_interpret_service; + +int of_interpret(const char *arg, ...); + + +typedef struct _of_set_callback_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + void *newfunc; + /*out*/ + void *oldfunc; +} of_set_callback_service; + +int of_set_callback(void *newfunc, void **oldfunc); + + +typedef struct _of_set_symbol_lookup_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + void *sym_to_value; + void *value_to_sym; + /*out*/ +} of_set_symbol_lookup_service; + +int of_set_symbol_lookup(void *sym_to_value, void *value_to_sym); + + +/* 6.3.2.7 Time */ + + +typedef struct _of_milliseconds_service { + const char *service; + int n_args; + int n_returns; + /*in*/ + /*out*/ + int ms; +} of_milliseconds_service; + +int of_milliseconds(int *ms); diff -Nru a/arch/ppc/boot/prep/vreset.c b/arch/ppc/boot/prep/vreset.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/prep/vreset.c Mon May 21 17:07:04 2001 @@ -0,0 +1,863 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * vreset.c + * + * Initialize the VGA control registers to 80x25 text mode. + * + * Adapted from a program by: + * Steve Sellgren + * San Francisco Indigo Company + * sfindigo!sellgren@uunet.uu.net + * + * Original concept by: + * Gary Thomas + * Adapted for Moto boxes by: + * Pat Kane & Mark Scott, 1996 + * Adapted for IBM portables by: + * Takeshi Ishimoto + * Multi-console support: + * Terje Malmedal + */ + +#include "iso_font.h" + +extern char *vidmem; +extern int lines, cols; +extern void udelay(long x); +extern void outb(int port, char val); +extern unsigned char inb(int port); +struct VaRegs; + +/* + * VGA Register + */ +struct VgaRegs +{ + unsigned short io_port; + unsigned char io_index; + unsigned char io_value; +}; + +void unlockVideo(int slot); +void setTextRegs(struct VgaRegs *svp); +void setTextCLUT(int shift); +void clearVideoMemory(); +void loadFont(unsigned char *ISA_mem); + +static void mdelay(int ms) +{ + for (; ms > 0; --ms) + udelay(1000); +} + +/* + * Default console text mode registers used to reset + * graphics adapter. + */ +#define NREGS 54 +#define ENDMK 0xFFFF /* End marker */ + +#define S3Vendor 0x5333 +#define CirrusVendor 0x1013 +#define DiamondVendor 0x100E +#define MatroxVendor 0x102B +#define ParadiseVendor 0x101C + +struct VgaRegs GenVgaTextRegs[NREGS+1] = { +/* port index value */ + /* SR Regs */ + 0x3c4, 0x1, 0x0, + 0x3c4, 0x2, 0x3, + 0x3c4, 0x3, 0x0, + 0x3c4, 0x4, 0x2, + /* CR Regs */ + 0x3d4, 0x0, 0x5f, + 0x3d4, 0x1, 0x4f, + 0x3d4, 0x2, 0x50, + 0x3d4, 0x3, 0x82, + 0x3d4, 0x4, 0x55, + 0x3d4, 0x5, 0x81, + 0x3d4, 0x6, 0xbf, + 0x3d4, 0x7, 0x1f, + 0x3d4, 0x8, 0x00, + 0x3d4, 0x9, 0x4f, + 0x3d4, 0xa, 0x0d, + 0x3d4, 0xb, 0x0e, + 0x3d4, 0xc, 0x00, + 0x3d4, 0xd, 0x00, + 0x3d4, 0xe, 0x00, + 0x3d4, 0xf, 0x00, + 0x3d4, 0x10, 0x9c, + 0x3d4, 0x11, 0x8e, + 0x3d4, 0x12, 0x8f, + 0x3d4, 0x13, 0x28, + 0x3d4, 0x14, 0x1f, + 0x3d4, 0x15, 0x96, + 0x3d4, 0x16, 0xb9, + 0x3d4, 0x17, 0xa3, + /* GR Regs */ + 0x3ce, 0x0, 0x0, + 0x3ce, 0x1, 0x0, + 0x3ce, 0x2, 0x0, + 0x3ce, 0x3, 0x0, + 0x3ce, 0x4, 0x0, + 0x3ce, 0x5, 0x10, + 0x3ce, 0x6, 0xe, + 0x3ce, 0x7, 0x0, + 0x3ce, 0x8, 0xff, + ENDMK +}; + +struct VgaRegs S3TextRegs[NREGS+1] = { +/* port index value */ + /* SR Regs */ + 0x3c4, 0x1, 0x0, + 0x3c4, 0x2, 0x3, + 0x3c4, 0x3, 0x0, + 0x3c4, 0x4, 0x2, + /* CR Regs */ + 0x3d4, 0x0, 0x5f, + 0x3d4, 0x1, 0x4f, + 0x3d4, 0x2, 0x50, + 0x3d4, 0x3, 0x82, + 0x3d4, 0x4, 0x55, + 0x3d4, 0x5, 0x81, + 0x3d4, 0x6, 0xbf, + 0x3d4, 0x7, 0x1f, + 0x3d4, 0x8, 0x00, + 0x3d4, 0x9, 0x4f, + 0x3d4, 0xa, 0x0d, + 0x3d4, 0xb, 0x0e, + 0x3d4, 0xc, 0x00, + 0x3d4, 0xd, 0x00, + 0x3d4, 0xe, 0x00, + 0x3d4, 0xf, 0x00, + 0x3d4, 0x10, 0x9c, + 0x3d4, 0x11, 0x8e, + 0x3d4, 0x12, 0x8f, + 0x3d4, 0x13, 0x28, + 0x3d4, 0x14, 0x1f, + 0x3d4, 0x15, 0x96, + 0x3d4, 0x16, 0xb9, + 0x3d4, 0x17, 0xa3, + /* GR Regs */ + 0x3ce, 0x0, 0x0, + 0x3ce, 0x1, 0x0, + 0x3ce, 0x2, 0x0, + 0x3ce, 0x3, 0x0, + 0x3ce, 0x4, 0x0, + 0x3ce, 0x5, 0x10, + 0x3ce, 0x6, 0xe, + 0x3ce, 0x7, 0x0, + 0x3ce, 0x8, 0xff, + ENDMK +}; + +struct RGBColors +{ + unsigned char r, g, b; +}; + +/* + * Default console text mode color table. + * These values were obtained by booting Linux with + * text mode firmware & then dumping the registers. + */ +struct RGBColors TextCLUT[256] = +{ + /* red green blue */ + 0x0, 0x0, 0x0, + 0x0, 0x0, 0x2a, + 0x0, 0x2a, 0x0, + 0x0, 0x2a, 0x2a, + 0x2a, 0x0, 0x0, + 0x2a, 0x0, 0x2a, + 0x2a, 0x2a, 0x0, + 0x2a, 0x2a, 0x2a, + 0x0, 0x0, 0x15, + 0x0, 0x0, 0x3f, + 0x0, 0x2a, 0x15, + 0x0, 0x2a, 0x3f, + 0x2a, 0x0, 0x15, + 0x2a, 0x0, 0x3f, + 0x2a, 0x2a, 0x15, + 0x2a, 0x2a, 0x3f, + 0x0, 0x15, 0x0, + 0x0, 0x15, 0x2a, + 0x0, 0x3f, 0x0, + 0x0, 0x3f, 0x2a, + 0x2a, 0x15, 0x0, + 0x2a, 0x15, 0x2a, + 0x2a, 0x3f, 0x0, + 0x2a, 0x3f, 0x2a, + 0x0, 0x15, 0x15, + 0x0, 0x15, 0x3f, + 0x0, 0x3f, 0x15, + 0x0, 0x3f, 0x3f, + 0x2a, 0x15, 0x15, + 0x2a, 0x15, 0x3f, + 0x2a, 0x3f, 0x15, + 0x2a, 0x3f, 0x3f, + 0x15, 0x0, 0x0, + 0x15, 0x0, 0x2a, + 0x15, 0x2a, 0x0, + 0x15, 0x2a, 0x2a, + 0x3f, 0x0, 0x0, + 0x3f, 0x0, 0x2a, + 0x3f, 0x2a, 0x0, + 0x3f, 0x2a, 0x2a, + 0x15, 0x0, 0x15, + 0x15, 0x0, 0x3f, + 0x15, 0x2a, 0x15, + 0x15, 0x2a, 0x3f, + 0x3f, 0x0, 0x15, + 0x3f, 0x0, 0x3f, + 0x3f, 0x2a, 0x15, + 0x3f, 0x2a, 0x3f, + 0x15, 0x15, 0x0, + 0x15, 0x15, 0x2a, + 0x15, 0x3f, 0x0, + 0x15, 0x3f, 0x2a, + 0x3f, 0x15, 0x0, + 0x3f, 0x15, 0x2a, + 0x3f, 0x3f, 0x0, + 0x3f, 0x3f, 0x2a, + 0x15, 0x15, 0x15, + 0x15, 0x15, 0x3f, + 0x15, 0x3f, 0x15, + 0x15, 0x3f, 0x3f, + 0x3f, 0x15, 0x15, + 0x3f, 0x15, 0x3f, + 0x3f, 0x3f, 0x15, + 0x3f, 0x3f, 0x3f, + 0x39, 0xc, 0x5, + 0x15, 0x2c, 0xf, + 0x26, 0x10, 0x3d, + 0x29, 0x29, 0x38, + 0x4, 0x1a, 0xe, + 0x2, 0x1e, 0x3a, + 0x3c, 0x25, 0x33, + 0x3c, 0xc, 0x2c, + 0x3f, 0x3, 0x2b, + 0x1c, 0x9, 0x13, + 0x25, 0x2a, 0x35, + 0x1e, 0xa, 0x38, + 0x24, 0x8, 0x3, + 0x3, 0xe, 0x36, + 0xc, 0x6, 0x2a, + 0x26, 0x3, 0x32, + 0x5, 0x2f, 0x33, + 0x3c, 0x35, 0x2f, + 0x2d, 0x26, 0x3e, + 0xd, 0xa, 0x10, + 0x25, 0x3c, 0x11, + 0xd, 0x4, 0x2e, + 0x5, 0x19, 0x3e, + 0xc, 0x13, 0x34, + 0x2b, 0x6, 0x24, + 0x4, 0x3, 0xd, + 0x2f, 0x3c, 0xc, + 0x2a, 0x37, 0x1f, + 0xf, 0x12, 0x38, + 0x38, 0xe, 0x2a, + 0x12, 0x2f, 0x19, + 0x29, 0x2e, 0x31, + 0x25, 0x13, 0x3e, + 0x33, 0x3e, 0x33, + 0x1d, 0x2c, 0x25, + 0x15, 0x15, 0x5, + 0x32, 0x25, 0x39, + 0x1a, 0x7, 0x1f, + 0x13, 0xe, 0x1d, + 0x36, 0x17, 0x34, + 0xf, 0x15, 0x23, + 0x2, 0x35, 0xd, + 0x15, 0x3f, 0xc, + 0x14, 0x2f, 0xf, + 0x19, 0x21, 0x3e, + 0x27, 0x11, 0x2f, + 0x38, 0x3f, 0x3c, + 0x36, 0x2d, 0x15, + 0x16, 0x17, 0x2, + 0x1, 0xa, 0x3d, + 0x1b, 0x11, 0x3f, + 0x21, 0x3c, 0xd, + 0x1a, 0x39, 0x3d, + 0x8, 0xe, 0xe, + 0x22, 0x21, 0x23, + 0x1e, 0x30, 0x5, + 0x1f, 0x22, 0x3d, + 0x1e, 0x2f, 0xa, + 0x0, 0x1c, 0xe, + 0x0, 0x1c, 0x15, + 0x0, 0x1c, 0x1c, + 0x0, 0x15, 0x1c, + 0x0, 0xe, 0x1c, + 0x0, 0x7, 0x1c, + 0xe, 0xe, 0x1c, + 0x11, 0xe, 0x1c, + 0x15, 0xe, 0x1c, + 0x18, 0xe, 0x1c, + 0x1c, 0xe, 0x1c, + 0x1c, 0xe, 0x18, + 0x1c, 0xe, 0x15, + 0x1c, 0xe, 0x11, + 0x1c, 0xe, 0xe, + 0x1c, 0x11, 0xe, + 0x1c, 0x15, 0xe, + 0x1c, 0x18, 0xe, + 0x1c, 0x1c, 0xe, + 0x18, 0x1c, 0xe, + 0x15, 0x1c, 0xe, + 0x11, 0x1c, 0xe, + 0xe, 0x1c, 0xe, + 0xe, 0x1c, 0x11, + 0xe, 0x1c, 0x15, + 0xe, 0x1c, 0x18, + 0xe, 0x1c, 0x1c, + 0xe, 0x18, 0x1c, + 0xe, 0x15, 0x1c, + 0xe, 0x11, 0x1c, + 0x14, 0x14, 0x1c, + 0x16, 0x14, 0x1c, + 0x18, 0x14, 0x1c, + 0x1a, 0x14, 0x1c, + 0x1c, 0x14, 0x1c, + 0x1c, 0x14, 0x1a, + 0x1c, 0x14, 0x18, + 0x1c, 0x14, 0x16, + 0x1c, 0x14, 0x14, + 0x1c, 0x16, 0x14, + 0x1c, 0x18, 0x14, + 0x1c, 0x1a, 0x14, + 0x1c, 0x1c, 0x14, + 0x1a, 0x1c, 0x14, + 0x18, 0x1c, 0x14, + 0x16, 0x1c, 0x14, + 0x14, 0x1c, 0x14, + 0x14, 0x1c, 0x16, + 0x14, 0x1c, 0x18, + 0x14, 0x1c, 0x1a, + 0x14, 0x1c, 0x1c, + 0x14, 0x1a, 0x1c, + 0x14, 0x18, 0x1c, + 0x14, 0x16, 0x1c, + 0x0, 0x0, 0x10, + 0x4, 0x0, 0x10, + 0x8, 0x0, 0x10, + 0xc, 0x0, 0x10, + 0x10, 0x0, 0x10, + 0x10, 0x0, 0xc, + 0x10, 0x0, 0x8, + 0x10, 0x0, 0x4, + 0x10, 0x0, 0x0, + 0x10, 0x4, 0x0, + 0x10, 0x8, 0x0, + 0x10, 0xc, 0x0, + 0x10, 0x10, 0x0, + 0xc, 0x10, 0x0, + 0x8, 0x10, 0x0, + 0x4, 0x10, 0x0, + 0x0, 0x10, 0x0, + 0x0, 0x10, 0x4, + 0x0, 0x10, 0x8, + 0x0, 0x10, 0xc, + 0x0, 0x10, 0x10, + 0x0, 0xc, 0x10, + 0x0, 0x8, 0x10, + 0x0, 0x4, 0x10, + 0x8, 0x8, 0x10, + 0xa, 0x8, 0x10, + 0xc, 0x8, 0x10, + 0xe, 0x8, 0x10, + 0x10, 0x8, 0x10, + 0x10, 0x8, 0xe, + 0x10, 0x8, 0xc, + 0x10, 0x8, 0xa, + 0x10, 0x8, 0x8, + 0x10, 0xa, 0x8, + 0x10, 0xc, 0x8, + 0x10, 0xe, 0x8, + 0x10, 0x10, 0x8, + 0xe, 0x10, 0x8, + 0xc, 0x10, 0x8, + 0xa, 0x10, 0x8, + 0x8, 0x10, 0x8, + 0x8, 0x10, 0xa, + 0x8, 0x10, 0xc, + 0x8, 0x10, 0xe, + 0x8, 0x10, 0x10, + 0x8, 0xe, 0x10, + 0x8, 0xc, 0x10, + 0x8, 0xa, 0x10, + 0xb, 0xb, 0x10, + 0xc, 0xb, 0x10, + 0xd, 0xb, 0x10, + 0xf, 0xb, 0x10, + 0x10, 0xb, 0x10, + 0x10, 0xb, 0xf, + 0x10, 0xb, 0xd, + 0x10, 0xb, 0xc, + 0x10, 0xb, 0xb, + 0x10, 0xc, 0xb, + 0x10, 0xd, 0xb, + 0x10, 0xf, 0xb, + 0x10, 0x10, 0xb, + 0xf, 0x10, 0xb, + 0xd, 0x10, 0xb, + 0xc, 0x10, 0xb, + 0xb, 0x10, 0xb, + 0xb, 0x10, 0xc, + 0xb, 0x10, 0xd, + 0xb, 0x10, 0xf, + 0xb, 0x10, 0x10, + 0xb, 0xf, 0x10, + 0xb, 0xd, 0x10, + 0xb, 0xc, 0x10, + 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0 +}; + +unsigned char AC[21] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, + 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, + 0x0C, 0x00, 0x0F, 0x08, 0x00}; + +static int scanPCI(int start_slt); +static int PCIVendor(int); +#ifdef DEBUG +static void printslots(void); +#endif +extern void puthex(unsigned long); +extern void puts(const char *); +static void unlockS3(void); + +static void inline +outw(int port, unsigned short val) +{ + outb(port, val >> 8); + outb(port+1, val); +} + +#define PPC_601 1 + +int +vga_init(unsigned char *ISA_mem) +{ + int slot; + struct VgaRegs *VgaTextRegs; +#if 0 + if ((_get_PVR()>>16) == PPC_601) { + return(old_vga_init(ISA_mem)); + } +#endif + + /* See if VGA already in TEXT mode - exit if so! */ + outb(0x3CE, 0x06); + if ((inb(0x3CF) & 0x01) == 0){ + puts("VGA already in text mode\n"); + return 0; + } + + /* If no VGA responding in text mode, then we have some work to do... + */ + slot = -1; + while((slot = scanPCI(slot)) > -1) { /* find video card in use */ + unlockVideo(slot); /* enable I/O to card */ + VgaTextRegs = GenVgaTextRegs; + + switch (PCIVendor(slot)) { + default: + break; + case(S3Vendor): + unlockS3(); + VgaTextRegs = S3TextRegs; + break; + + case(CirrusVendor): + outw(0x3C4, 0x0612); /* unlock ext regs */ + outw(0x3C4, 0x0700); /* reset ext sequence mode */ + break; + + case(ParadiseVendor): /* IBM Portable 850 */ + outw(0x3ce, 0x0f05); /* unlock pardise registers */ + outw(0x3c4, 0x0648); + outw(0x3d4, 0x2985); + outw(0x3d4, 0x34a6); + outb(0x3ce, 0x0b); /* disable linear addressing */ + outb(0x3cf, inb(0x3cf) & ~0x30); + outw(0x3c4, 0x1400); + outb(0x3ce, 0x0e); /* disable 256 color mode */ + outb(0x3cf, inb(0x3cf) & ~0x01); + outb(0xd00, 0xff); /* enable auto-centering */ + if (!(inb(0xd01) & 0x03)) { + outb(0x3d4, 0x33); + outb(0x3d5, inb(0x3d5) & ~0x90); + outb(0x3d4, 0x32); + outb(0x3d5, inb(0x3d5) | 0x04); + outw(0x3d4, 0x0250); + outw(0x3d4, 0x07ba); + outw(0x3d4, 0x0900); + outw(0x3d4, 0x15e7); + outw(0x3d4, 0x2a95); + } + outw(0x3d4, 0x34a0); + break; + + #if 0 /* Untested - probably doesn't work */ + case(MatroxVendor): + case(DiamondVendor): + puts("VGA Chip Vendor ID: "); + puthex(PCIVendor(slot)); + puts("\n"); + mdelay(1000); + #endif + }; + + outw(0x3C4, 0x0120); /* disable video */ + setTextRegs(VgaTextRegs); /* initial register setup */ + setTextCLUT(0); /* load color lookup table */ + loadFont(ISA_mem); /* load font */ + setTextRegs(VgaTextRegs); /* reload registers */ + outw(0x3C4, 0x0100); /* re-enable video */ + clearVideoMemory(); + + if (PCIVendor(slot) == S3Vendor) { + outb(0x3c2, 0x63); /* MISC */ + } /* endif */ + + #ifdef DEBUG + printslots(); + mdelay(5000); + #endif + + mdelay(1000); /* give time for the video monitor to come up */ + } + return (1); /* 'CRT' I/O supported */ +} + +/* + * Write to VGA Attribute registers. + */ +void +writeAttr(unsigned char index, unsigned char data, unsigned char videoOn) +{ + unsigned char v; + v = inb(0x3da); /* reset attr. address toggle */ + if (videoOn) + outb(0x3c0, (index & 0x1F) | 0x20); + else + outb(0x3c0, (index & 0x1F)); + outb(0x3c0, data); +} + +void +setTextRegs(struct VgaRegs *svp) +{ + int i; + + /* + * saved settings + */ + while( svp->io_port != ENDMK ) { + outb(svp->io_port, svp->io_index); + outb(svp->io_port+1, svp->io_value); + svp++; + } + + outb(0x3c2, 0x67); /* MISC */ + outb(0x3c6, 0xff); /* MASK */ + + for ( i = 0; i < 0x10; i++) + writeAttr(i, AC[i], 0); /* pallete */ + writeAttr(0x10, 0x0c, 0); /* text mode */ + writeAttr(0x11, 0x00, 0); /* overscan color (border) */ + writeAttr(0x12, 0x0f, 0); /* plane enable */ + writeAttr(0x13, 0x08, 0); /* pixel panning */ + writeAttr(0x14, 0x00, 1); /* color select; video on */ +} + +void +setTextCLUT(int shift) +{ + int i; + + outb(0x3C6, 0xFF); + i = inb(0x3C7); + outb(0x3C8, 0); + i = inb(0x3C7); + + for ( i = 0; i < 256; i++) { + outb(0x3C9, TextCLUT[i].r << shift); + outb(0x3C9, TextCLUT[i].g << shift); + outb(0x3C9, TextCLUT[i].b << shift); + } +} + +void +loadFont(unsigned char *ISA_mem) +{ + int i, j; + unsigned char *font_page = (unsigned char *) &ISA_mem[0xA0000]; + + outb(0x3C2, 0x67); + /* + * Load font + */ + i = inb(0x3DA); /* Reset Attr toggle */ + + outb(0x3C0,0x30); + outb(0x3C0, 0x01); /* graphics mode */ + + outw(0x3C4, 0x0001); /* reset sequencer */ + outw(0x3C4, 0x0204); /* write to plane 2 */ + outw(0x3C4, 0x0406); /* enable plane graphics */ + outw(0x3C4, 0x0003); /* reset sequencer */ + outw(0x3CE, 0x0402); /* read plane 2 */ + outw(0x3CE, 0x0500); /* write mode 0, read mode 0 */ + outw(0x3CE, 0x0605); /* set graphics mode */ + + for (i = 0; i < sizeof(font); i += 16) { + for (j = 0; j < 16; j++) { + __asm__ volatile("eieio"); + font_page[(2*i)+j] = font[i+j]; + } + } +} + +static void +unlockS3(void) +{ + int s3_device_id; + outw(0x3d4, 0x3848); + outw(0x3d4, 0x39a5); + outb(0x3d4, 0x2d); + s3_device_id = inb(0x3d5) << 8; + outb(0x3d4, 0x2e); + s3_device_id |= inb(0x3d5); + + if (s3_device_id != 0x8812) { + /* From the S3 manual */ + outb(0x46E8, 0x10); /* Put into setup mode */ + outb(0x3C3, 0x10); + outb(0x102, 0x01); /* Enable registers */ + outb(0x46E8, 0x08); /* Enable video */ + outb(0x3C3, 0x08); + outb(0x4AE8, 0x00); + +#if 0 + outb(0x42E8, 0x80); /* Reset graphics engine? */ +#endif + + outb(0x3D4, 0x38); /* Unlock all registers */ + outb(0x3D5, 0x48); + outb(0x3D4, 0x39); + outb(0x3D5, 0xA5); + outb(0x3D4, 0x40); + outb(0x3D5, inb(0x3D5)|0x01); + outb(0x3D4, 0x33); + outb(0x3D5, inb(0x3D5)&~0x52); + outb(0x3D4, 0x35); + outb(0x3D5, inb(0x3D5)&~0x30); + outb(0x3D4, 0x3A); + outb(0x3D5, 0x00); + outb(0x3D4, 0x53); + outb(0x3D5, 0x00); + outb(0x3D4, 0x31); + outb(0x3D5, inb(0x3D5)&~0x4B); + outb(0x3D4, 0x58); + + outb(0x3D5, 0); + + outb(0x3D4, 0x54); + outb(0x3D5, 0x38); + outb(0x3D4, 0x60); + outb(0x3D5, 0x07); + outb(0x3D4, 0x61); + outb(0x3D5, 0x80); + outb(0x3D4, 0x62); + outb(0x3D5, 0xA1); + outb(0x3D4, 0x69); /* High order bits for cursor address */ + outb(0x3D5, 0); + + outb(0x3D4, 0x32); + outb(0x3D5, inb(0x3D5)&~0x10); + } else { + outw(0x3c4, 0x0806); /* IBM Portable 860 */ + outw(0x3c4, 0x1041); + outw(0x3c4, 0x1128); + outw(0x3d4, 0x4000); + outw(0x3d4, 0x3100); + outw(0x3d4, 0x3a05); + outw(0x3d4, 0x6688); + outw(0x3d4, 0x5800); /* disable linear addressing */ + outw(0x3d4, 0x4500); /* disable H/W cursor */ + outw(0x3c4, 0x5410); /* enable auto-centering */ + outw(0x3c4, 0x561f); + outw(0x3c4, 0x1b80); /* lock DCLK selection */ + outw(0x3d4, 0x3900); /* lock S3 registers */ + outw(0x3d4, 0x3800); + } /* endif */ +} + +/* + * cursor() sets an offset (0-1999) into the 80x25 text area + */ +void +cursor(int x, int y) +{ + int pos = (y*cols)+x; + outb(0x3D4, 14); + outb(0x3D5, pos >> 8); + outb(0x3D4, 15); + outb(0x3D5, pos); +} + +void +clearVideoMemory() +{ + int i, j; + for (i = 0; i < lines; i++) { + for (j = 0; j < cols; j++) { + vidmem[((i*cols)+j)*2] = 0x20; /* fill with space character */ + vidmem[((i*cols)+j)*2+1] = 0x07; /* set bg & fg attributes */ + } + } +} + +/* ============ */ + + +#define NSLOTS 8 +#define NPCIREGS 5 + + +/* + should use devfunc number/indirect method to be totally safe on + all machines, this works for now on 3 slot Moto boxes +*/ + +struct PCI_ConfigInfo { + unsigned long * config_addr; + unsigned long regs[NPCIREGS]; +} PCI_slots [NSLOTS] = { + + { (unsigned long *)0x80808000, 0xDEADBEEF }, /* onboard */ + { (unsigned long *)0x80800800, 0xDEADBEEF }, /* onboard */ + { (unsigned long *)0x80801000, 0xDEADBEEF }, /* onboard */ + { (unsigned long *)0x80802000, 0xDEADBEEF }, /* onboard */ + { (unsigned long *)0x80804000, 0xDEADBEEF }, /* onboard */ + { (unsigned long *)0x80810000, 0xDEADBEEF }, /* slot A/1 */ + { (unsigned long *)0x80820000, 0xDEADBEEF }, /* slot B/2 */ + { (unsigned long *)0x80840000, 0xDEADBEEF } /* slot C/3 */ +}; + + + +/* + * The following code modifies the PCI Command register + * to enable memory and I/O accesses. + */ +void +unlockVideo(int slot) +{ + volatile unsigned char * ppci; + + ppci = (unsigned char * )PCI_slots[slot].config_addr; + ppci[4] = 0x0003; /* enable memory and I/O accesses */ + ppci[0x10] = 0x00000; /* turn off memory mapping */ + ppci[0x11] = 0x00000; /* mem_base = 0 */ + ppci[0x12] = 0x00000; + ppci[0x13] = 0x00000; + __asm__ volatile("eieio"); + + outb(0x3d4, 0x11); + outb(0x3d5, 0x0e); /* unlock CR0-CR7 */ +} + +long +SwapBytes(long lv) /* turn little endian into big indian long */ +{ + long t; + t = (lv&0x000000FF) << 24; + t |= (lv&0x0000FF00) << 8; + t |= (lv&0x00FF0000) >> 8; + t |= (lv&0xFF000000) >> 24; + return(t); +} + + +#define DEVID 0 +#define CMD 1 +#define CLASS 2 +#define MEMBASE 4 + +int +scanPCI(int start_slt) +{ + int slt, r; + struct PCI_ConfigInfo *pslot; + int theSlot = -1; + int highVgaSlot = 0; + + for ( slt = start_slt + 1; slt < NSLOTS; slt++) { + pslot = &PCI_slots[slt]; + for ( r = 0; r < NPCIREGS; r++) { + pslot->regs[r] = SwapBytes ( pslot->config_addr[r] ); + } + /* card in slot ? */ + if ( pslot->regs[DEVID] != 0xFFFFFFFF ) { + /* VGA ? */ + if ( ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) || + ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x00010000)) { + highVgaSlot = slt; + /* did firmware enable it ? */ + if ( (pslot->regs[CMD] & 0x03) ) { + theSlot = slt; + break; + } + } + } + } + + return ( theSlot ); +} + +/* return Vendor ID of card in the slot */ +static +int PCIVendor(int slotnum) { + struct PCI_ConfigInfo *pslot; + + pslot = &PCI_slots[slotnum]; + +return (pslot->regs[DEVID] & 0xFFFF); +} + +#ifdef DEBUG +static +void printslots(void) +{ + int i; +#if 0 + struct PCI_ConfigInfo *pslot; +#endif + for(i=0; i < NSLOTS; i++) { +#if 0 + pslot = &PCI_slots[i]; + printf("Slot: %d, Addr: %x, Vendor: %08x, Class: %08x\n", + i, pslot->config_addr, pslot->regs[0], pslot->regs[2]); +#else + puts("PCI Slot number: "); puthex(i); + puts(" Vendor ID: "); + puthex(PCIVendor(i)); puts("\n"); +#endif + } +} +#endif /* DEBUG */ 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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/sioffset b/arch/ppc/boot/sioffset --- a/arch/ppc/boot/sioffset Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,4 +0,0 @@ -#!/bin/bash - -OFFSET=`grep $1 sImage.map | awk '{print $2}'` -echo "0x"$OFFSET diff -Nru a/arch/ppc/boot/sisize b/arch/ppc/boot/sisize --- a/arch/ppc/boot/sisize Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,4 +0,0 @@ -#!/bin/bash - -OFFSET=`grep $1 sImage.map | awk '{print $3}'` -echo "0x"$OFFSET diff -Nru a/arch/ppc/boot/size b/arch/ppc/boot/size --- a/arch/ppc/boot/size Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,4 +0,0 @@ -#!/bin/bash - -OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'` -echo "0x"$OFFSET 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/tree/Makefile Mon May 21 17:07:04 2001 @@ -0,0 +1,65 @@ +# BK Id: %F% %I% %G% %U% %#% +# +# +# Module name: Makefile +# +# Description: +# Makefile for the IBM "tree" evaluation board Linux kernel +# boot loaders. +# +# +# Copyright (c) 1999 Grant Erickson +# +# PPC-405 modification +# Copyright 2000-2001 MontaVista Software Inc. +# Author: MontaVista Software, Inc. +# frank_rowand@mvista.com or source@mvista.com +# debbie_chu@mvista.com +# + +HOSTCFLAGS = -O -I$(TOPDIR)/include + +CC = $(CROSS_COMPILE)gcc +LD = $(CROSS_COMPILE)ld +OBJCOPY = $(CROSS_COMPILE)objcopy +OBJDUMP = $(CROSS_COMPILE)objdump + +GZIP = gzip -vf9 +RM = rm -f +MKEVIMG = ../utils/mkevimg -l +MKIRIMG = ../utils/mkirimg +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 +LIBS = ../lib/zlib.a + +treeboot: $(OBJS) $(LIBS) ld.script + $(LD) -o $@ $(LD_ARGS) $(OBJS) $(LIBS) + +zImage: vmlinux.img + +zImage.initrd: vmlinux.initrd.img + +treeboot.image: treeboot + $(OBJCOPY) --add-section=image=../images/vmlinux.gz treeboot $@ + +treeboot.initrd: treeboot.image ramdisk.image.gz + $(OBJCOPY) --add-section=initrd=ramdisk.image.gz treeboot.image $@ + +vmlinux.img: treeboot.image + $(OBJDUMP) --syms treeboot.image | grep irSectStart > irSectStart.txt + $(MKIRIMG) treeboot.image treeboot.image.out irSectStart.txt + $(MKEVIMG) treeboot.image.out ../images/vmlinux.tree.img + $(RM) treeboot.image treeboot.image.out irSectStart.txt + +vmlinux.initrd.img: treeboot.initrd + $(OBJDUMP) --all-headers treeboot.initrd | grep irSectStart > irSectStart.txt + $(MKIRIMG) treeboot.initrd treeboot.initrd.out irSectStart.txt + $(MKEVIMG) treeboot.initrd.out ../images/vmlinux.tree.initrd.img + $(RM) treeboot.initrd treeboot.initrd.out irSectStart.txt + +clean: + rm -f treeboot treeboot.image treeboot.initrd irSectStart.txt vmlinux.* + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/tree/irSect.c b/arch/ppc/boot/tree/irSect.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/tree/irSect.c Mon May 21 17:07:04 2001 @@ -0,0 +1,39 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * + * Copyright (c) 1999 Grant Erickson + * + * Module name: irSect.c + * + * Description: + * Defines variables to hold the absolute starting address and size + * of the Linux kernel "image" and the initial RAM disk "initrd" + * sections within the boot loader. + * + */ + +#include "irSect.h" + + +/* + * The order of globals below must not change. If more globals are added, + * you must change the script 'mkirimg' accordingly. + * + */ + +/* + * irSectStart must be at beginning of file + */ +unsigned int irSectStart = 0xdeadbeaf; + +unsigned int imageSect_start = 0; +unsigned int imageSect_size = 0; +unsigned int initrdSect_start = 0; +unsigned int initrdSect_size = 0; + +/* + * irSectEnd must be at end of file + */ +unsigned int irSectEnd = 0xdeadbeaf; diff -Nru a/arch/ppc/boot/tree/irSect.h b/arch/ppc/boot/tree/irSect.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/tree/irSect.h Mon May 21 17:07:04 2001 @@ -0,0 +1,35 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * + * Copyright (c) 1999 Grant Erickson + * + * Module name: irSect.h + * + * Description: + * Defines variables to hold the absolute starting address and size + * of the Linux kernel "image" and the initial RAM disk "initrd" + * sections within the boot loader. + * + */ + +#ifndef __IRSECT_H__ +#define __IRSECT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +extern unsigned int imageSect_start; +extern unsigned int imageSect_size; + +extern unsigned int initrdSect_start; +extern unsigned int initrdSect_size; + + +#ifdef __cplusplus +} +#endif + +#endif /* __IRSECT_H__ */ diff -Nru a/arch/ppc/boot/tree/ld.script b/arch/ppc/boot/tree/ld.script --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/tree/ld.script Mon May 21 17:07:03 2001 @@ -0,0 +1,68 @@ +OUTPUT_ARCH(powerpc) +SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); +/* Do we need any of these for elf? + __DYNAMIC = 0; */ +SECTIONS +{ + /* Read-only sections, merged into text segment: */ + . = + SIZEOF_HEADERS; + .interp : { *(.interp) } + .hash : { *(.hash) } + .dynsym : { *(.dynsym) } + .dynstr : { *(.dynstr) } + .rel.text : { *(.rel.text) } + .rela.text : { *(.rela.text) } + .rel.data : { *(.rel.data) } + .rela.data : { *(.rela.data) } + .rel.rodata : { *(.rel.rodata) } + .rela.rodata : { *(.rela.rodata) } + .rel.got : { *(.rel.got) } + .rela.got : { *(.rela.got) } + .rel.ctors : { *(.rel.ctors) } + .rela.ctors : { *(.rela.ctors) } + .rel.dtors : { *(.rel.dtors) } + .rela.dtors : { *(.rela.dtors) } + .rel.bss : { *(.rel.bss) } + .rela.bss : { *(.rela.bss) } + .rel.plt : { *(.rel.plt) } + .rela.plt : { *(.rela.plt) } + .init : { *(.init) } =0 + .plt : { *(.plt) } + .text : + { + *(.text) + *(.rodata) + *(.rodata1) + *(.got1) + } + .fini : { *(.fini) } =0 + .ctors : { *(.ctors) } + .dtors : { *(.dtors) } + _etext = .; + PROVIDE (etext = .); + /* Read-write section, merged into data segment: */ + . = (. + 0x0FFF) & 0xFFFFF000; + .data : + { + *(.data) + *(.data1) + *(.sdata) + *(.sdata2) + *(.got.plt) *(.got) + *(.dynamic) + CONSTRUCTORS + } + _edata = .; + PROVIDE (edata = .); + __bss_start = .; + .bss : + { + *(.sbss) *(.scommon) + *(.dynbss) + *(.bss) + *(COMMON) + } + _end = . ; + PROVIDE (end = .); +} + diff -Nru a/arch/ppc/boot/tree/main.c b/arch/ppc/boot/tree/main.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/tree/main.c Mon May 21 17:07:04 2001 @@ -0,0 +1,249 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Copyright (c) 1997 Paul Mackerras + * Initial Power Macintosh COFF version. + * Copyright (c) 1999 Grant Erickson + * Modifications for an ELF-based IBM evaluation board version. + * Copyright 2000-2001 MontaVista Software Inc. + * PPC405GP modifications + * Author: MontaVista Software, Inc. + * frank_rowand@mvista.com or source@mvista.com + * debbie_chu@mvista.com + * + * + * Module name: main.c + * + * Description: + * This module does most of the real work for the boot loader. It + * checks the variables holding the absolute start address and size + * of the Linux kernel "image" and initial RAM disk "initrd" sections + * and if they are present, moves them to their "proper" locations. + * + * For the Linux kernel, "proper" is physical address 0x00000000. + * For the RAM disk, "proper" is the image's size below the top + * of physical memory. The Linux kernel may be in either raw + * binary form or compressed with GNU zip (aka gzip). + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + */ + +#include +#include + +#include "nonstdio.h" +#include "irSect.h" +#if defined(CONFIG_SERIAL_CONSOLE) +#include "ns16550.h" +#endif /* CONFIG_SERIAL_CONSOLE */ + + +/* Preprocessor Defines */ + +/* + * Location of the IBM boot ROM function pointer address for retrieving + * the board information structure. + */ + +#define BOARD_INFO_VECTOR 0xFFFE0B50 + +/* + * Warning: the board_info doesn't contain valid data until get_board_info() + * gets called in start(). + */ +#define RAM_SIZE board_info.bi_memsize + +#define RAM_PBASE 0x00000000 +#define RAM_PEND (RAM_PBASE + RAM_SIZE) + +#define RAM_VBASE 0xC0000000 +#define RAM_VEND (RAM_VBASE + RAM_SIZE) + +#define RAM_START RAM_PBASE +#define RAM_END RAM_PEND +#define RAM_FREE (imageSect_start + imageSect_size + initrdSect_size) + +#define PROG_START RAM_START + + +/* Function Macros */ + +#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) + +#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 */ + +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). + */ + + +/* +** The bootrom may change bootrom_cmdline to point to a buffer in the +** bootrom. +*/ +char *bootrom_cmdline = ""; +char treeboot_bootrom_cmdline[512]; + +#ifdef CONFIG_CMDLINE +char *cmdline = CONFIG_CMDLINE; +#else +char *cmdline = ""; +#endif + +/* Function Prototypes */ + +extern void *zalloc(void *x, unsigned items, unsigned size); + +/* 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 +serial_putc(void *unused, unsigned char c) +{ + while ((*uart0_lsr & LSR_THRE) == 0); + *uart0_xcvr = c; +} + +unsigned char +serial_getc(void *unused) +{ + while ((*uart0_lsr & LSR_DR) == 0); + return (*uart0_xcvr); +} + +int +serial_tstc(void *unused) +{ + return ((*uart0_lsr & LSR_DR) != 0); +} + + +void start(void) +{ + void *options; + int ns, oh, i; + unsigned long sa, len; + void *dst; + unsigned char *im; + unsigned long initrd_start, initrd_size; + 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 */ + + + +#if defined(CONFIG_WALNUT) + /* turn off 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; + } +#endif + + + if ((bip = get_board_info()) != NULL) + memcpy(&board_info, bip, sizeof(bd_t)); + + /* Init RAM disk (initrd) section */ + + if (initrdSect_start != 0 && (initrd_size = initrdSect_size) != 0) { + initrd_start = (RAM_END - initrd_size) & ~0xFFF; + + _printk("Initial RAM disk at 0x%08x (%u bytes)\n", + initrd_start, initrd_size); + + memcpy((char *)initrd_start, + (char *)(initrdSect_start), + initrdSect_size); + + end_avail = (char *)initrd_start; + } else { + initrd_start = initrd_size = 0; + end_avail = (char *)RAM_END; + } + + /* Linux kernel image section */ + + im = (unsigned char *)(imageSect_start); + len = imageSect_size; + dst = (void *)PROG_START; + + /* Check for the gzip archive magic numbers */ + + if (im[0] == 0x1f && im[1] == 0x8b) { + + /* The gunzip routine needs everything nice and aligned */ + + void *cp = (void *)ALIGN_UP(RAM_FREE, 8); + avail_ram = (void *)(cp + ALIGN_UP(len, 8)); /* used by zalloc() */ + memcpy(cp, im, len); + + /* I'm not sure what the 0x200000 parameter is for, but it works. */ + /* It tells gzip the end of the area you wish to reserve, and it + * can use data past that point....unfortunately, this value + * isn't big enough (luck ran out). -- Dan + */ + + gunzip(dst, 0x400000, cp, (int *)&len); + } else { + memmove(dst, im, len); + } + + + flush_cache(dst, len); + + sa = (unsigned long)dst; + + (*(void (*)())sa)(&board_info, + initrd_start, + initrd_start + initrd_size, + cmdline, + cmdline + strlen(cmdline)); + + pause(); +} diff -Nru a/arch/ppc/boot/tree/misc.S b/arch/ppc/boot/tree/misc.S --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/tree/misc.S Mon May 21 17:07:04 2001 @@ -0,0 +1,43 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include "../../kernel/ppc_asm.tmpl" + + .text + +/* + * Flush the dcache and invalidate the icache for a range of addresses. + * + * flush_cache(addr, len) + */ + .global flush_cache +flush_cache: + mfpvr r5 # Get processor version register + extrwi r5,r5,16,0 # Get the version bits + cmpwi cr0,r5,0x0020 # Is this a 403-based processor? + beq 1f # Yes, it is + li r5,32 # It is not a 403, set to 32 bytes + addi r4,r4,32-1 # len += line_size - 1 + srwi. r4,r4,5 # Convert from bytes to lines + b 2f +1: li r5,16 # It is a 403, set to 16 bytes + addi r4,r4,16-1 # len += line_size - 1 + srwi. r4,r4,4 # Convert from bytes to lines +2: mtctr r4 # Set-up the counter register + beqlr # If it is 0, we are done +3: dcbf r0,r3 # Flush and invalidate the data line + icbi r0,r3 # Invalidate the instruction line + add r3,r3,r5 # Move to the next line + bdnz 3b # Are we done yet? + sync + isync + blr # Return to the caller diff -Nru a/arch/ppc/boot/utils/Makefile b/arch/ppc/boot/utils/Makefile --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/Makefile Mon May 21 17:07:05 2001 @@ -0,0 +1,19 @@ +# +# arch/ppc/boot/utils/Makefile +# +# This file is subject to the terms and conditions of the GNU General Public +# License. See the file "COPYING" in the main directory of this archive +# for more details. + +HOSTCFLAGS += -I$(TOPDIR)/arch/$(ARCH)/boot/include + +# Simple programs with 1 file and no extra CFLAGS +UTILS = addnote hack-coff mkprep mksimage mknote piggyback mkpmon mkbugboot + +$(UTILS): + $(HOSTCC) $(HOSTCFLAGS) -o $@ $@.c + +clean: + rm -f $(UTILS) + +include $(TOPDIR)/Rules.make diff -Nru a/arch/ppc/boot/utils/addnote.c b/arch/ppc/boot/utils/addnote.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/addnote.c Mon May 21 17:07:03 2001 @@ -0,0 +1,177 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Program to hack in a PT_NOTE program header entry in an ELF file. + * This is needed for OF on RS/6000s to load an image correctly. + * Note that OF needs a program header entry for the note, not an + * ELF section. + * + * Copyright 2000 Paul Mackerras. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Usage: addnote zImage + */ +#include +#include +#include +#include + +char arch[] = "PowerPC"; + +#define N_DESCR 6 +unsigned int descr[N_DESCR] = { +#if 1 + /* values for IBM RS/6000 machines */ + 0xffffffff, /* real-mode = true */ + 0x00c00000, /* real-base, i.e. where we expect OF to be */ + 0xffffffff, /* real-size */ + 0xffffffff, /* virt-base */ + 0xffffffff, /* virt-size */ + 0x4000, /* load-base */ +#else + /* values for longtrail CHRP */ + 0, /* real-mode = false */ + 0xffffffff, /* real-base */ + 0xffffffff, /* real-size */ + 0xffffffff, /* virt-base */ + 0xffffffff, /* virt-size */ + 0x00600000, /* load-base */ +#endif +}; + +unsigned char buf[512]; + +#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) +#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2)) + +#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \ + buf[(off) + 1] = (v) & 0xff) +#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \ + PUT_16BE((off) + 2, (v))) + +/* Structure of an ELF file */ +#define E_IDENT 0 /* ELF header */ +#define E_PHOFF 28 +#define E_PHENTSIZE 42 +#define E_PHNUM 44 +#define E_HSIZE 52 /* size of ELF header */ + +#define EI_MAGIC 0 /* offsets in E_IDENT area */ +#define EI_CLASS 4 +#define EI_DATA 5 + +#define PH_TYPE 0 /* ELF program header */ +#define PH_OFFSET 4 +#define PH_FILESZ 16 +#define PH_HSIZE 32 /* size of program header */ + +#define PT_NOTE 4 /* Program header type = note */ + +#define ELFCLASS32 1 +#define ELFDATA2MSB 2 + +unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; + +int main(int ac, char **av) +{ + int fd, n, i; + int ph, ps, np; + int nnote, ns; + + if (ac != 2) { + fprintf(stderr, "Usage: %s elf-file\n", av[0]); + exit(1); + } + fd = open(av[1], O_RDWR); + if (fd < 0) { + perror(av[1]); + exit(1); + } + + nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4; + + n = read(fd, buf, sizeof(buf)); + if (n < 0) { + perror("read"); + exit(1); + } + + if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0) + goto notelf; + + if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 + || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { + fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", + av[1]); + exit(1); + } + + ph = GET_32BE(E_PHOFF); + ps = GET_16BE(E_PHENTSIZE); + np = GET_16BE(E_PHNUM); + if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) + goto notelf; + if (ph + (np + 1) * ps + nnote > n) + goto nospace; + + for (i = 0; i < np; ++i) { + if (GET_32BE(ph + PH_TYPE) == PT_NOTE) { + fprintf(stderr, "%s already has a note entry\n", + av[1]); + exit(0); + } + ph += ps; + } + + /* XXX check that the area we want to use is all zeroes */ + for (i = 0; i < ps + nnote; ++i) + if (buf[ph + i] != 0) + goto nospace; + + /* fill in the program header entry */ + ns = ph + ps; + PUT_32BE(ph + PH_TYPE, PT_NOTE); + PUT_32BE(ph + PH_OFFSET, ns); + PUT_32BE(ph + PH_FILESZ, nnote); + + /* fill in the note area we point to */ + /* XXX we should probably make this a proper section */ + PUT_32BE(ns, strlen(arch) + 1); + PUT_32BE(ns + 4, N_DESCR * 4); + PUT_32BE(ns + 8, 0x1275); + strcpy(&buf[ns + 12], arch); + ns += 12 + strlen(arch) + 1; + for (i = 0; i < N_DESCR; ++i) + PUT_32BE(ns + i * 4, descr[i]); + + /* Update the number of program headers */ + PUT_16BE(E_PHNUM, np + 1); + + /* write back */ + lseek(fd, (long) 0, SEEK_SET); + i = write(fd, buf, n); + if (i < 0) { + perror("write"); + exit(1); + } + if (i < n) { + fprintf(stderr, "%s: write truncated\n", av[1]); + exit(1); + } + + exit(0); + + notelf: + fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]); + exit(1); + + nospace: + fprintf(stderr, "sorry, I can't find space in %s to put the note\n", + av[0]); + exit(1); +} diff -Nru a/arch/ppc/boot/utils/elf.pl b/arch/ppc/boot/utils/elf.pl --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/elf.pl Mon May 21 17:07:04 2001 @@ -0,0 +1,33 @@ +# +# ELF header field numbers +# + +$e_ident = 0; # Identification bytes / magic number +$e_type = 1; # ELF file type +$e_machine = 2; # Target machine type +$e_version = 3; # File version +$e_entry = 4; # Start address +$e_phoff = 5; # Program header file offset +$e_shoff = 6; # Section header file offset +$e_flags = 7; # File flags +$e_ehsize = 8; # Size of ELF header +$e_phentsize = 9; # Size of program header +$e_phnum = 10; # Number of program header entries +$e_shentsize = 11; # Size of section header +$e_shnum = 12; # Number of section header entries +$e_shstrndx = 13; # Section header table string index + +# +# Section header field numbers +# + +$sh_name = 0; # Section name +$sh_type = 1; # Section header type +$sh_flags = 2; # Section header flags +$sh_addr = 3; # Virtual address +$sh_offset = 4; # File offset +$sh_size = 5; # Section size +$sh_link = 6; # Miscellaneous info +$sh_info = 7; # More miscellaneous info +$sh_addralign = 8; # Memory alignment +$sh_entsize = 9; # Entry size if this is a table diff -Nru a/arch/ppc/boot/utils/hack-coff.c b/arch/ppc/boot/utils/hack-coff.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/hack-coff.c Mon May 21 17:07:04 2001 @@ -0,0 +1,85 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * hack-coff.c - hack the header of an xcoff file to fill in + * a few fields needed by the Open Firmware xcoff loader on + * Power Macs but not initialized by objcopy. + * + * Copyright (C) Paul Mackerras 1997. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include "rs6000.h" + +#define AOUT_MAGIC 0x010b + +#define get_16be(x) ((((unsigned char *)(x))[0] << 8) \ + + ((unsigned char *)(x))[1]) +#define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \ + ((unsigned char *)(x))[1] = (v) & 0xff) +#define get_32be(x) ((((unsigned char *)(x))[0] << 24) \ + + (((unsigned char *)(x))[1] << 16) \ + + (((unsigned char *)(x))[2] << 8) \ + + ((unsigned char *)(x))[3]) + +int +main(int ac, char **av) +{ + int fd; + int i, nsect; + int aoutsz; + struct external_filehdr fhdr; + AOUTHDR aout; + struct external_scnhdr shdr; + + if (ac != 2) { + fprintf(stderr, "Usage: hack-coff coff-file\n"); + exit(1); + } + if ((fd = open(av[1], 2)) == -1) { + perror(av[2]); + exit(1); + } + if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr)) + goto readerr; + i = get_16be(fhdr.f_magic); + if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) { + fprintf(stderr, "%s: not an xcoff file\n", av[1]); + exit(1); + } + aoutsz = get_16be(fhdr.f_opthdr); + if (read(fd, &aout, aoutsz) != aoutsz) + goto readerr; + nsect = get_16be(fhdr.f_nscns); + for (i = 0; i < nsect; ++i) { + if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr)) + goto readerr; + if (strcmp(shdr.s_name, ".text") == 0) { + put_16be(aout.o_snentry, i+1); + put_16be(aout.o_sntext, i+1); + } else if (strcmp(shdr.s_name, ".data") == 0) { + put_16be(aout.o_sndata, i+1); + } else if (strcmp(shdr.s_name, ".bss") == 0) { + put_16be(aout.o_snbss, i+1); + } + } + put_16be(aout.magic, AOUT_MAGIC); + if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1 + || write(fd, &aout, aoutsz) != aoutsz) { + fprintf(stderr, "%s: write error\n", av[1]); + exit(1); + } + close(fd); + exit(0); + +readerr: + fprintf(stderr, "%s: read error or file too short\n", av[1]); + exit(1); +} 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 Mon May 21 17:07:05 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 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/mkevimg Mon May 21 17:07:03 2001 @@ -0,0 +1,437 @@ +#!/usr/bin/perl + +# +# Copyright (c) 1998-1999 TiVo, Inc. +# All rights reserved. +# +# Copyright (c) 1999 Grant Erickson +# Major syntactic and usability rework. +# +# Module name: mkevimg +# +# Description: +# Converts an ELF output file from the linker into the format used by +# the IBM evaluation board ROM Monitor to load programs from a host +# onto the evaluation board. The ELF file must be an otherwise execut- +# able file (with the text and data addresses bound at link time) and +# have space reserved after the entry point for the load information +# block: +# +# typedef struct boot_block { +# unsigned long magic; 0x0052504F +# unsigned long dest; Target address of the image +# unsigned long num_512blocks; Size, rounded-up, in 512 byte blocks +# unsigned long debug_flag; Run the debugger or image after load +# unsigned long entry_point; The image address to jump to after load +# unsigned long reserved[3]; +# } boot_block_t; +# +# + +use File::Basename; +use Getopt::Std; + +# +# usage() +# +# Description: +# This routine prints out the proper command line usage for this program +# +# Input(s): +# status - Flag determining what usage information will be printed and what +# the exit status of the program will be after the information is +# printed. +# +# Output(s): +# N/A +# +# Returns: +# This subroutine does not return. +# + +sub usage { + my($status); + $status = $_[0]; + + printf("Usage: %s [-hlvV] \n", + $program); + + if ($status != 0) { + printf("Try `%s -h' for more information.\n", $program); + } + + if ($status != 1) { + print(" -h Print out this message and exit.\n"); + print(" -l Linux mode; if present, copy 'image' and 'initrd' sections.\n"); + print(" -v Verbose. Print out lots of ELF information.\n"); + print(" -V Print out version information and exit.\n"); + } + + exit($status); +} + +# +# version() +# +# Description: +# This routine prints out program version information +# +# Input(s): +# N/A +# +# Output(s): +# N/A +# +# Returns: +# This subroutine does not return. +# + +sub version { + print("mkevimg Version 1.1.0\n"); + print("Copyright (c) 1998-1999 TiVo, Inc.\n"); + print("Copyright (c) 1999 Grant Erickson \n"); + + exit (0); +} + +# +# file_check() +# +# Description: +# This routine checks an input file to ensure that it exists, is a +# regular file, and is readable. +# +# Input(s): +# file - Input file to be checked. +# +# Output(s): +# N/A +# +# Returns: +# 0 if the file exists, is a regular file, and is readable, otherwise -1. +# + +sub file_check { + my($file); + $file = $_[0]; + + if (!(-e $file)) { + printf("The file \"%s\" does not exist.\n", $file); + return (-1); + } elsif (!(-f $file)) { + printf("The file \"%s\" is not a regular file.\n", $file); + return (-1); + } elsif (!(-r $file)) { + printf("The file \"%s\" is not readable.\n", $file); + return (-1); + } + + return (0); +} + +# +# decode_options() +# +# Description: +# This routine steps through the command-line arguments, parsing out +# recognzied options. +# +# Input(s): +# N/A +# +# Output(s): +# N/A +# +# Returns: +# N/A +# + +sub decode_options { + + if (!getopts("hlvV")) { + usage(1); + } + + if ($opt_h) { + usage(0); + } + + if ($opt_l) { + $linux = 1; + } + + if ($opt_V) { + version(); + exit (0); + } + + if ($opt_v) { + $verbose = 1; + } + + if (!($ifile = shift(@ARGV))) { + usage(1); + } + + if (!($ofile = shift(@ARGV))) { + usage (1); + } + + if (file_check($ifile)) { + exit(1); + } + +} + +# +# ELF file and section header field numbers +# + +require '../utils/elf.pl'; + +# +# Main program body +# + +{ + $program = basename($0); + + decode_options(); + + open(ELF, "<$ifile") || die "Cannot open input file"; + + $ifilesize = (-s $ifile); + + if ($verbose) { + print("Output file: $ofile\n"); + print("Input file: $ifile, $ifilesize bytes.\n"); + } + + if (read(ELF, $ibuf, $ifilesize) != $ifilesize) { + print("Failed to read input file!\n"); + exit(1); + } + + # + # Parse ELF header + # + + @eh = unpack("a16n2N5n6", $ibuf); + + # + # Make sure this is actually a PowerPC ELF file. + # + + if (substr($eh[$e_ident], 0, 4) ne "\177ELF") { + printf("The file \"%s\" is not an ELF file.\n", $ifile); + exit (1); + } elsif ($eh[$e_machine] != 20) { + printf("The file \"%s\" is not a PowerPC ELF file.\n", $ifile); + exit (1); + } + + if ($verbose) { + print("File header:\n"); + printf(" Identifier: %s\n", $eh[$e_ident]); + printf(" Type: %d\n", $eh[$e_type]); + printf(" Machine: %d\n", $eh[$e_machine]); + printf(" Version: %d\n", $eh[$e_version]); + printf(" Entry point: 0x%08x\n", $eh[$e_entry]); + printf(" Program header offset: 0x%x\n", $eh[$e_phoff]); + printf(" Section header offset: 0x%x\n", $eh[$e_shoff]); + printf(" Flags: 0x%08x\n", $eh[$e_flags]); + printf(" Header size: %d\n", $eh[$e_ehsize]); + printf(" Program entry size: %d\n", $eh[$e_phentsize]); + printf(" Program table entries: %d\n", $eh[$e_phnum]); + printf(" Section header size: %d\n", $eh[$e_shentsize]); + printf(" Section table entries: %d\n", $eh[$e_shnum]); + printf(" String table section: %d\n", $eh[$e_shstrndx]); + } + + # + # Find the section header for the string table. + # + + $strtable_section_offset = $eh[$e_shoff] + + $eh[$e_shstrndx] * $eh[$e_shentsize]; + + if ($verbose) { + printf("String table section header offset: 0x%x\n", + $strtable_section_offset); + } + + # + # Find the start of the string table. + # + + @strh = unpack("N10", substr($ibuf, $strtable_section_offset, + $eh[$e_shentsize])); + + if ($verbose) { + printf("Section name strings start at: 0x%x, %d bytes.\n", + $strh[$sh_offset], $strh[$sh_size]); + } + + $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]); + + # Grab each section header and find '.text' and '.bss' sections in + # particular. + + if ($verbose) { + print("Section headers:\n"); + print("Idx Name Size Address File off Algn\n"); + print("--- ------------------------ -------- -------- -------- ----\n"); + } + + $off = $eh[$e_shoff]; + + for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) { + @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize])); + + # Take the first section name from the array returned by split. + + ($name) = split(/\000/, substr($names, $sh[$sh_name])); + + if ($verbose) { + printf("%3d %-24s %8x %08x %08x %4d\n", + $i, $name, $sh[$sh_size], $sh[$sh_addr], + $sh[$sh_offset], $sh[$sh_addralign]); + } + + # Attempt to find the .text and .bss sections + + if ($name =~ /^\.bss$/) { + ($bss_addr, $bss_offset, $bss_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + + } elsif ($name =~ /^\.text$/) { + ($text_addr, $text_offset, $text_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + + } elsif ($linux && ($name =~ /^\image$/)) { + $image_found = 1; + + ($image_addr, $image_offset, $image_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + + } elsif ($linux && ($name =~ /^\initrd$/)) { + $initrd_found = 1; + + ($initrd_addr, $initrd_offset, $initrd_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + + } + } + + printf("Text section - Address: 0x%08x, Size: 0x%08x\n", + $text_addr, $text_size); + printf("Bss section - Address: 0x%08x, Size: 0x%08x\n", + $bss_addr, $bss_size); + + if ($linux) { + if ($image_found) { + printf("Image section - Address: 0x%08x, Size: 0x%08x\n", + $image_addr, $image_size); + } + + if ($initrd_found) { + printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n", + $initrd_addr, $initrd_size); + } + } + + # + # Open output file + # + + open(BOOT, ">$ofile") || die "Cannot open output file"; + + # + # Compute image size + # + + $output_size = $bss_offset - $text_offset + $bss_size; + + if ($linux && $image_found) { + $output_size += $image_size; + } + + if ($linux && $initrd_found) { + $output_size += $initrd_size; + } + + $num_blocks = $output_size / 512 + 1; + + # + # Write IBM PowerPC evaluation board boot_block_t header + # + + $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0, + $text_addr, 0, 0, 0); + + $bytes = length($header); + + if (($resid = syswrite(BOOT, $header, $bytes)) != $bytes) { + die("Could not write boot image header to output file."); + } + + printf("Entry point = 0x%08x\n", $text_addr); + printf("Image size = 0x%08x (%d bytes) (%d blocks).\n", + $output_size, $output_size, $num_blocks); + + # + # Write image starting after ELF and program headers and + # continuing to beginning of bss + # + + $bytes = $bss_offset - $text_offset + $bss_size; + + if (($resid = syswrite(BOOT, $ibuf, $bytes, $text_offset)) != $bytes) { + die("Could not write boot image to output file.\n"); + } + + # + # If configured, write out the image and initrd sections as well + # + + if ($linux) { + if ($image_found) { + $bytes = $image_size; + if (($resid = syswrite(BOOT, $ibuf, $bytes, $image_offset)) != $bytes) { + die("Could not write boot image to output file.\n"); + } + } + + if ($initrd_found) { + $bytes = $initrd_size; + if (($resid = syswrite(BOOT, $ibuf, $bytes, $initrd_offset)) != $bytes) { + die("Could not write boot image to output file.\n"); + } + } + } + + # + # Pad to a multiple of 512 bytes + # + + $pad_size = 512 - (length($header) + $output_size) % 512; + + if ($verbose) { + print("Padding boot image by an additional $pad_size bytes.\n"); + } + + $pad_string = pack(("H8","deadbeef") x 128); + + syswrite(BOOT, $pad_string, $pad_size) or + die "Could not pad boot image in output file.\n"; + + # + # Clean-up and leave + # + + close(BOOT); + + print("\nBoot image file \"$ofile\" built successfuly.\n\n"); + + exit(0); +} diff -Nru a/arch/ppc/boot/utils/mkirimg b/arch/ppc/boot/utils/mkirimg --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/mkirimg Mon May 21 17:07:04 2001 @@ -0,0 +1,367 @@ +#!/usr/bin/perl +# +# Copyright (c) 1998-1999 TiVo, Inc. +# Original ELF parsing code. +# +# Copyright (c) 1999 Grant Erickson +# Original code from 'mkevimg'. +# +# Module name: mkirimg +# +# Description: +# Reads an ELF file and assigns global variables 'imageSect_start', +# 'imageSect_size', 'initrdSect_start', and 'initrdSect_size' from +# the "image" and "initrd" section header information. It then +# rewrites the input ELF file with assigned globals to an output +# file. +# +# An input file, "irSectStart.txt" has the memory address of +# 'irSectStart'. The irSectStart memory address is used to find +# the global variables in the ".data" section of the ELF file. +# The 'irSectStart' and the above global variables are defined +# in "irSect.c". +# +# + +use File::Basename; +use Getopt::Std; + +# +# usage() +# +# Description: +# This routine prints out the proper command line usage for this program +# +# Input(s): +# status - Flag determining what usage information will be printed and what +# the exit status of the program will be after the information is +# printed. +# +# Output(s): +# N/A +# +# Returns: +# This subroutine does not return. +# + +sub usage { + my($status); + $status = $_[0]; + + printf("Usage: %s [-hvV] \n", + $program); + + if ($status != 0) { + printf("Try `%s -h' for more information.\n", $program); + } + + if ($status != 1) { + print(" -h Print out this message and exit.\n"); + print(" -v Verbose. Print out lots of ELF information.\n"); + print(" -V Print out version information and exit.\n"); + } + + exit($status); +} + +# +# version() +# +# Description: +# This routine prints out program version information +# +# Input(s): +# N/A +# +# Output(s): +# N/A +# +# Returns: +# This subroutine does not return. +# + +sub version { + print("mkirimg Version 1.1.0\n"); + print("Copyright (c) 1998-1999 TiVo, Inc.\n"); + print("Copyright (c) 1999 Grant Erickson \n"); + + exit (0); +} + +# +# file_check() +# +# Description: +# This routine checks an input file to ensure that it exists, is a +# regular file, and is readable. +# +# Input(s): +# file - Input file to be checked. +# +# Output(s): +# N/A +# +# Returns: +# 0 if the file exists, is a regular file, and is readable, otherwise -1. +# + +sub file_check { + my($file); + $file = $_[0]; + + if (!(-e $file)) { + printf("The file \"%s\" does not exist.\n", $file); + return (-1); + } elsif (!(-f $file)) { + printf("The file \"%s\" is not a regular file.\n", $file); + return (-1); + } elsif (!(-r $file)) { + printf("The file \"%s\" is not readable.\n", $file); + return (-1); + } + + return (0); +} + +# +# decode_options() +# +# Description: +# This routine steps through the command-line arguments, parsing out +# recognzied options. +# +# Input(s): +# N/A +# +# Output(s): +# N/A +# +# Returns: +# N/A +# + +sub decode_options { + + if (!getopts("hvV")) { + usage(1); + } + + if ($opt_h) { + usage(0); + } + + if ($opt_V) { + version(); + exit (0); + } + + if ($opt_v) { + $verbose = 1; + } + + if (!($ElfFile = shift(@ARGV))) { + usage(1); + } + + if (!($OutputFile = shift(@ARGV))) { + usage (1); + } + + if (!($IrFile = shift(@ARGV))) { + usage (1); + } + + if (file_check($ElfFile)) { + exit(1); + } + + if (file_check($IrFile)) { + exit(1); + } +} + +# +# ELF file and section header field numbers +# + +require '../utils/elf.pl'; + +# +# Main program body +# + +{ + $program = basename($0); + decode_options(); + + open(ELF, "<$ElfFile") || die "Cannot open input file"; + open(OUTPUT, ">$OutputFile") || die "Cannot open output file"; + open(IR, "$IrFile") || die "Cannot open input file"; + + $ElfFilesize = (-s $ElfFile); + + if (read(ELF, $ibuf, $ElfFilesize) != $ElfFilesize) { + print("Failed to read ELF input file!\n"); + exit(1); + } + + if (read(IR, $irbuf, 8) != 8) { + print("Failed to read Ir input file!\n"); + exit(1); + } + + # + # Parse ELF header + # + + @eh = unpack("a16n2N5n6", $ibuf); + + # + # Make sure this is actually a PowerPC ELF file. + # + + if (substr($eh[$e_ident], 0, 4) ne "\177ELF") { + printf("The file \"%s\" is not an ELF file.\n", $ElfFile); + exit (1); + } elsif ($eh[$e_machine] != 20) { + printf("The file \"%s\" is not a PowerPC ELF file.\n", $ElfFile); + exit (1); + } + + # + # Find the section header for the string table. + # + + $strtable_section_offset = $eh[$e_shoff] + + + $eh[$e_shstrndx] * $eh[$e_shentsize]; + + if ($verbose) { + printf("String table section header offset: 0x%x\n", + $strtable_section_offset); + } + + # + # Find the start of the string table. + # + + @strh = unpack("N10", substr($ibuf, $strtable_section_offset, + $eh[$e_shentsize])); + + if ($verbose) { + printf("Section name strings start at: 0x%x, %d bytes.\n", + $strh[$sh_offset], $strh[$sh_size]); + } + + $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]); + + # Grab each section header and find '.data', 'image', and + # 'initrd' sections in particular. + + $off = $eh[$e_shoff]; + $imageFound = 0; + $initrdFound = 0; + + for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) { + @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize])); + + # Take the first section name from the array returned by split. + + ($name) = split(/\000/, substr($names, $sh[$sh_name])); + + # Attempt to find the .data, image, and initrd sections + + if ($name =~ /^\image$/) { + ($image_addr, $image_offset, $image_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + $imageFound = 1; + + } elsif ($name =~ /^\initrd$/) { + ($initrd_addr, $initrd_offset, $initrd_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + $initrdFound = 1; + + } elsif ($name =~ /^\.data$/) { + ($data_addr, $data_offset, $data_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + + } elsif ($name =~ /^\.bss$/) { + ($bss_addr, $bss_offset, $bss_size) = + ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); + + } + } + + if ($verbose) { + printf("Data section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n", + $data_addr, $data_size, $data_offset); + printf("Bss section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n", + $bss_addr, $bss_size, $bss_offset); + } + + if ($verbose) { + if ($imageFound) { + printf("Image section - Address: 0x%08x, Size: 0x%08x\n", + $image_addr, $image_size); + } else { + printf("Image section not found in file: $ElfFile\n"); + } + + if ($initrdFound) { + printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n", + $initrd_addr, $initrd_size); + } else { + printf("Initrd section not found in file: $ElfFile\n"); + } + } + + # get file offset of irSectStart + + $irSectStartoffset = hex ($irbuf); + + if ($verbose) { + printf("irSectStartOffset Address: 0x%08x\n", $irSectStartoffset); + } + + # get the offset of global variables + + $initialOffset = ($irSectStartoffset - $data_addr) + $data_offset + 4; + + # write modified values to OUTPUT file + + syswrite(OUTPUT, $ibuf, $initialOffset); + + if ($imageFound) { + $testN = pack ("N2", $bss_addr + $bss_size, $image_size); + syswrite(OUTPUT, $testN, length($testN)); + printf("Updated symbol \"imageSect_start\" to 0x%08x\n", + $bss_addr + $bss_size); + printf("Updated symbol \"imageSect_size\" to 0x%08x\n", $image_size); + } else { + syswrite(OUTPUT, $ibuf, 8, $initialOffset); + } + + if ($initrdFound) { + $testN = pack ("N2", $bss_addr + $bss_size + $image_size, $initrd_size); + syswrite(OUTPUT, $testN, length($testN)); + printf("Updated symbol \"initrdSect_start\" to 0x%08x\n", + $bss_addr + $bss_size + $image_size); + printf("Updated symbol \"initrdSect_size\" to 0x%08x\n", $initrd_size); + } else { + syswrite(OUTPUT, $ibuf,8, $initialOffset + 8); + } + + syswrite(OUTPUT, $ibuf, $ElfFilesize - ($initialOffset + 16), + $initialOffset + 16); + + # + # Clean-up and leave + # + + close (ELF); + close (OUTPUT); + close (IR); + + exit (0); +} + diff -Nru a/arch/ppc/boot/utils/mknote.c b/arch/ppc/boot/utils/mknote.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/mknote.c Mon May 21 17:07:04 2001 @@ -0,0 +1,46 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Copyright (C) Cort Dougan 1999. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * Generate a note section as per the CHRP specification. + * + */ + +#include + +#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); + +int main(void) +{ +/* header */ + /* namesz */ + PL(strlen("PowerPC")+1); + /* descrsz */ + PL(6*4); + /* type */ + PL(0x1275); + /* name */ + printf("PowerPC"); printf("%c", 0); + +/* descriptor */ + /* real-mode */ + PL(0xffffffff); + /* real-base */ + PL(0x00c00000); + /* real-size */ + PL(0xffffffff); + /* virt-base */ + PL(0xffffffff); + /* virt-size */ + PL(0xffffffff); + /* load-base */ + PL(0x4000); + return 0; +} diff -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 Mon May 21 17:07:05 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 --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/mkprep.c Mon May 21 17:07:03 2001 @@ -0,0 +1,292 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Makes a prep bootable image which can be dd'd onto + * a disk device to make a bootdisk. Will take + * as input a elf executable, strip off the header + * and write out a boot image as: + * 1) default - strips elf header + * suitable as a network boot image + * 2) -pbp - strips elf header and writes out prep boot partition image + * cat or dd onto disk for booting + * 3) -asm - strips elf header and writes out as asm data + * useful for generating data for a compressed image + * -- Cort + * + * Modified for x86 hosted builds by Matt Porter + */ + +#include +#include +#include +#include +#include +#include + +#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)); +} + +#define cpu_to_be32(x) (x) +#define be32_to_cpu(x) (x) +#define cpu_to_be16(x) (x) +#define be16_to_cpu(x) (x) + +/* size of read buffer */ +#define SIZE 0x1000 + + +typedef unsigned long dword_t; +typedef unsigned short word_t; +typedef unsigned char byte_t; +typedef byte_t block_t[512]; +typedef byte_t page_t[4096]; + + +/* + * Partition table entry + * - from the PReP spec + */ +typedef struct partition_entry { + byte_t boot_indicator; + byte_t starting_head; + byte_t starting_sector; + byte_t starting_cylinder; + + byte_t system_indicator; + byte_t ending_head; + byte_t ending_sector; + byte_t ending_cylinder; + + dword_t beginning_sector; + dword_t number_of_sectors; +} partition_entry_t; + +#define BootActive 0x80 +#define SystemPrep 0x41 + +void copy_image(int , int); +void write_prep_partition(int , int ); +void write_asm_data( int in, int out ); + +unsigned int elfhdr_size = 65536; + +int main(int argc, char *argv[]) +{ + int in_fd, out_fd; + int argptr = 1; + unsigned int prep = 0; + unsigned int asmoutput = 0; + + if ( (argc < 3) || (argc > 4) ) + { + fprintf(stderr, "usage: %s [-pbp] [-asm] \n",argv[0]); + exit(-1); + } + + /* needs to handle args more elegantly -- but this is a small/simple program */ + + /* check for -pbp */ + if ( !strcmp( argv[argptr], "-pbp" ) ) + { + prep = 1; + argptr++; + } + + /* check for -asm */ + if ( !strcmp( argv[argptr], "-asm" ) ) + { + asmoutput = 1; + argptr++; + } + + /* input file */ + if ( !strcmp( argv[argptr], "-" ) ) + in_fd = 0; /* stdin */ + else + if ((in_fd = open( argv[argptr] , 0)) < 0) + exit(-1); + argptr++; + + /* output file */ + if ( !strcmp( argv[argptr], "-" ) ) + out_fd = 1; /* stdout */ + else + if ((out_fd = creat( argv[argptr] , 0755)) < 0) + exit(-1); + argptr++; + + /* skip elf header in input file */ + /*if ( !prep )*/ + lseek(in_fd, elfhdr_size, SEEK_SET); + + /* write prep partition if necessary */ + if ( prep ) + write_prep_partition( in_fd, out_fd ); + + /* write input image to bootimage */ + if ( asmoutput ) + write_asm_data( in_fd, out_fd ); + else + copy_image(in_fd, out_fd); + + return 0; +} + +void write_prep_partition(int in, int out) +{ + unsigned char block[512]; + partition_entry_t *pe = (partition_entry_t *)&block[0x1BE]; + dword_t *entry = (dword_t *)&block[0]; + dword_t *length = (dword_t *)&block[sizeof(long)]; + struct stat info; + + if (fstat(in, &info) < 0) + { + fprintf(stderr,"info failed\n"); + exit(-1); + } + + bzero( block, sizeof block ); + + /* set entry point and boot image size skipping over elf header */ +#ifdef __i386__ + *entry = 0x400/*+65536*/; + *length = info.st_size-elfhdr_size+0x400; +#else + *entry = cpu_to_le32(0x400/*+65536*/); + *length = cpu_to_le32(info.st_size-elfhdr_size+0x400); +#endif /* __i386__ */ + + /* sets magic number for msdos partition (used by linux) */ + block[510] = 0x55; + block[511] = 0xAA; + + /* + * Build a "PReP" partition table entry in the boot record + * - "PReP" may only look at the system_indicator + */ + pe->boot_indicator = BootActive; + pe->system_indicator = SystemPrep; + /* + * The first block of the diskette is used by this "boot record" which + * actually contains the partition table. (The first block of the + * partition contains the boot image, but I digress...) We'll set up + * one partition on the diskette and it shall contain the rest of the + * diskette. + */ + pe->starting_head = 0; /* zero-based */ + pe->starting_sector = 2; /* one-based */ + pe->starting_cylinder = 0; /* zero-based */ + pe->ending_head = 1; /* assumes two heads */ + pe->ending_sector = 18; /* assumes 18 sectors/track */ + pe->ending_cylinder = 79; /* assumes 80 cylinders/diskette */ + + /* + * The "PReP" software ignores the above fields and just looks at + * the next two. + * - size of the diskette is (assumed to be) + * (2 tracks/cylinder)(18 sectors/tracks)(80 cylinders/diskette) + * - unlike the above sector numbers, the beginning sector is zero-based! + */ +#if 0 + pe->beginning_sector = cpu_to_le32(1); +#else + /* This has to be 0 on the PowerStack? */ +#ifdef __i386__ + pe->beginning_sector = 0; +#else + pe->beginning_sector = cpu_to_le32(0); +#endif /* __i386__ */ +#endif + +#ifdef __i386__ + pe->number_of_sectors = 2*18*80-1; +#else + pe->number_of_sectors = cpu_to_le32(2*18*80-1); +#endif /* __i386__ */ + + write( out, block, sizeof(block) ); + write( out, entry, sizeof(*entry) ); + write( out, length, sizeof(*length) ); + /* set file position to 2nd sector where image will be written */ + lseek( out, 0x400, SEEK_SET ); +} + + + +void +copy_image(int in, int out) +{ + char buf[SIZE]; + int n; + + while ( (n = read(in, buf, SIZE)) > 0 ) + write(out, buf, n); +} + + +void +write_asm_data( int in, int out ) +{ + int i, cnt, pos, len; + unsigned int cksum, val; + unsigned char *lp; + unsigned char buf[SIZE]; + unsigned char str[256]; + + write( out, "\t.data\n\t.globl input_data\ninput_data:\n", + strlen( "\t.data\n\t.globl input_data\ninput_data:\n" ) ); + pos = 0; + cksum = 0; + while ((len = read(in, buf, sizeof(buf))) > 0) + { + cnt = 0; + lp = (unsigned char *)buf; + len = (len + 3) & ~3; /* Round up to longwords */ + for (i = 0; i < len; i += 4) + { + if (cnt == 0) + { + write( out, "\t.long\t", strlen( "\t.long\t" ) ); + } + sprintf( str, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); + write( out, str, strlen(str) ); + val = *(unsigned long *)lp; + cksum ^= val; + lp += 4; + if (++cnt == 4) + { + cnt = 0; + sprintf( str, " # %x \n", pos+i-12); + write( out, str, strlen(str) ); + } else + { + write( out, ",", 1 ); + } + } + if (cnt) + { + write( out, "0\n", 2 ); + } + pos += len; + } + sprintf(str, "\t.globl input_len\ninput_len:\t.long\t0x%x\n", pos); + write( out, str, strlen(str) ); + + fprintf(stderr, "cksum = %x\n", cksum); +} diff -Nru a/arch/ppc/boot/utils/mksimage.c b/arch/ppc/boot/utils/mksimage.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/mksimage.c Mon May 21 17:07:05 2001 @@ -0,0 +1,127 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * + * + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + + +#define SIZE 1024 +#define BLOCK_ALIGN(x) (((x)+SIZE-1)&(~(SIZE-1))) + +static void +die(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + vfprintf(stderr, fmt, args); + fputc('\n', stderr); + exit(1); +} + +static void +usage(void) +{ + printf("Usage: mkbinimg -o \n"); + exit(1); +} + +static int +copy_blocks(int ifd, int ofd, unsigned long *offset, unsigned long *size) +{ + off_t cur; + int amt; + unsigned long len = 0; + char buffer[SIZE]; + + cur = lseek(ofd, 0, SEEK_CUR); + + if (cur % SIZE) { + cur = BLOCK_ALIGN(cur); + cur = lseek(ofd, cur, SEEK_SET); + } + + *offset = (unsigned long) cur; + while((amt = read(ifd, buffer, SIZE)) > 0) { + write(ofd, buffer, amt); + len += amt; + } + *size = len; + return 0; +} + + +int +main(int argc, char *argv[]) +{ + char *kernel, *loader, *rdimage = NULL; + unsigned long ld_off, kern_off, rd_off; + unsigned long ld_size, kern_size, rd_size; + int fd, ofd, len; + char buffer[500]; + + if (argc < 5 && !strcmp(argv[argc-2], "-o")) + usage(); + + if (argc > 5) + rdimage = argv[3]; + + kernel = argv[2]; + loader = argv[1]; + + ofd = open(argv[argc-1], (O_RDWR|O_CREAT), 0755); + if (ofd < 0) { + die("can't open %s: %s", argv[5], strerror(errno)); + } + + ld_off = kern_off = rd_off = 0; + ld_size = kern_size = rd_size = 0; + memset(buffer, 0, 500); + len = 0; + + fd = open(loader, O_RDONLY); + if (fd < 0) + die("can't open loader: %s", strerror(errno)); + + copy_blocks(fd, ofd, &ld_off, &ld_size); + len = sprintf(buffer, "bootloader: %x %x\n", ld_off, ld_size); + close(fd); + + fd = open(kernel, O_RDONLY); + if (fd < 0) + die("can't open kernel: %s", strerror(errno)); + + copy_blocks(fd, ofd, &kern_off, &kern_size); + len += sprintf(buffer+len, "zimage: %x %x\n", kern_off, kern_size); + close(fd); + + if (rdimage) { + fd = open(rdimage, O_RDONLY); + if (fd < 0) + die("can't get ramdisk: %s", strerror(errno)); + + copy_blocks(fd, ofd, &rd_off, &rd_size); + close(fd); + } + + len += sprintf(buffer+len, "initrd: %x %x", rd_off, rd_size); + + close(ofd); + + printf("%s\n", buffer); + + return 0; +} + diff -Nru a/arch/ppc/boot/utils/offset b/arch/ppc/boot/utils/offset --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/offset Mon May 21 17:07:04 2001 @@ -0,0 +1,4 @@ +#!/bin/bash + +OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux| awk '{print $6}'` +echo "0x"$OFFSET diff -Nru a/arch/ppc/boot/utils/piggyback.c b/arch/ppc/boot/utils/piggyback.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/piggyback.c Mon May 21 17:07:04 2001 @@ -0,0 +1,69 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +#include +#include + +extern long ce_exec_config[]; + +int main(int argc, char *argv[]) +{ + int i, cnt, pos, len; + unsigned int cksum, val; + unsigned char *lp; + unsigned char buf[8192]; + if (argc != 2) + { + fprintf(stderr, "usage: %s name out-file\n", + argv[0]); + exit(1); + } + fprintf(stdout, "#\n"); + fprintf(stdout, "# Miscellaneous data structures:\n"); + fprintf(stdout, "# WARNING - this file is automatically generated!\n"); + fprintf(stdout, "#\n"); + fprintf(stdout, "\n"); + fprintf(stdout, "\t.data\n"); + fprintf(stdout, "\t.globl %s_data\n", argv[1]); + fprintf(stdout, "%s_data:\n", argv[1]); + pos = 0; + cksum = 0; + while ((len = read(0, buf, sizeof(buf))) > 0) + { + cnt = 0; + lp = (unsigned char *)buf; + len = (len + 3) & ~3; /* Round up to longwords */ + for (i = 0; i < len; i += 4) + { + if (cnt == 0) + { + fprintf(stdout, "\t.long\t"); + } + fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); + val = *(unsigned long *)lp; + cksum ^= val; + lp += 4; + if (++cnt == 4) + { + cnt = 0; + fprintf(stdout, " # %x \n", pos+i-12); + fflush(stdout); + } else + { + fprintf(stdout, ","); + } + } + if (cnt) + { + fprintf(stdout, "0\n"); + } + pos += len; + } + fprintf(stdout, "\t.globl %s_len\n", argv[1]); + fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos); + fflush(stdout); + fclose(stdout); + fprintf(stderr, "cksum = %x\n", cksum); + exit(0); +} + diff -Nru a/arch/ppc/boot/utils/sioffset b/arch/ppc/boot/utils/sioffset --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/sioffset Mon May 21 17:07:05 2001 @@ -0,0 +1,4 @@ +#!/bin/bash + +OFFSET=`grep $1 sImage.map | awk '{print $2}'` +echo "0x"$OFFSET diff -Nru a/arch/ppc/boot/utils/sisize b/arch/ppc/boot/utils/sisize --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/sisize Mon May 21 17:07:05 2001 @@ -0,0 +1,4 @@ +#!/bin/bash + +OFFSET=`grep $1 sImage.map | awk '{print $3}'` +echo "0x"$OFFSET diff -Nru a/arch/ppc/boot/utils/size b/arch/ppc/boot/utils/size --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/boot/utils/size Mon May 21 17:07:04 2001 @@ -0,0 +1,4 @@ +#!/bin/bash + +OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'` +echo "0x"$OFFSET diff -Nru a/arch/ppc/boot/vreset.c b/arch/ppc/boot/vreset.c --- a/arch/ppc/boot/vreset.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,838 +0,0 @@ -/* - * vreset.c - * - * Initialize the VGA control registers to 80x25 text mode. - * - * Adapted from a program by: - * Steve Sellgren - * San Francisco Indigo Company - * sfindigo!sellgren@uunet.uu.net - * - * Original concept by: - * Gary Thomas - * Adapted for Moto boxes by: - * Pat Kane & Mark Scott, 1996 - * Adapted for IBM portables by: - * Takeshi Ishimoto - * Multi-console support: - * Terje Malmedal - */ - -#include "iso_font.h" - -extern char *vidmem; -extern int lines, cols; - -static void mdelay(int ms) -{ - for (; ms > 0; --ms) - udelay(1000); -} - -/* - * VGA Register - */ -struct VgaRegs -{ - unsigned short io_port; - unsigned char io_index; - unsigned char io_value; -}; - -/* - * Default console text mode registers used to reset - * graphics adapter. - */ -#define NREGS 54 -#define ENDMK 0xFFFF /* End marker */ - -#define S3Vendor 0x5333 -#define CirrusVendor 0x1013 -#define DiamondVendor 0x100E -#define MatroxVendor 0x102B -#define ParadiseVendor 0x101C - -struct VgaRegs GenVgaTextRegs[NREGS+1] = { -/* port index value */ - /* SR Regs */ - 0x3c4, 0x1, 0x0, - 0x3c4, 0x2, 0x3, - 0x3c4, 0x3, 0x0, - 0x3c4, 0x4, 0x2, - /* CR Regs */ - 0x3d4, 0x0, 0x5f, - 0x3d4, 0x1, 0x4f, - 0x3d4, 0x2, 0x50, - 0x3d4, 0x3, 0x82, - 0x3d4, 0x4, 0x55, - 0x3d4, 0x5, 0x81, - 0x3d4, 0x6, 0xbf, - 0x3d4, 0x7, 0x1f, - 0x3d4, 0x8, 0x00, - 0x3d4, 0x9, 0x4f, - 0x3d4, 0xa, 0x0d, - 0x3d4, 0xb, 0x0e, - 0x3d4, 0xc, 0x00, - 0x3d4, 0xd, 0x00, - 0x3d4, 0xe, 0x00, - 0x3d4, 0xf, 0x00, - 0x3d4, 0x10, 0x9c, - 0x3d4, 0x11, 0x8e, - 0x3d4, 0x12, 0x8f, - 0x3d4, 0x13, 0x28, - 0x3d4, 0x14, 0x1f, - 0x3d4, 0x15, 0x96, - 0x3d4, 0x16, 0xb9, - 0x3d4, 0x17, 0xa3, - /* GR Regs */ - 0x3ce, 0x0, 0x0, - 0x3ce, 0x1, 0x0, - 0x3ce, 0x2, 0x0, - 0x3ce, 0x3, 0x0, - 0x3ce, 0x4, 0x0, - 0x3ce, 0x5, 0x10, - 0x3ce, 0x6, 0xe, - 0x3ce, 0x7, 0x0, - 0x3ce, 0x8, 0xff, - ENDMK -}; - -struct VgaRegs S3TextRegs[NREGS+1] = { -/* port index value */ - /* SR Regs */ - 0x3c4, 0x1, 0x0, - 0x3c4, 0x2, 0x3, - 0x3c4, 0x3, 0x0, - 0x3c4, 0x4, 0x2, - /* CR Regs */ - 0x3d4, 0x0, 0x5f, - 0x3d4, 0x1, 0x4f, - 0x3d4, 0x2, 0x50, - 0x3d4, 0x3, 0x82, - 0x3d4, 0x4, 0x55, - 0x3d4, 0x5, 0x81, - 0x3d4, 0x6, 0xbf, - 0x3d4, 0x7, 0x1f, - 0x3d4, 0x8, 0x00, - 0x3d4, 0x9, 0x4f, - 0x3d4, 0xa, 0x0d, - 0x3d4, 0xb, 0x0e, - 0x3d4, 0xc, 0x00, - 0x3d4, 0xd, 0x00, - 0x3d4, 0xe, 0x00, - 0x3d4, 0xf, 0x00, - 0x3d4, 0x10, 0x9c, - 0x3d4, 0x11, 0x8e, - 0x3d4, 0x12, 0x8f, - 0x3d4, 0x13, 0x28, - 0x3d4, 0x14, 0x1f, - 0x3d4, 0x15, 0x96, - 0x3d4, 0x16, 0xb9, - 0x3d4, 0x17, 0xa3, - /* GR Regs */ - 0x3ce, 0x0, 0x0, - 0x3ce, 0x1, 0x0, - 0x3ce, 0x2, 0x0, - 0x3ce, 0x3, 0x0, - 0x3ce, 0x4, 0x0, - 0x3ce, 0x5, 0x10, - 0x3ce, 0x6, 0xe, - 0x3ce, 0x7, 0x0, - 0x3ce, 0x8, 0xff, - ENDMK -}; - -struct RGBColors -{ - unsigned char r, g, b; -}; - -/* - * Default console text mode color table. - * These values were obtained by booting Linux with - * text mode firmware & then dumping the registers. - */ -struct RGBColors TextCLUT[256] = -{ - /* red green blue */ - 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2a, - 0x0, 0x2a, 0x0, - 0x0, 0x2a, 0x2a, - 0x2a, 0x0, 0x0, - 0x2a, 0x0, 0x2a, - 0x2a, 0x2a, 0x0, - 0x2a, 0x2a, 0x2a, - 0x0, 0x0, 0x15, - 0x0, 0x0, 0x3f, - 0x0, 0x2a, 0x15, - 0x0, 0x2a, 0x3f, - 0x2a, 0x0, 0x15, - 0x2a, 0x0, 0x3f, - 0x2a, 0x2a, 0x15, - 0x2a, 0x2a, 0x3f, - 0x0, 0x15, 0x0, - 0x0, 0x15, 0x2a, - 0x0, 0x3f, 0x0, - 0x0, 0x3f, 0x2a, - 0x2a, 0x15, 0x0, - 0x2a, 0x15, 0x2a, - 0x2a, 0x3f, 0x0, - 0x2a, 0x3f, 0x2a, - 0x0, 0x15, 0x15, - 0x0, 0x15, 0x3f, - 0x0, 0x3f, 0x15, - 0x0, 0x3f, 0x3f, - 0x2a, 0x15, 0x15, - 0x2a, 0x15, 0x3f, - 0x2a, 0x3f, 0x15, - 0x2a, 0x3f, 0x3f, - 0x15, 0x0, 0x0, - 0x15, 0x0, 0x2a, - 0x15, 0x2a, 0x0, - 0x15, 0x2a, 0x2a, - 0x3f, 0x0, 0x0, - 0x3f, 0x0, 0x2a, - 0x3f, 0x2a, 0x0, - 0x3f, 0x2a, 0x2a, - 0x15, 0x0, 0x15, - 0x15, 0x0, 0x3f, - 0x15, 0x2a, 0x15, - 0x15, 0x2a, 0x3f, - 0x3f, 0x0, 0x15, - 0x3f, 0x0, 0x3f, - 0x3f, 0x2a, 0x15, - 0x3f, 0x2a, 0x3f, - 0x15, 0x15, 0x0, - 0x15, 0x15, 0x2a, - 0x15, 0x3f, 0x0, - 0x15, 0x3f, 0x2a, - 0x3f, 0x15, 0x0, - 0x3f, 0x15, 0x2a, - 0x3f, 0x3f, 0x0, - 0x3f, 0x3f, 0x2a, - 0x15, 0x15, 0x15, - 0x15, 0x15, 0x3f, - 0x15, 0x3f, 0x15, - 0x15, 0x3f, 0x3f, - 0x3f, 0x15, 0x15, - 0x3f, 0x15, 0x3f, - 0x3f, 0x3f, 0x15, - 0x3f, 0x3f, 0x3f, - 0x39, 0xc, 0x5, - 0x15, 0x2c, 0xf, - 0x26, 0x10, 0x3d, - 0x29, 0x29, 0x38, - 0x4, 0x1a, 0xe, - 0x2, 0x1e, 0x3a, - 0x3c, 0x25, 0x33, - 0x3c, 0xc, 0x2c, - 0x3f, 0x3, 0x2b, - 0x1c, 0x9, 0x13, - 0x25, 0x2a, 0x35, - 0x1e, 0xa, 0x38, - 0x24, 0x8, 0x3, - 0x3, 0xe, 0x36, - 0xc, 0x6, 0x2a, - 0x26, 0x3, 0x32, - 0x5, 0x2f, 0x33, - 0x3c, 0x35, 0x2f, - 0x2d, 0x26, 0x3e, - 0xd, 0xa, 0x10, - 0x25, 0x3c, 0x11, - 0xd, 0x4, 0x2e, - 0x5, 0x19, 0x3e, - 0xc, 0x13, 0x34, - 0x2b, 0x6, 0x24, - 0x4, 0x3, 0xd, - 0x2f, 0x3c, 0xc, - 0x2a, 0x37, 0x1f, - 0xf, 0x12, 0x38, - 0x38, 0xe, 0x2a, - 0x12, 0x2f, 0x19, - 0x29, 0x2e, 0x31, - 0x25, 0x13, 0x3e, - 0x33, 0x3e, 0x33, - 0x1d, 0x2c, 0x25, - 0x15, 0x15, 0x5, - 0x32, 0x25, 0x39, - 0x1a, 0x7, 0x1f, - 0x13, 0xe, 0x1d, - 0x36, 0x17, 0x34, - 0xf, 0x15, 0x23, - 0x2, 0x35, 0xd, - 0x15, 0x3f, 0xc, - 0x14, 0x2f, 0xf, - 0x19, 0x21, 0x3e, - 0x27, 0x11, 0x2f, - 0x38, 0x3f, 0x3c, - 0x36, 0x2d, 0x15, - 0x16, 0x17, 0x2, - 0x1, 0xa, 0x3d, - 0x1b, 0x11, 0x3f, - 0x21, 0x3c, 0xd, - 0x1a, 0x39, 0x3d, - 0x8, 0xe, 0xe, - 0x22, 0x21, 0x23, - 0x1e, 0x30, 0x5, - 0x1f, 0x22, 0x3d, - 0x1e, 0x2f, 0xa, - 0x0, 0x1c, 0xe, - 0x0, 0x1c, 0x15, - 0x0, 0x1c, 0x1c, - 0x0, 0x15, 0x1c, - 0x0, 0xe, 0x1c, - 0x0, 0x7, 0x1c, - 0xe, 0xe, 0x1c, - 0x11, 0xe, 0x1c, - 0x15, 0xe, 0x1c, - 0x18, 0xe, 0x1c, - 0x1c, 0xe, 0x1c, - 0x1c, 0xe, 0x18, - 0x1c, 0xe, 0x15, - 0x1c, 0xe, 0x11, - 0x1c, 0xe, 0xe, - 0x1c, 0x11, 0xe, - 0x1c, 0x15, 0xe, - 0x1c, 0x18, 0xe, - 0x1c, 0x1c, 0xe, - 0x18, 0x1c, 0xe, - 0x15, 0x1c, 0xe, - 0x11, 0x1c, 0xe, - 0xe, 0x1c, 0xe, - 0xe, 0x1c, 0x11, - 0xe, 0x1c, 0x15, - 0xe, 0x1c, 0x18, - 0xe, 0x1c, 0x1c, - 0xe, 0x18, 0x1c, - 0xe, 0x15, 0x1c, - 0xe, 0x11, 0x1c, - 0x14, 0x14, 0x1c, - 0x16, 0x14, 0x1c, - 0x18, 0x14, 0x1c, - 0x1a, 0x14, 0x1c, - 0x1c, 0x14, 0x1c, - 0x1c, 0x14, 0x1a, - 0x1c, 0x14, 0x18, - 0x1c, 0x14, 0x16, - 0x1c, 0x14, 0x14, - 0x1c, 0x16, 0x14, - 0x1c, 0x18, 0x14, - 0x1c, 0x1a, 0x14, - 0x1c, 0x1c, 0x14, - 0x1a, 0x1c, 0x14, - 0x18, 0x1c, 0x14, - 0x16, 0x1c, 0x14, - 0x14, 0x1c, 0x14, - 0x14, 0x1c, 0x16, - 0x14, 0x1c, 0x18, - 0x14, 0x1c, 0x1a, - 0x14, 0x1c, 0x1c, - 0x14, 0x1a, 0x1c, - 0x14, 0x18, 0x1c, - 0x14, 0x16, 0x1c, - 0x0, 0x0, 0x10, - 0x4, 0x0, 0x10, - 0x8, 0x0, 0x10, - 0xc, 0x0, 0x10, - 0x10, 0x0, 0x10, - 0x10, 0x0, 0xc, - 0x10, 0x0, 0x8, - 0x10, 0x0, 0x4, - 0x10, 0x0, 0x0, - 0x10, 0x4, 0x0, - 0x10, 0x8, 0x0, - 0x10, 0xc, 0x0, - 0x10, 0x10, 0x0, - 0xc, 0x10, 0x0, - 0x8, 0x10, 0x0, - 0x4, 0x10, 0x0, - 0x0, 0x10, 0x0, - 0x0, 0x10, 0x4, - 0x0, 0x10, 0x8, - 0x0, 0x10, 0xc, - 0x0, 0x10, 0x10, - 0x0, 0xc, 0x10, - 0x0, 0x8, 0x10, - 0x0, 0x4, 0x10, - 0x8, 0x8, 0x10, - 0xa, 0x8, 0x10, - 0xc, 0x8, 0x10, - 0xe, 0x8, 0x10, - 0x10, 0x8, 0x10, - 0x10, 0x8, 0xe, - 0x10, 0x8, 0xc, - 0x10, 0x8, 0xa, - 0x10, 0x8, 0x8, - 0x10, 0xa, 0x8, - 0x10, 0xc, 0x8, - 0x10, 0xe, 0x8, - 0x10, 0x10, 0x8, - 0xe, 0x10, 0x8, - 0xc, 0x10, 0x8, - 0xa, 0x10, 0x8, - 0x8, 0x10, 0x8, - 0x8, 0x10, 0xa, - 0x8, 0x10, 0xc, - 0x8, 0x10, 0xe, - 0x8, 0x10, 0x10, - 0x8, 0xe, 0x10, - 0x8, 0xc, 0x10, - 0x8, 0xa, 0x10, - 0xb, 0xb, 0x10, - 0xc, 0xb, 0x10, - 0xd, 0xb, 0x10, - 0xf, 0xb, 0x10, - 0x10, 0xb, 0x10, - 0x10, 0xb, 0xf, - 0x10, 0xb, 0xd, - 0x10, 0xb, 0xc, - 0x10, 0xb, 0xb, - 0x10, 0xc, 0xb, - 0x10, 0xd, 0xb, - 0x10, 0xf, 0xb, - 0x10, 0x10, 0xb, - 0xf, 0x10, 0xb, - 0xd, 0x10, 0xb, - 0xc, 0x10, 0xb, - 0xb, 0x10, 0xb, - 0xb, 0x10, 0xc, - 0xb, 0x10, 0xd, - 0xb, 0x10, 0xf, - 0xb, 0x10, 0x10, - 0xb, 0xf, 0x10, - 0xb, 0xd, 0x10, - 0xb, 0xc, 0x10, - 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0 -}; - -unsigned char AC[21] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, - 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, - 0x0C, 0x00, 0x0F, 0x08, 0x00}; - -static int scanPCI(int start_slt); -static int PCIVendor(int); -static void printslots(void); -extern void puthex(unsigned long); -extern void puts(const char *); -static void unlockS3(void); - -static inline -outw(int port, unsigned short val) -{ - outb(port, val >> 8); - outb(port+1, val); -} - -#define PPC_601 1 - -vga_init(unsigned char *ISA_mem) -{ - int slot; - struct VgaRegs *VgaTextRegs; -#if 0 - if ((_get_PVR()>>16) == PPC_601) { - return(old_vga_init(ISA_mem)); - } -#endif - - /* See if VGA already in TEXT mode - exit if so! */ - outb(0x3CE, 0x06); - if ((inb(0x3CF) & 0x01) == 0){puts("VGA already in text mode\n"); return;} - - /* If no VGA responding in text mode, then we have some work to do... - */ - slot = -1; - while((slot = scanPCI(slot)) > -1) { /* find video card in use */ - unlockVideo(slot); /* enable I/O to card */ - VgaTextRegs = GenVgaTextRegs; - - switch (PCIVendor(slot)) { - default: - break; - case(S3Vendor): - unlockS3(); - VgaTextRegs = S3TextRegs; - break; - - case(CirrusVendor): - outw(0x3C4, 0x0612); /* unlock ext regs */ - outw(0x3C4, 0x0700); /* reset ext sequence mode */ - break; - - case(ParadiseVendor): /* IBM Portable 850 */ - outw(0x3ce, 0x0f05); /* unlock pardise registers */ - outw(0x3c4, 0x0648); - outw(0x3d4, 0x2985); - outw(0x3d4, 0x34a6); - outb(0x3ce, 0x0b); /* disable linear addressing */ - outb(0x3cf, inb(0x3cf) & ~0x30); - outw(0x3c4, 0x1400); - outb(0x3ce, 0x0e); /* disable 256 color mode */ - outb(0x3cf, inb(0x3cf) & ~0x01); - outb(0xd00, 0xff); /* enable auto-centering */ - if (!(inb(0xd01) & 0x03)) { - outb(0x3d4, 0x33); - outb(0x3d5, inb(0x3d5) & ~0x90); - outb(0x3d4, 0x32); - outb(0x3d5, inb(0x3d5) | 0x04); - outw(0x3d4, 0x0250); - outw(0x3d4, 0x07ba); - outw(0x3d4, 0x0900); - outw(0x3d4, 0x15e7); - outw(0x3d4, 0x2a95); - } - outw(0x3d4, 0x34a0); - break; - - #if 0 /* Untested - probably doesn't work */ - case(MatroxVendor): - case(DiamondVendor): - puts("VGA Chip Vendor ID: "); - puthex(PCIVendor(slot)); - puts("\n"); - mdelay(1000); - #endif - }; - - outw(0x3C4, 0x0120); /* disable video */ - setTextRegs(VgaTextRegs); /* initial register setup */ - setTextCLUT(0); /* load color lookup table */ - loadFont(ISA_mem); /* load font */ - setTextRegs(VgaTextRegs); /* reload registers */ - outw(0x3C4, 0x0100); /* re-enable video */ - clearVideoMemory(); - - if (PCIVendor(slot) == S3Vendor) { - outb(0x3c2, 0x63); /* MISC */ - } /* endif */ - - #ifdef DEBUG - printslots(); - mdelay(5000); - #endif - - mdelay(1000); /* give time for the video monitor to come up */ - } - return (1); /* 'CRT' I/O supported */ -} - -/* - * Write to VGA Attribute registers. - */ -writeAttr(index, data, videoOn) - unsigned char index; - unsigned char data; - unsigned char videoOn; /* video on flag */ -{ - unsigned char v; - v = inb(0x3da); /* reset attr. address toggle */ - if (videoOn) - outb(0x3c0, (index & 0x1F) | 0x20); - else - outb(0x3c0, (index & 0x1F)); - outb(0x3c0, data); -} - -setTextRegs(struct VgaRegs *svp) -{ - int i; - - /* - * saved settings - */ - while( svp->io_port != ENDMK ) { - outb(svp->io_port, svp->io_index); - outb(svp->io_port+1, svp->io_value); - svp++; - } - - outb(0x3c2, 0x67); /* MISC */ - outb(0x3c6, 0xff); /* MASK */ - - for ( i = 0; i < 0x10; i++) - writeAttr(i, AC[i], 0); /* pallete */ - writeAttr(0x10, 0x0c, 0); /* text mode */ - writeAttr(0x11, 0x00, 0); /* overscan color (border) */ - writeAttr(0x12, 0x0f, 0); /* plane enable */ - writeAttr(0x13, 0x08, 0); /* pixel panning */ - writeAttr(0x14, 0x00, 1); /* color select; video on */ -} - -setTextCLUT(int shift) -{ - int i; - - outb(0x3C6, 0xFF); - i = inb(0x3C7); - outb(0x3C8, 0); - i = inb(0x3C7); - - for ( i = 0; i < 256; i++) { - outb(0x3C9, TextCLUT[i].r << shift); - outb(0x3C9, TextCLUT[i].g << shift); - outb(0x3C9, TextCLUT[i].b << shift); - } -} - - -loadFont(unsigned char *ISA_mem) -{ - int i, j; - unsigned char *font_page = (unsigned char *) &ISA_mem[0xA0000]; - - outb(0x3C2, 0x67); - /* - * Load font - */ - i = inb(0x3DA); /* Reset Attr toggle */ - - outb(0x3C0,0x30); - outb(0x3C0, 0x01); /* graphics mode */ - - outw(0x3C4, 0x0001); /* reset sequencer */ - outw(0x3C4, 0x0204); /* write to plane 2 */ - outw(0x3C4, 0x0406); /* enable plane graphics */ - outw(0x3C4, 0x0003); /* reset sequencer */ - outw(0x3CE, 0x0402); /* read plane 2 */ - outw(0x3CE, 0x0500); /* write mode 0, read mode 0 */ - outw(0x3CE, 0x0605); /* set graphics mode */ - - for (i = 0; i < sizeof(font); i += 16) { - for (j = 0; j < 16; j++) { - __asm__ volatile("eieio"); - font_page[(2*i)+j] = font[i+j]; - } - } -} - -static void -unlockS3(void) -{ - int s3_device_id; - outw(0x3d4, 0x3848); - outw(0x3d4, 0x39a5); - outb(0x3d4, 0x2d); - s3_device_id = inb(0x3d5) << 8; - outb(0x3d4, 0x2e); - s3_device_id |= inb(0x3d5); - - if (s3_device_id != 0x8812) { - /* From the S3 manual */ - outb(0x46E8, 0x10); /* Put into setup mode */ - outb(0x3C3, 0x10); - outb(0x102, 0x01); /* Enable registers */ - outb(0x46E8, 0x08); /* Enable video */ - outb(0x3C3, 0x08); - outb(0x4AE8, 0x00); - -#if 0 - outb(0x42E8, 0x80); /* Reset graphics engine? */ -#endif - - outb(0x3D4, 0x38); /* Unlock all registers */ - outb(0x3D5, 0x48); - outb(0x3D4, 0x39); - outb(0x3D5, 0xA5); - outb(0x3D4, 0x40); - outb(0x3D5, inb(0x3D5)|0x01); - outb(0x3D4, 0x33); - outb(0x3D5, inb(0x3D5)&~0x52); - outb(0x3D4, 0x35); - outb(0x3D5, inb(0x3D5)&~0x30); - outb(0x3D4, 0x3A); - outb(0x3D5, 0x00); - outb(0x3D4, 0x53); - outb(0x3D5, 0x00); - outb(0x3D4, 0x31); - outb(0x3D5, inb(0x3D5)&~0x4B); - outb(0x3D4, 0x58); - - outb(0x3D5, 0); - - outb(0x3D4, 0x54); - outb(0x3D5, 0x38); - outb(0x3D4, 0x60); - outb(0x3D5, 0x07); - outb(0x3D4, 0x61); - outb(0x3D5, 0x80); - outb(0x3D4, 0x62); - outb(0x3D5, 0xA1); - outb(0x3D4, 0x69); /* High order bits for cursor address */ - outb(0x3D5, 0); - - outb(0x3D4, 0x32); - outb(0x3D5, inb(0x3D5)&~0x10); - } else { - outw(0x3c4, 0x0806); /* IBM Portable 860 */ - outw(0x3c4, 0x1041); - outw(0x3c4, 0x1128); - outw(0x3d4, 0x4000); - outw(0x3d4, 0x3100); - outw(0x3d4, 0x3a05); - outw(0x3d4, 0x6688); - outw(0x3d4, 0x5800); /* disable linear addressing */ - outw(0x3d4, 0x4500); /* disable H/W cursor */ - outw(0x3c4, 0x5410); /* enable auto-centering */ - outw(0x3c4, 0x561f); - outw(0x3c4, 0x1b80); /* lock DCLK selection */ - outw(0x3d4, 0x3900); /* lock S3 registers */ - outw(0x3d4, 0x3800); - } /* endif */ -} - -/* - * cursor() sets an offset (0-1999) into the 80x25 text area - */ -void -cursor(int x, int y) -{ - int pos = (y*cols)+x; - outb(0x3D4, 14); - outb(0x3D5, pos >> 8); - outb(0x3D4, 15); - outb(0x3D5, pos); -} - -clearVideoMemory() -{ - int i, j; - for (i = 0; i < lines; i++) { - for (j = 0; j < cols; j++) { - vidmem[((i*cols)+j)*2] = 0x20; /* fill with space character */ - vidmem[((i*cols)+j)*2+1] = 0x07; /* set bg & fg attributes */ - } - } -} - -/* ============ */ - - -#define NSLOTS 8 -#define NPCIREGS 5 - - -/* - should use devfunc number/indirect method to be totally safe on - all machines, this works for now on 3 slot Moto boxes -*/ - -struct PCI_ConfigInfo { - unsigned long * config_addr; - unsigned long regs[NPCIREGS]; -} PCI_slots [NSLOTS] = { - - { (unsigned long *)0x80808000, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80800800, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80801000, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80802000, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80804000, 0xDEADBEEF }, /* onboard */ - { (unsigned long *)0x80810000, 0xDEADBEEF }, /* slot A/1 */ - { (unsigned long *)0x80820000, 0xDEADBEEF }, /* slot B/2 */ - { (unsigned long *)0x80840000, 0xDEADBEEF } /* slot C/3 */ -}; - - - -/* - * The following code modifies the PCI Command register - * to enable memory and I/O accesses. - */ -unlockVideo(slot) -{ - volatile unsigned char * ppci; - - ppci = (unsigned char * )PCI_slots[slot].config_addr; - ppci[4] = 0x0003; /* enable memory and I/O accesses */ - ppci[0x10] = 0x00000; /* turn off memory mapping */ - ppci[0x11] = 0x00000; /* mem_base = 0 */ - ppci[0x12] = 0x00000; - ppci[0x13] = 0x00000; - __asm__ volatile("eieio"); - - outb(0x3d4, 0x11); - outb(0x3d5, 0x0e); /* unlock CR0-CR7 */ -} - -long -SwapBytes(long lv) /* turn little endian into big indian long */ -{ - long t; - t = (lv&0x000000FF) << 24; - t |= (lv&0x0000FF00) << 8; - t |= (lv&0x00FF0000) >> 8; - t |= (lv&0xFF000000) >> 24; - return(t); -} - - -#define DEVID 0 -#define CMD 1 -#define CLASS 2 -#define MEMBASE 4 - -int -scanPCI(int start_slt) -{ - int slt, r; - struct PCI_ConfigInfo *pslot; - int theSlot = -1; - int highVgaSlot = 0; - - for ( slt = start_slt + 1; slt < NSLOTS; slt++) { - pslot = &PCI_slots[slt]; - for ( r = 0; r < NPCIREGS; r++) { - pslot->regs[r] = SwapBytes ( pslot->config_addr[r] ); - } - /* card in slot ? */ - if ( pslot->regs[DEVID] != 0xFFFFFFFF ) { - /* VGA ? */ - if ( ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x03000000) || - ((pslot->regs[CLASS] & 0xFFFFFF00) == 0x00010000)) { - highVgaSlot = slt; - /* did firmware enable it ? */ - if ( (pslot->regs[CMD] & 0x03) ) { - theSlot = slt; - break; - } - } - } - } - - return ( theSlot ); -} - -/* return Vendor ID of card in the slot */ -static -int PCIVendor(int slotnum) { - struct PCI_ConfigInfo *pslot; - - pslot = &PCI_slots[slotnum]; - -return (pslot->regs[DEVID] & 0xFFFF); -} - -static -void printslots(void) -{ - int i; - struct PCI_ConfigInfo *pslot; - for(i=0; i < NSLOTS; i++) { -#if 0 - pslot = &PCI_slots[i]; - printf("Slot: %d, Addr: %x, Vendor: %08x, Class: %08x\n", - i, pslot->config_addr, pslot->regs[0], pslot->regs[2]); -#else - puts("PCI Slot number: "); puthex(i); - puts(" Vendor ID: "); - puthex(PCIVendor(i)); puts("\n"); -#endif - } -} 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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/chrpboot/Makefile b/arch/ppc/chrpboot/Makefile --- a/arch/ppc/chrpboot/Makefile Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,101 +0,0 @@ -# Makefile for making ELF bootable images for booting on CHRP -# using Open Firmware. -# -# Geert Uytterhoeven September 1997 -# -# Based on coffboot by Paul Mackerras - -ifeq ($(CONFIG_PPC64BRIDGE),y) -MSIZE=.64 -AFLAGS += -Wa,-mppc64bridge -else -MSIZE= -endif - -.c.o: - $(CC) $(CFLAGS) -DKERNELBASE=$(KERNELBASE) -c -o $*.o $< -.S.o: - $(CC) $(AFLAGS) -traditional -c -o $*.o $< - -CFLAGS = $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS -LD_ARGS = -Ttext 0x00400000 - -OBJS = crt0.o start.o main.o misc.o ../coffboot/string.o ../coffboot/zlib.o image.o -LIBS = $(TOPDIR)/lib/lib.a - -ifeq ($(CONFIG_SMP),y) -TFTPIMAGE=/tftpboot/zImage.chrp.smp$(MSIZE) -else -TFTPIMAGE=/tftpboot/zImage.chrp$(MSIZE) -endif - -all: $(TOPDIR)/zImage - -# -# Only build anything here if we're configured for ALL_PPC -# -- cort -# -ifeq ($(CONFIG_ALL_PPC),y) -znetboot: zImage - cp zImage $(TFTPIMAGE) - -znetboot.initrd: zImage.initrd - cp zImage.initrd $(TFTPIMAGE) - -floppy: zImage - mcopy zImage a:zImage - -piggyback: piggyback.c - $(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c - -addnote: addnote.c - $(HOSTCC) $(HOSTCFLAGS) -o addnote addnote.c - -image.o: piggyback ../coffboot/vmlinux.gz - ./piggyback image < ../coffboot/vmlinux.gz | $(AS) -o image.o - -sysmap.o: piggyback ../../../System.map - ./piggyback sysmap < ../../../System.map | $(AS) -o sysmap.o - -initrd.o: ramdisk.image.gz piggyback - ./piggyback initrd < ramdisk.image.gz | $(AS) -o initrd.o - -zImage: $(OBJS) no_initrd.o addnote - $(LD) $(LD_ARGS) -o $@ $(OBJS) no_initrd.o $(LIBS) - cp $@ $@.rs6k - ./addnote $@.rs6k - -zImage.initrd: $(OBJS) initrd.o addnote - $(LD) $(LD_ARGS) -o $@ $(OBJS) initrd.o $(LIBS) - cp $@ $@.rs6k - ./addnote $@.rs6k - -else -znetboot: - -znetboot.initrd: - -floppy: - -zImage: - -zImage.initrd: - -endif - -# just here to match coffboot/Makefile -vmlinux.coff: - -vmlinux.coff.initrd: - - -clean: - rm -f piggyback note addnote $(OBJS) zImage - rm -f zImage.rs6k zImage.initrd zImage.initrd.rs6k - -fastdep: - $(TOPDIR)/scripts/mkdep *.[Sch] > .depend - -dep: - $(CPP) $(CPPFLAGS) -M *.S *.c > .depend - diff -Nru a/arch/ppc/chrpboot/addnote.c b/arch/ppc/chrpboot/addnote.c --- a/arch/ppc/chrpboot/addnote.c Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,174 +0,0 @@ -/* - * Program to hack in a PT_NOTE program header entry in an ELF file. - * This is needed for OF on RS/6000s to load an image correctly. - * Note that OF needs a program header entry for the note, not an - * ELF section. - * - * Copyright 2000 Paul Mackerras. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Usage: addnote zImage - */ -#include -#include -#include -#include - -char arch[] = "PowerPC"; - -#define N_DESCR 6 -unsigned int descr[N_DESCR] = { -#if 1 - /* values for IBM RS/6000 machines */ - 0xffffffff, /* real-mode = true */ - 0x00c00000, /* real-base, i.e. where we expect OF to be */ - 0xffffffff, /* real-size */ - 0xffffffff, /* virt-base */ - 0xffffffff, /* virt-size */ - 0x4000, /* load-base */ -#else - /* values for longtrail CHRP */ - 0, /* real-mode = false */ - 0xffffffff, /* real-base */ - 0xffffffff, /* real-size */ - 0xffffffff, /* virt-base */ - 0xffffffff, /* virt-size */ - 0x00600000, /* load-base */ -#endif -}; - -unsigned char buf[512]; - -#define GET_16BE(off) ((buf[off] << 8) + (buf[(off)+1])) -#define GET_32BE(off) ((GET_16BE(off) << 16) + GET_16BE((off)+2)) - -#define PUT_16BE(off, v) (buf[off] = ((v) >> 8) & 0xff, \ - buf[(off) + 1] = (v) & 0xff) -#define PUT_32BE(off, v) (PUT_16BE((off), (v) >> 16), \ - PUT_16BE((off) + 2, (v))) - -/* Structure of an ELF file */ -#define E_IDENT 0 /* ELF header */ -#define E_PHOFF 28 -#define E_PHENTSIZE 42 -#define E_PHNUM 44 -#define E_HSIZE 52 /* size of ELF header */ - -#define EI_MAGIC 0 /* offsets in E_IDENT area */ -#define EI_CLASS 4 -#define EI_DATA 5 - -#define PH_TYPE 0 /* ELF program header */ -#define PH_OFFSET 4 -#define PH_FILESZ 16 -#define PH_HSIZE 32 /* size of program header */ - -#define PT_NOTE 4 /* Program header type = note */ - -#define ELFCLASS32 1 -#define ELFDATA2MSB 2 - -unsigned char elf_magic[4] = { 0x7f, 'E', 'L', 'F' }; - -int main(int ac, char **av) -{ - int fd, n, i; - int ph, ps, np; - int nnote, ns; - - if (ac != 2) { - fprintf(stderr, "Usage: %s elf-file\n", av[0]); - exit(1); - } - fd = open(av[1], O_RDWR); - if (fd < 0) { - perror(av[1]); - exit(1); - } - - nnote = strlen(arch) + 1 + (N_DESCR + 3) * 4; - - n = read(fd, buf, sizeof(buf)); - if (n < 0) { - perror("read"); - exit(1); - } - - if (n < E_HSIZE || memcmp(&buf[E_IDENT+EI_MAGIC], elf_magic, 4) != 0) - goto notelf; - - if (buf[E_IDENT+EI_CLASS] != ELFCLASS32 - || buf[E_IDENT+EI_DATA] != ELFDATA2MSB) { - fprintf(stderr, "%s is not a big-endian 32-bit ELF image\n", - av[1]); - exit(1); - } - - ph = GET_32BE(E_PHOFF); - ps = GET_16BE(E_PHENTSIZE); - np = GET_16BE(E_PHNUM); - if (ph < E_HSIZE || ps < PH_HSIZE || np < 1) - goto notelf; - if (ph + (np + 1) * ps + nnote > n) - goto nospace; - - for (i = 0; i < np; ++i) { - if (GET_32BE(ph + PH_TYPE) == PT_NOTE) { - fprintf(stderr, "%s already has a note entry\n", - av[1]); - exit(0); - } - ph += ps; - } - - /* XXX check that the area we want to use is all zeroes */ - for (i = 0; i < ps + nnote; ++i) - if (buf[ph + i] != 0) - goto nospace; - - /* fill in the program header entry */ - ns = ph + ps; - PUT_32BE(ph + PH_TYPE, PT_NOTE); - PUT_32BE(ph + PH_OFFSET, ns); - PUT_32BE(ph + PH_FILESZ, nnote); - - /* fill in the note area we point to */ - /* XXX we should probably make this a proper section */ - PUT_32BE(ns, strlen(arch) + 1); - PUT_32BE(ns + 4, N_DESCR * 4); - PUT_32BE(ns + 8, 0x1275); - strcpy(&buf[ns + 12], arch); - ns += 12 + strlen(arch) + 1; - for (i = 0; i < N_DESCR; ++i) - PUT_32BE(ns + i * 4, descr[i]); - - /* Update the number of program headers */ - PUT_16BE(E_PHNUM, np + 1); - - /* write back */ - lseek(fd, (long) 0, SEEK_SET); - i = write(fd, buf, n); - if (i < 0) { - perror("write"); - exit(1); - } - if (i < n) { - fprintf(stderr, "%s: write truncated\n", av[1]); - exit(1); - } - - exit(0); - - notelf: - fprintf(stderr, "%s does not appear to be an ELF file\n", av[0]); - exit(1); - - nospace: - fprintf(stderr, "sorry, I can't find space in %s to put the note\n", - av[0]); - exit(1); -} diff -Nru a/arch/ppc/chrpboot/crt0.S b/arch/ppc/chrpboot/crt0.S --- a/arch/ppc/chrpboot/crt0.S Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,20 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - .text - .globl _start -_start: - lis 9,_start@h - lis 8,_etext@ha - addi 8,8,_etext@l -1: dcbf 0,9 - icbi 0,9 - addi 9,9,0x20 - cmplwi 0,9,8 - blt 1b - b start diff -Nru a/arch/ppc/chrpboot/main.c b/arch/ppc/chrpboot/main.c --- a/arch/ppc/chrpboot/main.c Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,195 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include "../coffboot/nonstdio.h" -#include "../coffboot/zlib.h" -#include -#include -#include - -extern void *finddevice(const char *); -extern int getprop(void *, const char *, void *, int); -void gunzip(void *, int, unsigned char *, int *); - -#define RAM_START 0x00000000 -#define RAM_END (64<<20) - -#define BOOT_START ((unsigned long)_start) -#define BOOT_END ((unsigned long)(_end + 0xFFF) & ~0xFFF) - -#define RAM_FREE ((unsigned long)(_end+0x1000)&~0xFFF) -#define PROG_START 0x00010000 - -char *avail_ram; -char *end_avail; - -extern char _end[]; -extern char image_data[]; -extern int image_len; -extern char initrd_data[]; -extern int initrd_len; -extern char sysmap_data[]; -extern int sysmap_len; - -static char scratch[1024<<10]; /* 1MB of scratch space for gunzip */ - -chrpboot(int a1, int a2, void *prom) -{ - int ns, oh, i; - unsigned sa, len; - void *dst; - unsigned char *im; - unsigned initrd_start, initrd_size; - extern char _start; - - printf("chrpboot starting: loaded at 0x%x\n\r", &_start); - - if (initrd_len) { - initrd_size = initrd_len; - initrd_start = (RAM_END - initrd_size) & ~0xFFF; - a1 = initrd_start; - a2 = initrd_size; - claim(initrd_start, RAM_END - initrd_start, 0); - printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n\r", - initrd_start, initrd_data, initrd_size); - memcpy((char *)initrd_start, initrd_data, initrd_size); - } - - im = image_data; - len = image_len; - /* claim 4MB starting at PROG_START */ - claim(PROG_START, (4<<20) - PROG_START, 0); - dst = (void *) PROG_START; - if (im[0] == 0x1f && im[1] == 0x8b) { - avail_ram = scratch; - end_avail = scratch + sizeof(scratch); - printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); - gunzip(dst, 0x400000, im, &len); - printf("done %u bytes\n\r", len); - } else { - memmove(dst, im, len); - } - - flush_cache(dst, len); - - sa = (unsigned long)PROG_START; - printf("start address = 0x%x\n\r", sa); - - { - struct bi_record *rec; - - rec = (struct bi_record *)_ALIGN((unsigned long)dst+len+(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; - sprintf( (char *)rec->data, "chrpboot"); - rec->size = sizeof(struct bi_record) + strlen("chrpboot") + 1; - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_MACHTYPE; - rec->data[0] = _MACH_chrp; - rec->data[1] = 1; - rec->size = sizeof(struct bi_record) + sizeof(unsigned long); - rec = (struct bi_record *)((unsigned long)rec + rec->size); -#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 = (struct bi_record *)((unsigned long)rec + rec->size); -#endif - rec->tag = BI_LAST; - rec->size = sizeof(struct bi_record); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - } - (*(void (*)())sa)(a1, a2, prom); - - printf("returned?\n\r"); - - pause(); -} - -void *zalloc(void *x, unsigned items, unsigned size) -{ - void *p = avail_ram; - - size *= items; - size = (size + 7) & -8; - avail_ram += size; - if (avail_ram > end_avail) { - printf("oops... out of memory\n\r"); - pause(); - } - return p; -} - -void zfree(void *x, void *addr, unsigned nb) -{ - nb = (nb + 7) & -8; - if (addr == (avail_ram - nb)) { - avail_ram -= nb; - } -} - -#define HEAD_CRC 2 -#define EXTRA_FIELD 4 -#define ORIG_NAME 8 -#define COMMENT 0x10 -#define RESERVED 0xe0 - -#define DEFLATED 8 - -void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) -{ - z_stream s; - int r, i, flags; - - /* skip header */ - i = 10; - flags = src[3]; - if (src[2] != DEFLATED || (flags & RESERVED) != 0) { - printf("bad gzipped data\n\r"); - exit(); - } - if ((flags & EXTRA_FIELD) != 0) - i = 12 + src[10] + (src[11] << 8); - if ((flags & ORIG_NAME) != 0) - while (src[i++] != 0) - ; - if ((flags & COMMENT) != 0) - while (src[i++] != 0) - ; - if ((flags & HEAD_CRC) != 0) - i += 2; - if (i >= *lenp) { - printf("gunzip: ran out of data in header\n\r"); - exit(); - } - - s.zalloc = zalloc; - s.zfree = zfree; - r = inflateInit2(&s, -MAX_WBITS); - if (r != Z_OK) { - printf("inflateInit2 returned %d\n\r", r); - exit(); - } - s.next_in = src + i; - s.avail_in = *lenp - i; - s.next_out = dst; - s.avail_out = dstlen; - r = inflate(&s, Z_FINISH); - if (r != Z_OK && r != Z_STREAM_END) { - printf("inflate returned %d msg: %s\n\r", r, s.msg); - exit(); - } - *lenp = s.next_out - (unsigned char *) dst; - inflateEnd(&s); -} diff -Nru a/arch/ppc/chrpboot/misc.S b/arch/ppc/chrpboot/misc.S --- a/arch/ppc/chrpboot/misc.S Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,50 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - .text - -/* - * Use the BAT0 registers to map the 1st 8MB of RAM to 0x90000000. - */ - .globl setup_bats -setup_bats: - mfpvr 3 - rlwinm 3,3,16,16,31 /* r3 = 1 for 601, 4 for 604 */ - cmpi 0,3,1 - lis 4,0x9000 - bne 4f - ori 4,4,4 /* set up BAT registers for 601 */ - li 5,0x7f - b 5f -4: ori 4,4,0xff /* set up BAT registers for 604 */ - li 5,2 - mtdbatu 3,4 - mtdbatl 3,5 -5: mtibatu 3,4 - mtibatl 3,5 - isync - blr - -/* - * Flush the dcache and invalidate the icache for a range of addresses. - * - * flush_cache(addr, len) - */ - .global flush_cache -flush_cache: - addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ - rlwinm. 4,4,27,5,31 - mtctr 4 - beqlr -1: dcbf 0,3 - icbi 0,3 - addi 3,3,0x20 - bdnz 1b - sync - isync - blr diff -Nru a/arch/ppc/chrpboot/mknote.c b/arch/ppc/chrpboot/mknote.c --- a/arch/ppc/chrpboot/mknote.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,43 +0,0 @@ -/* - * Copyright (C) Cort Dougan 1999. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Generate a note section as per the CHRP specification. - * - */ - -#include - -#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); - -int main(void) -{ -/* header */ - /* namesz */ - PL(strlen("PowerPC")+1); - /* descrsz */ - PL(6*4); - /* type */ - PL(0x1275); - /* name */ - printf("PowerPC"); printf("%c", 0); - -/* descriptor */ - /* real-mode */ - PL(0xffffffff); - /* real-base */ - PL(0x00c00000); - /* real-size */ - PL(0xffffffff); - /* virt-base */ - PL(0xffffffff); - /* virt-size */ - PL(0xffffffff); - /* load-base */ - PL(0x4000); - return 0; -} diff -Nru a/arch/ppc/chrpboot/no_initrd.c b/arch/ppc/chrpboot/no_initrd.c --- a/arch/ppc/chrpboot/no_initrd.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,2 +0,0 @@ -char initrd_data[1]; -int initrd_len = 0; diff -Nru a/arch/ppc/chrpboot/piggyback.c b/arch/ppc/chrpboot/piggyback.c --- a/arch/ppc/chrpboot/piggyback.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,66 +0,0 @@ -#include -#include - -extern long ce_exec_config[]; - -int main(int argc, char *argv[]) -{ - int i, cnt, pos, len; - unsigned int cksum, val; - unsigned char *lp; - unsigned char buf[8192]; - if (argc != 2) - { - fprintf(stderr, "usage: %s name out-file\n", - argv[0]); - exit(1); - } - fprintf(stdout, "#\n"); - fprintf(stdout, "# Miscellaneous data structures:\n"); - fprintf(stdout, "# WARNING - this file is automatically generated!\n"); - fprintf(stdout, "#\n"); - fprintf(stdout, "\n"); - fprintf(stdout, "\t.data\n"); - fprintf(stdout, "\t.globl %s_data\n", argv[1]); - fprintf(stdout, "%s_data:\n", argv[1]); - pos = 0; - cksum = 0; - while ((len = read(0, buf, sizeof(buf))) > 0) - { - cnt = 0; - lp = (unsigned char *)buf; - len = (len + 3) & ~3; /* Round up to longwords */ - for (i = 0; i < len; i += 4) - { - if (cnt == 0) - { - fprintf(stdout, "\t.long\t"); - } - fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); - val = *(unsigned long *)lp; - cksum ^= val; - lp += 4; - if (++cnt == 4) - { - cnt = 0; - fprintf(stdout, " # %x \n", pos+i-12); - fflush(stdout); - } else - { - fprintf(stdout, ","); - } - } - if (cnt) - { - fprintf(stdout, "0\n"); - } - pos += len; - } - fprintf(stdout, "\t.globl %s_len\n", argv[1]); - fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos); - fflush(stdout); - fclose(stdout); - fprintf(stderr, "cksum = %x\n", cksum); - exit(0); -} - diff -Nru a/arch/ppc/chrpboot/start.c b/arch/ppc/chrpboot/start.c --- a/arch/ppc/chrpboot/start.c Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,305 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include - -int (*prom)(); - -void *chosen_handle; -void *stdin; -void *stdout; -void *stderr; - -void exit(void); -void *finddevice(const char *name); -int getprop(void *phandle, const char *name, void *buf, int buflen); - -void printk(char *fmt, ...); - -void -start(int a1, int a2, void *promptr) -{ - prom = (int (*)()) promptr; - chosen_handle = finddevice("/chosen"); - if (chosen_handle == (void *) -1) - exit(); - if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) - exit(); - stderr = stdout; - if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) - exit(); - - chrpboot(a1, a2, promptr); - for (;;) - exit(); -} - -int -write(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "write"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - -int -read(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "read"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - -void -exit() -{ - struct prom_args { - char *service; - } args; - - for (;;) { - args.service = "exit"; - (*prom)(&args); - } -} - -void -pause() -{ - struct prom_args { - char *service; - } args; - - args.service = "enter"; - (*prom)(&args); -} - -void * -finddevice(const char *name) -{ - struct prom_args { - char *service; - int nargs; - int nret; - const char *devspec; - void *phandle; - } args; - - args.service = "finddevice"; - args.nargs = 1; - args.nret = 1; - args.devspec = name; - args.phandle = (void *) -1; - (*prom)(&args); - return args.phandle; -} - -void * -claim(unsigned int virt, unsigned int size, unsigned int align) -{ - struct prom_args { - char *service; - int nargs; - int nret; - unsigned int virt; - unsigned int size; - unsigned int align; - void *ret; - } args; - - args.service = "claim"; - args.nargs = 3; - args.nret = 1; - args.virt = virt; - args.size = size; - args.align = align; - (*prom)(&args); - return args.ret; -} - -int -getprop(void *phandle, const char *name, void *buf, int buflen) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *phandle; - const char *name; - void *buf; - int buflen; - int size; - } args; - - args.service = "getprop"; - args.nargs = 4; - args.nret = 1; - args.phandle = phandle; - args.name = name; - args.buf = buf; - args.buflen = buflen; - args.size = -1; - (*prom)(&args); - return args.size; -} - -int -putc(int c, void *f) -{ - char ch = c; - - if (c == '\n') - putc('\r', f); - return write(f, &ch, 1) == 1? c: -1; -} - -int -putchar(int c) -{ - return putc(c, stdout); -} - -int -fputs(char *str, void *f) -{ - int n = strlen(str); - - return write(f, str, n) == n? 0: -1; -} - -int -readchar() -{ - char ch; - - for (;;) { - switch (read(stdin, &ch, 1)) { - case 1: - return ch; - case -1: - printk("read(stdin) returned -1\r\n"); - return -1; - } - } -} - -static char line[256]; -static char *lineptr; -static int lineleft; - -int -getchar() -{ - int c; - - if (lineleft == 0) { - lineptr = line; - for (;;) { - c = readchar(); - if (c == -1 || c == 4) - break; - if (c == '\r' || c == '\n') { - *lineptr++ = '\n'; - putchar('\n'); - break; - } - switch (c) { - case 0177: - case '\b': - if (lineptr > line) { - putchar('\b'); - putchar(' '); - putchar('\b'); - --lineptr; - } - break; - case 'U' & 0x1F: - while (lineptr > line) { - putchar('\b'); - putchar(' '); - putchar('\b'); - --lineptr; - } - break; - default: - if (lineptr >= &line[sizeof(line) - 1]) - putchar('\a'); - else { - putchar(c); - *lineptr++ = c; - } - } - } - lineleft = lineptr - line; - lineptr = line; - } - if (lineleft == 0) - return -1; - --lineleft; - return *lineptr++; -} - -extern int vsprintf(char *buf, const char *fmt, va_list args); -static char sprint_buf[1024]; - -void -printk(char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - write(stdout, sprint_buf, n); -} - -int -printf(char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - write(stdout, sprint_buf, n); - return n; -} diff -Nru a/arch/ppc/coffboot/Makefile b/arch/ppc/coffboot/Makefile --- a/arch/ppc/coffboot/Makefile Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,131 +0,0 @@ -# Makefile for making XCOFF bootable images for booting on PowerMacs -# using Open Firmware. -# -# Paul Mackerras January 1997 - -HOSTCFLAGS = -O -I$(TOPDIR)/include - -CFLAGS = $(CPPFLAGS) -O -fno-builtin -OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment -COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic -CHRP_LD_ARGS = -Ttext 0x01000000 - -COFFOBJS = coffcrt0.o start.o coffmain.o misc.o string.o zlib.o image.o -CHRPOBJS = crt0.o start.o chrpmain.o misc.o string.o zlib.o image.o -LIBS = $(TOPDIR)/lib/lib.a - -ifeq ($(CONFIG_PPC64BRIDGE),y) -MSIZE=.64 -else -MSIZE= -endif - -ifeq ($(CONFIG_SMP),y) -TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE) -else -TFTPIMAGE=/tftpboot/zImage.pmac$(MSIZE) -endif - -ifeq ($(CONFIG_ALL_PPC),y) -chrpmain.o: chrpmain.c - $(CC) $(CFLAGS) -DSYSMAP_OFFSET=0 -DSYSMAP_SIZE=0 -c chrpmain.c - -hack-coff: hack-coff.c - $(HOSTCC) $(HOSTCFLAGS) -o hack-coff hack-coff.c - -znetboot: vmlinux.coff vmlinux.elf zImage - cp vmlinux.coff $(TFTPIMAGE) - cp vmlinux.elf $(TFTPIMAGE).elf - -znetboot.initrd: vmlinux.coff.initrd vmlinux.elf.initrd - cp vmlinux.coff.initrd $(TFTPIMAGE) - cp vmlinux.elf.initrd $(TFTPIMAGE).elf - -floppy: zImage -# mount -t hfs /dev/fd0 /mnt -# cp vmlinux.coff /mnt -# umount /mnt - -miboot.image: dummy.o vmlinux.gz - $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=image=vmlinux.gz dummy.o $@ - -miboot.image.initrd: miboot.image ramdisk.image.gz - $(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=ramdisk.image.gz miboot.image $@ - -coffboot: $(COFFOBJS) no_initrd.o ld.script - $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) no_initrd.o $(LIBS) - -coffboot.initrd: $(COFFOBJS) initrd.o ld.script - $(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) initrd.o $(LIBS) - -piggyback: piggyback.c - $(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c - -mknote: mknote.c - $(HOSTCC) $(HOSTCFLAGS) -o mknote mknote.c - -image.o: piggyback vmlinux.gz - ./piggyback image < vmlinux.gz | $(AS) -o image.o - -initrd.o: ramdisk.image.gz piggyback - ./piggyback initrd < ramdisk.image.gz | $(AS) -o initrd.o - -vmlinux.coff: coffboot hack-coff - $(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@ - ./hack-coff $@ - ln -sf vmlinux.coff zImage - -vmlinux.coff.initrd: coffboot.initrd hack-coff - $(OBJCOPY) $(OBJCOPY_ARGS) coffboot.initrd $@ - ./hack-coff $@ - -vmlinux.elf: $(CHRPOBJS) no_initrd.o mknote - $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) no_initrd.o $(LIBS) - ./mknote > note - $(OBJCOPY) $@ $@ --add-section=.note=note \ - --add-section=sysmap=../../../System.map -R .comment - $(CC) $(CFLAGS) chrpmain.c -c -o chrpmain.o \ - -DSYSMAP_OFFSET=`sh ../boot/offset $(OBJDUMP) $@ sysmap` \ - -DSYSMAP_SIZE=`sh ../boot/size $(OBJDUMP) $@ sysmap` - $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) no_initrd.o $(LIBS) - $(OBJCOPY) $@ $@ --add-section=.note=note \ - --add-section=sysmap=../../../System.map -R .comment - -vmlinux.elf.initrd: $(CHRPOBJS) initrd.o mknote - $(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) initrd.o $(LIBS) - ./mknote > note - $(OBJCOPY) $@ $@ --add-section=.note=note -R .comment - -zImage: vmlinux.coff vmlinux.elf miboot.image - -zImage.initrd: vmlinux.coff.initrd vmlinux.elf.initrd miboot.image.initrd - -else -znetboot: vmlinux.gz - -znetboot.initrd: vmlinux.gz - -coffboot: vmlinux.gz - -zImage: vmlinux.gz - -zImage.initrd: vmlinux.gz - -vmlinux.coff: vmlinux.gz - -vmlinux.coff.initrd: vmlinux.gz - -floppy: vmlinux.gz - -endif - -vmlinux.gz: $(TOPDIR)/vmlinux - $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux - gzip -vf9 vmlinux - -clean: - rm -f hack-coff coffboot zImage vmlinux.coff vmlinux.gz - rm -f mknote piggyback vmlinux.elf note - rm -f miboot.image miboot.image.initrd - -fastdep: diff -Nru a/arch/ppc/coffboot/chrpmain.c b/arch/ppc/coffboot/chrpmain.c --- a/arch/ppc/coffboot/chrpmain.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,294 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include "nonstdio.h" -#include "zlib.h" -#include -#include -#include - -extern void *finddevice(const char *); -extern int getprop(void *, const char *, void *, int); -extern void *claim(unsigned int, unsigned int, unsigned int); -extern void release(void *ptr, unsigned int len); -void make_bi_recs(unsigned long); -void gunzip(void *, int, unsigned char *, int *); -void stop_imac_ethernet(void); -void stop_imac_usb(void); - -#define get_16be(x) (*(unsigned short *)(x)) -#define get_32be(x) (*(unsigned *)(x)) - -#define RAM_END (16 << 20) - -#define PROG_START 0x00010000 -#define PROG_SIZE 0x003f0000 - -#define SCRATCH_SIZE (128 << 10) - -char *avail_ram; -char *begin_avail, *end_avail; -char *avail_high; -unsigned int heap_use; -unsigned int heap_max; - -extern char _end[]; -extern char image_data[]; -extern int image_len; -extern char initrd_data[]; -extern int initrd_len; - - -boot(int a1, int a2, void *prom) -{ - int ns, oh, i; - unsigned sa, len; - void *dst; - unsigned char *im; - unsigned initrd_start, initrd_size; - extern char _start; - - printf("chrpboot starting: loaded at 0x%x\n", &_start); - if (initrd_len) { - initrd_size = initrd_len; - initrd_start = (RAM_END - initrd_size) & ~0xFFF; - a1 = initrd_start; - a2 = initrd_size; - claim(initrd_start, RAM_END - initrd_start, 0); - printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", initrd_start, - initrd_data,initrd_size); - memcpy((char *)initrd_start, initrd_data, initrd_size); - } - im = image_data; - len = image_len; - /* claim 3MB starting at PROG_START */ - claim(PROG_START, PROG_SIZE, 0); - dst = (void *) PROG_START; - if (im[0] == 0x1f && im[1] == 0x8b) { - /* claim some memory for scratch space */ - avail_ram = (char *) claim(0, SCRATCH_SIZE, 0x10); - begin_avail = avail_high = avail_ram; - end_avail = avail_ram + SCRATCH_SIZE; - printf("heap at 0x%x\n", avail_ram); - printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); - gunzip(dst, PROG_SIZE, im, &len); - printf("done %u bytes\n", len); - printf("%u bytes of heap consumed, max in use %u\n", - avail_high - begin_avail, heap_max); - release(begin_avail, SCRATCH_SIZE); - } else { - memmove(dst, im, len); - } - - flush_cache(dst, len); - make_bi_recs((unsigned long) dst + len); - - sa = (unsigned long)PROG_START; - printf("start address = 0x%x\n", sa); - - (*(void (*)())sa)(a1, a2, prom); - - printf("returned?\n"); - - pause(); -} - -void make_bi_recs(unsigned long addr) -{ - struct bi_record *rec; - - /* leave a 1MB gap then align to the next 1MB boundary */ - addr = _ALIGN(addr+ (1<<20) - 1, (1<<20)); - if (addr >= PROG_START + PROG_SIZE) - claim(addr, 0x1000, 0); - - rec = (struct bi_record *)addr; - rec->tag = BI_FIRST; - rec->size = sizeof(struct bi_record); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_BOOTLOADER_ID; - sprintf( (char *)rec->data, "coffboot"); - rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1; - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_MACHTYPE; - rec->data[0] = _MACH_Pmac; - rec->data[1] = 1; - rec->size = sizeof(struct bi_record) + sizeof(unsigned long); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - -#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 = (struct bi_record *)((unsigned long)rec + rec->size); -#endif /* SYSMAP_OFFSET */ - - rec->tag = BI_LAST; - rec->size = sizeof(struct bi_record); - rec = (struct bi_record *)((unsigned long)rec + rec->size); -} - -#if 0 -#define eieio() asm volatile("eieio"); - -void stop_imac_ethernet(void) -{ - void *macio, *enet; - unsigned int macio_addr[5], enet_reg[6]; - int len; - volatile unsigned int *dbdma; - - macio = finddevice("/pci/mac-io"); - enet = finddevice("/pci/mac-io/ethernet"); - if (macio == NULL || enet == NULL) - return; - len = getprop(macio, "assigned-addresses", macio_addr, sizeof(macio_addr)); - if (len != sizeof(macio_addr)) - return; - len = getprop(enet, "reg", enet_reg, sizeof(enet_reg)); - if (len != sizeof(enet_reg)) - return; - printf("macio base %x, dma at %x & %x\n", - macio_addr[2], enet_reg[2], enet_reg[4]); - - /* hope this is mapped... */ - dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[2]); - *dbdma = 0x80; /* clear the RUN bit */ - eieio(); - dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[4]); - *dbdma = 0x80; /* clear the RUN bit */ - eieio(); -} - -void stop_imac_usb(void) -{ - void *usb; - unsigned int usb_addr[5]; - int len; - volatile unsigned int *usb_ctrl; - - usb = finddevice("/pci/usb"); - if (usb == NULL) - return; - len = getprop(usb, "assigned-addresses", usb_addr, sizeof(usb_addr)); - if (len != sizeof(usb_addr)) - return; - printf("usb base %x\n", usb_addr[2]); - - usb_ctrl = (volatile unsigned int *) (usb_addr[2] + 8); - *usb_ctrl = 0x01000000; /* cpu_to_le32(1) */ - eieio(); -} -#endif - -struct memchunk { - unsigned int size; - struct memchunk *next; -}; - -static struct memchunk *freechunks; - -void *zalloc(void *x, unsigned items, unsigned size) -{ - void *p; - struct memchunk **mpp, *mp; - - size *= items; - size = (size + 7) & -8; - heap_use += size; - if (heap_use > heap_max) - heap_max = heap_use; - for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { - if (mp->size == size) { - *mpp = mp->next; - return mp; - } - } - p = avail_ram; - avail_ram += size; - if (avail_ram > avail_high) - avail_high = avail_ram; - if (avail_ram > end_avail) { - printf("oops... out of memory\n"); - pause(); - } - return p; -} - -void zfree(void *x, void *addr, unsigned nb) -{ - struct memchunk *mp = addr; - - nb = (nb + 7) & -8; - heap_use -= nb; - if (avail_ram == addr + nb) { - avail_ram = addr; - return; - } - mp->size = nb; - mp->next = freechunks; - freechunks = mp; -} - -#define HEAD_CRC 2 -#define EXTRA_FIELD 4 -#define ORIG_NAME 8 -#define COMMENT 0x10 -#define RESERVED 0xe0 - -#define DEFLATED 8 - -void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) -{ - z_stream s; - int r, i, flags; - - /* skip header */ - i = 10; - flags = src[3]; - if (src[2] != DEFLATED || (flags & RESERVED) != 0) { - printf("bad gzipped data\n"); - exit(); - } - if ((flags & EXTRA_FIELD) != 0) - i = 12 + src[10] + (src[11] << 8); - if ((flags & ORIG_NAME) != 0) - while (src[i++] != 0) - ; - if ((flags & COMMENT) != 0) - while (src[i++] != 0) - ; - if ((flags & HEAD_CRC) != 0) - i += 2; - if (i >= *lenp) { - printf("gunzip: ran out of data in header\n"); - exit(); - } - - s.zalloc = zalloc; - s.zfree = zfree; - r = inflateInit2(&s, -MAX_WBITS); - if (r != Z_OK) { - printf("inflateInit2 returned %d\n", r); - exit(); - } - s.next_in = src + i; - s.avail_in = *lenp - i; - s.next_out = dst; - s.avail_out = dstlen; - r = inflate(&s, Z_FINISH); - if (r != Z_OK && r != Z_STREAM_END) { - printf("inflate returned %d msg: %s\n", r, s.msg); - exit(); - } - *lenp = s.next_out - (unsigned char *) dst; - inflateEnd(&s); -} diff -Nru a/arch/ppc/coffboot/coffcrt0.S b/arch/ppc/coffboot/coffcrt0.S --- a/arch/ppc/coffboot/coffcrt0.S Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,24 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - .text - .globl _start -_start: - .long __start,0,0 - - .globl __start -__start: - lis 9,_start@h - lis 8,_etext@ha - addi 8,8,_etext@l -1: dcbf 0,9 - icbi 0,9 - addi 9,9,0x20 - cmplwi 0,9,8 - blt 1b - b start diff -Nru a/arch/ppc/coffboot/coffmain.c b/arch/ppc/coffboot/coffmain.c --- a/arch/ppc/coffboot/coffmain.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,226 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include "nonstdio.h" -#include "zlib.h" -#include -#include -#include - -extern void *finddevice(const char *); -extern int getprop(void *, const char *, void *, int); -extern char *claim(unsigned, unsigned, unsigned); -void make_bi_recs(unsigned long); -void gunzip(void *, int, unsigned char *, int *); - -#define get_16be(x) (*(unsigned short *)(x)) -#define get_32be(x) (*(unsigned *)(x)) - -#define RAM_START 0xc0000000 -#define RAM_END (RAM_START + 0x800000) /* only 8M mapped with BATs */ - -#define PROG_START RAM_START -#define PROG_SIZE 0x00400000 - -#define SCRATCH_SIZE (128 << 10) - -char *avail_ram; -char *begin_avail, *end_avail; -char *avail_high; -unsigned int heap_use; -unsigned int heap_max; - -extern char _start[], _end[]; -extern char image_data[]; -extern int image_len; -extern char initrd_data[]; -extern int initrd_len; - -char heap[SCRATCH_SIZE]; - -boot(int a1, int a2, void *prom) -{ - int ns, oh, i; - unsigned sa, len; - void *dst; - unsigned char *im; - unsigned initrd_start, initrd_size; - - printf("coffboot starting: loaded at 0x%x\n", _start); - setup_bats(RAM_START); - if (initrd_len) { - initrd_size = initrd_len; - initrd_start = (RAM_END - initrd_size) & ~0xFFF; - a1 = initrd_start; - a2 = initrd_size; - claim(initrd_start - RAM_START, RAM_END - initrd_start, 0); - printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n", - initrd_start, initrd_data, initrd_size); - memcpy((char *)initrd_start, initrd_data, initrd_size); - } - im = image_data; - len = image_len; - /* claim 3MB starting at 0 */ - claim(0, PROG_SIZE, 0); - dst = (void *) RAM_START; - if (im[0] == 0x1f && im[1] == 0x8b) { - /* claim some memory for scratch space */ - begin_avail = avail_high = avail_ram = heap; - end_avail = heap + sizeof(heap); - printf("heap at 0x%x\n", avail_ram); - printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len); - gunzip(dst, PROG_SIZE, im, &len); - printf("done %u bytes\n", len); - printf("%u bytes of heap consumed, max in use %u\n", - avail_high - begin_avail, heap_max); - } else { - memmove(dst, im, len); - } - - flush_cache(dst, len); - make_bi_recs((unsigned long)dst + len); - - sa = (unsigned long)PROG_START; - printf("start address = 0x%x\n", sa); - - (*(void (*)())sa)(a1, a2, prom); - - printf("returned?\n"); - - pause(); -} - -void make_bi_recs(unsigned long addr) -{ - struct bi_record *rec; - - rec = (struct bi_record *)PAGE_ALIGN(addr); - - rec->tag = BI_FIRST; - rec->size = sizeof(struct bi_record); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_BOOTLOADER_ID; - sprintf( (char *)rec->data, "coffboot"); - rec->size = sizeof(struct bi_record) + strlen("coffboot") + 1; - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_MACHTYPE; - rec->data[0] = _MACH_Pmac; - rec->data[1] = 1; - rec->size = sizeof(struct bi_record) + sizeof(unsigned long); - rec = (struct bi_record *)((unsigned long)rec + rec->size); - - rec->tag = BI_LAST; - rec->size = sizeof(struct bi_record); - rec = (struct bi_record *)((unsigned long)rec + rec->size); -} - -struct memchunk { - unsigned int size; - struct memchunk *next; -}; - -static struct memchunk *freechunks; - -void *zalloc(void *x, unsigned items, unsigned size) -{ - void *p; - struct memchunk **mpp, *mp; - - size *= items; - size = (size + 7) & -8; - heap_use += size; - if (heap_use > heap_max) - heap_max = heap_use; - for (mpp = &freechunks; (mp = *mpp) != 0; mpp = &mp->next) { - if (mp->size == size) { - *mpp = mp->next; - return mp; - } - } - p = avail_ram; - avail_ram += size; - if (avail_ram > avail_high) - avail_high = avail_ram; - if (avail_ram > end_avail) { - printf("oops... out of memory\n"); - pause(); - } - return p; -} - -void zfree(void *x, void *addr, unsigned nb) -{ - struct memchunk *mp = addr; - - nb = (nb + 7) & -8; - heap_use -= nb; - if (avail_ram == addr + nb) { - avail_ram = addr; - return; - } - mp->size = nb; - mp->next = freechunks; - freechunks = mp; -} - -#define HEAD_CRC 2 -#define EXTRA_FIELD 4 -#define ORIG_NAME 8 -#define COMMENT 0x10 -#define RESERVED 0xe0 - -#define DEFLATED 8 - -void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) -{ - z_stream s; - int r, i, flags; - - /* skip header */ - i = 10; - flags = src[3]; - if (src[2] != DEFLATED || (flags & RESERVED) != 0) { - printf("bad gzipped data\n"); - exit(); - } - if ((flags & EXTRA_FIELD) != 0) - i = 12 + src[10] + (src[11] << 8); - if ((flags & ORIG_NAME) != 0) - while (src[i++] != 0) - ; - if ((flags & COMMENT) != 0) - while (src[i++] != 0) - ; - if ((flags & HEAD_CRC) != 0) - i += 2; - if (i >= *lenp) { - printf("gunzip: ran out of data in header\n"); - exit(); - } - - s.zalloc = zalloc; - s.zfree = zfree; - r = inflateInit2(&s, -MAX_WBITS); - if (r != Z_OK) { - printf("inflateInit2 returned %d\n", r); - exit(); - } - s.next_in = src + i; - s.avail_in = *lenp - i; - s.next_out = dst; - s.avail_out = dstlen; - r = inflate(&s, Z_FINISH); - if (r != Z_OK && r != Z_STREAM_END) { - printf("inflate returned %d msg: %s\n", r, s.msg); - exit(); - } - *lenp = s.next_out - (unsigned char *) dst; - inflateEnd(&s); -} diff -Nru a/arch/ppc/coffboot/crt0.S b/arch/ppc/coffboot/crt0.S --- a/arch/ppc/coffboot/crt0.S Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,20 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - .text - .globl _start -_start: - lis 9,_start@h - lis 8,_etext@ha - addi 8,8,_etext@l -1: dcbf 0,9 - icbi 0,9 - addi 9,9,0x20 - cmplwi 0,9,8 - blt 1b - b start diff -Nru a/arch/ppc/coffboot/dummy.c b/arch/ppc/coffboot/dummy.c --- a/arch/ppc/coffboot/dummy.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,4 +0,0 @@ -int main(void) -{ - return 0; -} diff -Nru a/arch/ppc/coffboot/hack-coff.c b/arch/ppc/coffboot/hack-coff.c --- a/arch/ppc/coffboot/hack-coff.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,79 +0,0 @@ -/* - * hack-coff.c - hack the header of an xcoff file to fill in - * a few fields needed by the Open Firmware xcoff loader on - * Power Macs but not initialized by objcopy. - * - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include "rs6000.h" - -#define AOUT_MAGIC 0x010b - -#define get_16be(x) ((((unsigned char *)(x))[0] << 8) \ - + ((unsigned char *)(x))[1]) -#define put_16be(x, v) (((unsigned char *)(x))[0] = (v) >> 8, \ - ((unsigned char *)(x))[1] = (v) & 0xff) -#define get_32be(x) ((((unsigned char *)(x))[0] << 24) \ - + (((unsigned char *)(x))[1] << 16) \ - + (((unsigned char *)(x))[2] << 8) \ - + ((unsigned char *)(x))[3]) - -main(int ac, char **av) -{ - int fd; - int i, nsect; - int aoutsz; - struct external_filehdr fhdr; - AOUTHDR aout; - struct external_scnhdr shdr; - - if (ac != 2) { - fprintf(stderr, "Usage: hack-coff coff-file\n"); - exit(1); - } - if ((fd = open(av[1], 2)) == -1) { - perror(av[2]); - exit(1); - } - if (read(fd, &fhdr, sizeof(fhdr)) != sizeof(fhdr)) - goto readerr; - i = get_16be(fhdr.f_magic); - if (i != U802TOCMAGIC && i != U802WRMAGIC && i != U802ROMAGIC) { - fprintf(stderr, "%s: not an xcoff file\n", av[1]); - exit(1); - } - aoutsz = get_16be(fhdr.f_opthdr); - if (read(fd, &aout, aoutsz) != aoutsz) - goto readerr; - nsect = get_16be(fhdr.f_nscns); - for (i = 0; i < nsect; ++i) { - if (read(fd, &shdr, sizeof(shdr)) != sizeof(shdr)) - goto readerr; - if (strcmp(shdr.s_name, ".text") == 0) { - put_16be(aout.o_snentry, i+1); - put_16be(aout.o_sntext, i+1); - } else if (strcmp(shdr.s_name, ".data") == 0) { - put_16be(aout.o_sndata, i+1); - } else if (strcmp(shdr.s_name, ".bss") == 0) { - put_16be(aout.o_snbss, i+1); - } - } - put_16be(aout.magic, AOUT_MAGIC); - if (lseek(fd, (long) sizeof(struct external_filehdr), 0) == -1 - || write(fd, &aout, aoutsz) != aoutsz) { - fprintf(stderr, "%s: write error\n", av[1]); - exit(1); - } - close(fd); - exit(0); - -readerr: - fprintf(stderr, "%s: read error or file too short\n", av[1]); - exit(1); -} diff -Nru a/arch/ppc/coffboot/ld.script b/arch/ppc/coffboot/ld.script --- a/arch/ppc/coffboot/ld.script Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,68 +0,0 @@ -OUTPUT_ARCH(powerpc) -SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); -/* Do we need any of these for elf? - __DYNAMIC = 0; */ -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } - .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.bss : { *(.rel.bss) } - .rela.bss : { *(.rela.bss) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : { *(.init) } =0 - .plt : { *(.plt) } - .text : - { - *(.text) - *(.rodata) - *(.rodata1) - *(.got1) - } - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - _etext = .; - PROVIDE (etext = .); - /* Read-write section, merged into data segment: */ - . = (. + 0x0FFF) & 0xFFFFF000; - .data : - { - *(.data) - *(.data1) - *(.sdata) - *(.sdata2) - *(.got.plt) *(.got) - *(.dynamic) - CONSTRUCTORS - } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - .bss : - { - *(.sbss) *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - } - _end = . ; - PROVIDE (end = .); -} - diff -Nru a/arch/ppc/coffboot/misc.S b/arch/ppc/coffboot/misc.S --- a/arch/ppc/coffboot/misc.S Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,57 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - .text - -/* - * Use the BAT3 registers to map the 1st 8MB of RAM to - * the address given as the 1st argument. - */ - .globl setup_bats -setup_bats: - mfpvr 5 - rlwinm 5,5,16,16,31 /* r3 = 1 for 601, 4 for 604 */ - cmpi 0,5,1 - li 0,0 - bne 4f - mtibatl 3,0 /* invalidate BAT first */ - ori 3,3,4 /* set up BAT registers for 601 */ - li 4,0x7f - mtibatu 3,3 - mtibatl 3,4 - b 5f -4: mtdbatu 3,0 /* invalidate BATs first */ - mtibatu 3,0 - ori 3,3,0xff /* set up BAT registers for 604 */ - li 4,2 - mtdbatl 3,4 - mtdbatu 3,3 - mtibatl 3,4 - mtibatu 3,3 -5: sync - isync - blr - -/* - * Flush the dcache and invalidate the icache for a range of addresses. - * - * flush_cache(addr, len) - */ - .global flush_cache -flush_cache: - addi 4,4,0x1f /* len = (len + 0x1f) / 0x20 */ - rlwinm. 4,4,27,5,31 - mtctr 4 - beqlr -1: dcbf 0,3 - icbi 0,3 - addi 3,3,0x20 - bdnz 1b - sync - isync - blr diff -Nru a/arch/ppc/coffboot/mknote.c b/arch/ppc/coffboot/mknote.c --- a/arch/ppc/coffboot/mknote.c Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,43 +0,0 @@ -/* - * Copyright (C) Cort Dougan 1999. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Generate a note section as per the CHRP specification. - * - */ - -#include - -#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff ); - -int main(void) -{ -/* header */ - /* namesz */ - PL(strlen("PowerPC")+1); - /* descrsz */ - PL(6*4); - /* type */ - PL(0x1275); - /* name */ - printf("PowerPC"); printf("%c", 0); - -/* descriptor */ - /* real-mode */ - PL(0xffffffff); - /* real-base */ - PL(0x00c00000); - /* real-size */ - PL(0xffffffff); - /* virt-base */ - PL(0xffffffff); - /* virt-size */ - PL(0xffffffff); - /* load-base */ - PL(0x4000); - return 0; -} diff -Nru a/arch/ppc/coffboot/no_initrd.c b/arch/ppc/coffboot/no_initrd.c --- a/arch/ppc/coffboot/no_initrd.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,2 +0,0 @@ -char initrd_data[1]; -int initrd_len = 0; diff -Nru a/arch/ppc/coffboot/nonstdio.h b/arch/ppc/coffboot/nonstdio.h --- a/arch/ppc/coffboot/nonstdio.h Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,18 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -typedef int FILE; -extern FILE *stdin, *stdout; -#define NULL ((void *)0) -#define EOF (-1) -#define fopen(n, m) NULL -#define fflush(f) 0 -#define fclose(f) 0 -extern char *fgets(); - -#define perror(s) printf("%s: no files!\n", (s)) diff -Nru a/arch/ppc/coffboot/piggyback.c b/arch/ppc/coffboot/piggyback.c --- a/arch/ppc/coffboot/piggyback.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,66 +0,0 @@ -#include -#include - -extern long ce_exec_config[]; - -int main(int argc, char *argv[]) -{ - int i, cnt, pos, len; - unsigned int cksum, val; - unsigned char *lp; - unsigned char buf[8192]; - if (argc != 2) - { - fprintf(stderr, "usage: %s name out-file\n", - argv[0]); - exit(1); - } - fprintf(stdout, "#\n"); - fprintf(stdout, "# Miscellaneous data structures:\n"); - fprintf(stdout, "# WARNING - this file is automatically generated!\n"); - fprintf(stdout, "#\n"); - fprintf(stdout, "\n"); - fprintf(stdout, "\t.data\n"); - fprintf(stdout, "\t.globl %s_data\n", argv[1]); - fprintf(stdout, "%s_data:\n", argv[1]); - pos = 0; - cksum = 0; - while ((len = read(0, buf, sizeof(buf))) > 0) - { - cnt = 0; - lp = (unsigned char *)buf; - len = (len + 3) & ~3; /* Round up to longwords */ - for (i = 0; i < len; i += 4) - { - if (cnt == 0) - { - fprintf(stdout, "\t.long\t"); - } - fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); - val = *(unsigned long *)lp; - cksum ^= val; - lp += 4; - if (++cnt == 4) - { - cnt = 0; - fprintf(stdout, " # %x \n", pos+i-12); - fflush(stdout); - } else - { - fprintf(stdout, ","); - } - } - if (cnt) - { - fprintf(stdout, "0\n"); - } - pos += len; - } - fprintf(stdout, "\t.globl %s_len\n", argv[1]); - fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos); - fflush(stdout); - fclose(stdout); - fprintf(stderr, "cksum = %x\n", cksum); - exit(0); -} - diff -Nru a/arch/ppc/coffboot/rs6000.h b/arch/ppc/coffboot/rs6000.h --- a/arch/ppc/coffboot/rs6000.h Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,243 +0,0 @@ -/* IBM RS/6000 "XCOFF" file definitions for BFD. - Copyright (C) 1990, 1991 Free Software Foundation, Inc. - FIXME: Can someone provide a transliteration of this name into ASCII? - Using the following chars caused a compiler warning on HIUX (so I replaced - them with octal escapes), and isn't useful without an understanding of what - character set it is. - Written by Mimi Ph\373\364ng-Th\345o V\365 of IBM - and John Gilmore of Cygnus Support. */ - -/********************** FILE HEADER **********************/ - -struct external_filehdr { - char f_magic[2]; /* magic number */ - char f_nscns[2]; /* number of sections */ - char f_timdat[4]; /* time & date stamp */ - char f_symptr[4]; /* file pointer to symtab */ - char f_nsyms[4]; /* number of symtab entries */ - char f_opthdr[2]; /* sizeof(optional hdr) */ - char f_flags[2]; /* flags */ -}; - - /* IBM RS/6000 */ -#define U802WRMAGIC 0730 /* writeable text segments **chh** */ -#define U802ROMAGIC 0735 /* readonly sharable text segments */ -#define U802TOCMAGIC 0737 /* readonly text segments and TOC */ - -#define BADMAG(x) \ - ((x).f_magic != U802ROMAGIC && (x).f_magic != U802WRMAGIC && \ - (x).f_magic != U802TOCMAGIC) - -#define FILHDR struct external_filehdr -#define FILHSZ 20 - - -/********************** AOUT "OPTIONAL HEADER" **********************/ - - -typedef struct -{ - unsigned char magic[2]; /* type of file */ - unsigned char vstamp[2]; /* version stamp */ - unsigned char tsize[4]; /* text size in bytes, padded to FW bdry */ - unsigned char dsize[4]; /* initialized data " " */ - unsigned char bsize[4]; /* uninitialized data " " */ - unsigned char entry[4]; /* entry pt. */ - unsigned char text_start[4]; /* base of text used for this file */ - unsigned char data_start[4]; /* base of data used for this file */ - unsigned char o_toc[4]; /* address of TOC */ - unsigned char o_snentry[2]; /* section number of entry point */ - unsigned char o_sntext[2]; /* section number of .text section */ - unsigned char o_sndata[2]; /* section number of .data section */ - unsigned char o_sntoc[2]; /* section number of TOC */ - unsigned char o_snloader[2]; /* section number of .loader section */ - unsigned char o_snbss[2]; /* section number of .bss section */ - unsigned char o_algntext[2]; /* .text alignment */ - unsigned char o_algndata[2]; /* .data alignment */ - unsigned char o_modtype[2]; /* module type (??) */ - unsigned char o_cputype[2]; /* cpu type */ - unsigned char o_maxstack[4]; /* max stack size (??) */ - unsigned char o_maxdata[4]; /* max data size (??) */ - unsigned char o_resv2[12]; /* reserved */ -} -AOUTHDR; - -#define AOUTSZ 72 -#define SMALL_AOUTSZ (28) -#define AOUTHDRSZ 72 - -#define RS6K_AOUTHDR_OMAGIC 0x0107 /* old: text & data writeable */ -#define RS6K_AOUTHDR_NMAGIC 0x0108 /* new: text r/o, data r/w */ -#define RS6K_AOUTHDR_ZMAGIC 0x010B /* paged: text r/o, both page-aligned */ - - -/********************** SECTION HEADER **********************/ - - -struct external_scnhdr { - char s_name[8]; /* section name */ - char s_paddr[4]; /* physical address, aliased s_nlib */ - char s_vaddr[4]; /* virtual address */ - char s_size[4]; /* section size */ - char s_scnptr[4]; /* file ptr to raw data for section */ - char s_relptr[4]; /* file ptr to relocation */ - char s_lnnoptr[4]; /* file ptr to line numbers */ - char s_nreloc[2]; /* number of relocation entries */ - char s_nlnno[2]; /* number of line number entries*/ - char s_flags[4]; /* flags */ -}; - -/* - * names of "special" sections - */ -#define _TEXT ".text" -#define _DATA ".data" -#define _BSS ".bss" -#define _PAD ".pad" -#define _LOADER ".loader" - -#define SCNHDR struct external_scnhdr -#define SCNHSZ 40 - -/* XCOFF uses a special .loader section with type STYP_LOADER. */ -#define STYP_LOADER 0x1000 - -/* XCOFF uses a special .debug section with type STYP_DEBUG. */ -#define STYP_DEBUG 0x2000 - -/* XCOFF handles line number or relocation overflow by creating - another section header with STYP_OVRFLO set. */ -#define STYP_OVRFLO 0x8000 - -/********************** LINE NUMBERS **********************/ - -/* 1 line number entry for every "breakpointable" source line in a section. - * Line numbers are grouped on a per function basis; first entry in a function - * grouping will have l_lnno = 0 and in place of physical address will be the - * symbol table index of the function name. - */ -struct external_lineno { - union { - char l_symndx[4]; /* function name symbol index, iff l_lnno == 0*/ - char l_paddr[4]; /* (physical) address of line number */ - } l_addr; - char l_lnno[2]; /* line number */ -}; - - -#define LINENO struct external_lineno -#define LINESZ 6 - - -/********************** SYMBOLS **********************/ - -#define E_SYMNMLEN 8 /* # characters in a symbol name */ -#define E_FILNMLEN 14 /* # characters in a file name */ -#define E_DIMNUM 4 /* # array dimensions in auxiliary entry */ - -struct external_syment -{ - union { - char e_name[E_SYMNMLEN]; - struct { - char e_zeroes[4]; - char e_offset[4]; - } e; - } e; - char e_value[4]; - char e_scnum[2]; - char e_type[2]; - char e_sclass[1]; - char e_numaux[1]; -}; - - - -#define N_BTMASK (017) -#define N_TMASK (060) -#define N_BTSHFT (4) -#define N_TSHIFT (2) - - -union external_auxent { - struct { - char x_tagndx[4]; /* str, un, or enum tag indx */ - union { - struct { - char x_lnno[2]; /* declaration line number */ - char x_size[2]; /* str/union/array size */ - } x_lnsz; - char x_fsize[4]; /* size of function */ - } x_misc; - union { - struct { /* if ISFCN, tag, or .bb */ - char x_lnnoptr[4]; /* ptr to fcn line # */ - char x_endndx[4]; /* entry ndx past block end */ - } x_fcn; - struct { /* if ISARY, up to 4 dimen. */ - char x_dimen[E_DIMNUM][2]; - } x_ary; - } x_fcnary; - char x_tvndx[2]; /* tv index */ - } x_sym; - - union { - char x_fname[E_FILNMLEN]; - struct { - char x_zeroes[4]; - char x_offset[4]; - } x_n; - } x_file; - - struct { - char x_scnlen[4]; /* section length */ - char x_nreloc[2]; /* # relocation entries */ - char x_nlinno[2]; /* # line numbers */ - } x_scn; - - struct { - char x_tvfill[4]; /* tv fill value */ - char x_tvlen[2]; /* length of .tv */ - char x_tvran[2][2]; /* tv range */ - } x_tv; /* info about .tv section (in auxent of symbol .tv)) */ - - struct { - unsigned char x_scnlen[4]; - unsigned char x_parmhash[4]; - unsigned char x_snhash[2]; - unsigned char x_smtyp[1]; - unsigned char x_smclas[1]; - unsigned char x_stab[4]; - unsigned char x_snstab[2]; - } x_csect; - -}; - -#define SYMENT struct external_syment -#define SYMESZ 18 -#define AUXENT union external_auxent -#define AUXESZ 18 -#define DBXMASK 0x80 /* for dbx storage mask */ -#define SYMNAME_IN_DEBUG(symptr) ((symptr)->n_sclass & DBXMASK) - - - -/********************** RELOCATION DIRECTIVES **********************/ - - -struct external_reloc { - char r_vaddr[4]; - char r_symndx[4]; - char r_size[1]; - char r_type[1]; -}; - - -#define RELOC struct external_reloc -#define RELSZ 10 - -#define DEFAULT_DATA_SECTION_ALIGNMENT 4 -#define DEFAULT_BSS_SECTION_ALIGNMENT 4 -#define DEFAULT_TEXT_SECTION_ALIGNMENT 4 -/* For new sections we havn't heard of before */ -#define DEFAULT_SECTION_ALIGNMENT 4 diff -Nru a/arch/ppc/coffboot/start.c b/arch/ppc/coffboot/start.c --- a/arch/ppc/coffboot/start.c Mon May 21 17:07:05 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,340 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include - -int (*prom)(); - -void *chosen_handle; -void *stdin; -void *stdout; -void *stderr; - -void exit(void); -void *finddevice(const char *name); -int getprop(void *phandle, const char *name, void *buf, int buflen); -void printk(char *fmt, ...); - -void -start(int a1, int a2, void *promptr) -{ - prom = (int (*)()) promptr; - chosen_handle = finddevice("/chosen"); - if (chosen_handle == (void *) -1) - exit(); - if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) - exit(); - stderr = stdout; - if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) - exit(); - - boot(a1, a2, promptr); - for (;;) - exit(); -} - -int -write(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "write"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - -int writestring(void *f, char *ptr, int nb) -{ - int w = 0, i; - char *ret = "\r"; - - for (i = 0; i < nb; ++i) { - if (ptr[i] == '\n') { - if (i > w) { - write(f, ptr + w, i - w); - w = i; - } - write(f, ret, 1); - } - } - if (w < nb) - write(f, ptr + w, nb - w); - return nb; -} - -int -read(void *handle, void *ptr, int nb) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *ihandle; - void *addr; - int len; - int actual; - } args; - - args.service = "read"; - args.nargs = 3; - args.nret = 1; - args.ihandle = handle; - args.addr = ptr; - args.len = nb; - args.actual = -1; - (*prom)(&args); - return args.actual; -} - -void -exit() -{ - struct prom_args { - char *service; - } args; - - for (;;) { - args.service = "exit"; - (*prom)(&args); - } -} - -void -pause() -{ - struct prom_args { - char *service; - } args; - - args.service = "enter"; - (*prom)(&args); -} - -void * -finddevice(const char *name) -{ - struct prom_args { - char *service; - int nargs; - int nret; - const char *devspec; - void *phandle; - } args; - - args.service = "finddevice"; - args.nargs = 1; - args.nret = 1; - args.devspec = name; - args.phandle = (void *) -1; - (*prom)(&args); - return args.phandle; -} - -void * -claim(unsigned int virt, unsigned int size, unsigned int align) -{ - struct prom_args { - char *service; - int nargs; - int nret; - unsigned int virt; - unsigned int size; - unsigned int align; - void *ret; - } args; - - args.service = "claim"; - args.nargs = 3; - args.nret = 1; - args.virt = virt; - args.size = size; - args.align = align; - (*prom)(&args); - return args.ret; -} - -void -release(void *virt, unsigned int size) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *virt; - unsigned int size; - } args; - - args.service = "release"; - args.nargs = 2; - args.nret = 0; - args.virt = virt; - args.size = size; - (*prom)(&args); -} - -int -getprop(void *phandle, const char *name, void *buf, int buflen) -{ - struct prom_args { - char *service; - int nargs; - int nret; - void *phandle; - const char *name; - void *buf; - int buflen; - int size; - } args; - - args.service = "getprop"; - args.nargs = 4; - args.nret = 1; - args.phandle = phandle; - args.name = name; - args.buf = buf; - args.buflen = buflen; - args.size = -1; - (*prom)(&args); - return args.size; -} - -int -putc(int c, void *f) -{ - char ch = c; - - return writestring(f, &ch, 1) == 1? c: -1; -} - -int -putchar(int c) -{ - return putc(c, stdout); -} - -int -fputs(char *str, void *f) -{ - int n = strlen(str); - - return writestring(f, str, n) == n? 0: -1; -} - -int -readchar() -{ - char ch; - - for (;;) { - switch (read(stdin, &ch, 1)) { - case 1: - return ch; - case -1: - printk("read(stdin) returned -1\n"); - return -1; - } - } -} - -static char line[256]; -static char *lineptr; -static int lineleft; - -int -getchar() -{ - int c; - - if (lineleft == 0) { - lineptr = line; - for (;;) { - c = readchar(); - if (c == -1 || c == 4) - break; - if (c == '\r' || c == '\n') { - *lineptr++ = '\n'; - putchar('\n'); - break; - } - switch (c) { - case 0177: - case '\b': - if (lineptr > line) { - putchar('\b'); - putchar(' '); - putchar('\b'); - --lineptr; - } - break; - case 'U' & 0x1F: - while (lineptr > line) { - putchar('\b'); - putchar(' '); - putchar('\b'); - --lineptr; - } - break; - default: - if (lineptr >= &line[sizeof(line) - 1]) - putchar('\a'); - else { - putchar(c); - *lineptr++ = c; - } - } - } - lineleft = lineptr - line; - lineptr = line; - } - if (lineleft == 0) - return -1; - --lineleft; - return *lineptr++; -} - -extern int vsprintf(char *buf, const char *fmt, va_list args); -static char sprint_buf[1024]; - -void -printk(char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - writestring(stdout, sprint_buf, n); -} - -int -printf(char *fmt, ...) -{ - va_list args; - int n; - - va_start(args, fmt); - n = vsprintf(sprint_buf, fmt, args); - va_end(args); - writestring(stdout, sprint_buf, n); - return n; -} diff -Nru a/arch/ppc/coffboot/string.S b/arch/ppc/coffboot/string.S --- a/arch/ppc/coffboot/string.S Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,206 +0,0 @@ -/* - * String handling functions for PowerPC. - * - * Copyright (C) 1996 Paul Mackerras. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#define r0 0 -#define r3 3 -#define r4 4 -#define r5 5 -#define r6 6 -#define r7 7 -#define r8 8 - - .globl strcpy -strcpy: - addi r5,r3,-1 - addi r4,r4,-1 -1: lbzu r0,1(r4) - cmpwi 0,r0,0 - stbu r0,1(r5) - bne 1b - blr - - .globl strncpy -strncpy: - cmpwi 0,r5,0 - beqlr - mtctr r5 - addi r6,r3,-1 - addi r4,r4,-1 -1: lbzu r0,1(r4) - cmpwi 0,r0,0 - stbu r0,1(r6) - bdnzf 2,1b /* dec ctr, branch if ctr != 0 && !cr0.eq */ - blr - - .globl strcat -strcat: - addi r5,r3,-1 - addi r4,r4,-1 -1: lbzu r0,1(r5) - cmpwi 0,r0,0 - bne 1b - addi r5,r5,-1 -1: lbzu r0,1(r4) - cmpwi 0,r0,0 - stbu r0,1(r5) - bne 1b - blr - - .globl strcmp -strcmp: - addi r5,r3,-1 - addi r4,r4,-1 -1: lbzu r3,1(r5) - cmpwi 1,r3,0 - lbzu r0,1(r4) - subf. r3,r0,r3 - beqlr 1 - beq 1b - blr - - .globl strlen -strlen: - addi r4,r3,-1 -1: lbzu r0,1(r4) - cmpwi 0,r0,0 - bne 1b - subf r3,r3,r4 - blr - - .globl memset -memset: - rlwimi r4,r4,8,16,23 - rlwimi r4,r4,16,0,15 - addi r6,r3,-4 - cmplwi 0,r5,4 - blt 7f - stwu r4,4(r6) - beqlr - andi. r0,r6,3 - add r5,r0,r5 - subf r6,r0,r6 - rlwinm r0,r5,32-2,2,31 - mtctr r0 - bdz 6f -1: stwu r4,4(r6) - bdnz 1b -6: andi. r5,r5,3 -7: cmpwi 0,r5,0 - beqlr - mtctr r5 - addi r6,r6,3 -8: stbu r4,1(r6) - bdnz 8b - blr - - .globl bcopy -bcopy: - mr r6,r3 - mr r3,r4 - mr r4,r6 - b memcpy - - .globl memmove -memmove: - cmplw 0,r3,r4 - bgt backwards_memcpy - /* fall through */ - - .globl memcpy -memcpy: - rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ - addi r6,r3,-4 - addi r4,r4,-4 - beq 2f /* if less than 8 bytes to do */ - andi. r0,r6,3 /* get dest word aligned */ - mtctr r7 - bne 5f -1: lwz r7,4(r4) - lwzu r8,8(r4) - stw r7,4(r6) - stwu r8,8(r6) - bdnz 1b - andi. r5,r5,7 -2: cmplwi 0,r5,4 - blt 3f - lwzu r0,4(r4) - addi r5,r5,-4 - stwu r0,4(r6) -3: cmpwi 0,r5,0 - beqlr - mtctr r5 - addi r4,r4,3 - addi r6,r6,3 -4: lbzu r0,1(r4) - stbu r0,1(r6) - bdnz 4b - blr -5: subfic r0,r0,4 - mtctr r0 -6: lbz r7,4(r4) - addi r4,r4,1 - stb r7,4(r6) - addi r6,r6,1 - bdnz 6b - subf r5,r0,r5 - rlwinm. r7,r5,32-3,3,31 - beq 2b - mtctr r7 - b 1b - - .globl backwards_memcpy -backwards_memcpy: - rlwinm. r7,r5,32-3,3,31 /* r0 = r5 >> 3 */ - add r6,r3,r5 - add r4,r4,r5 - beq 2f - andi. r0,r6,3 - mtctr r7 - bne 5f -1: lwz r7,-4(r4) - lwzu r8,-8(r4) - stw r7,-4(r6) - stwu r8,-8(r6) - bdnz 1b - andi. r5,r5,7 -2: cmplwi 0,r5,4 - blt 3f - lwzu r0,-4(r4) - subi r5,r5,4 - stwu r0,-4(r6) -3: cmpwi 0,r5,0 - beqlr - mtctr r5 -4: lbzu r0,-1(r4) - stbu r0,-1(r6) - bdnz 4b - blr -5: mtctr r0 -6: lbzu r7,-1(r4) - stbu r7,-1(r6) - bdnz 6b - subf r5,r0,r5 - rlwinm. r7,r5,32-3,3,31 - beq 2b - mtctr r7 - b 1b - - .globl memcmp -memcmp: - cmpwi 0,r5,0 - blelr - mtctr r5 - addi r6,r3,-1 - addi r4,r4,-1 -1: lbzu r3,1(r6) - lbzu r0,1(r4) - subf. r3,r0,r3 - bdnzt 2,1b - blr diff -Nru a/arch/ppc/coffboot/zlib.c b/arch/ppc/coffboot/zlib.c --- a/arch/ppc/coffboot/zlib.c Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,2148 +0,0 @@ -/* - * This file is derived from various .h and .c files from the zlib-0.95 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. See zlib.h for conditions of - * distribution and use. - * - * Changes that have been made include: - * - changed functions not used outside this file to "local" - * - added minCompression parameter to deflateInit2 - * - added Z_PACKET_FLUSH (see zlib.h for details) - * - added inflateIncomp - * - * $Id: zlib.c,v 1.3 1999/05/27 22:22:54 cort Exp $ - */ - -/*+++++*/ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* From: zutil.h,v 1.9 1995/05/03 17:27:12 jloup Exp */ - -#define _Z_UTIL_H - -#include "zlib.h" - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -#define FAR - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern char *z_errmsg[]; /* indexed by 1-zlib_error */ - -#define ERR_RETURN(strm,err) return (strm->msg=z_errmsg[1-err], err) -/* To be used only when the state is known to be valid */ - -#ifndef NULL -#define NULL ((void *) 0) -#endif - - /* common constants */ - -#define DEFLATED 8 - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - - /* functions */ - -#include -#define zmemcpy memcpy -#define zmemzero(dest, len) memset(dest, 0, len) - -/* Diagnostic functions */ -#ifdef DEBUG_ZLIB -# include -# ifndef verbose -# define verbose 0 -# endif -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) fprintf x -# define Tracev(x) {if (verbose) fprintf x ;} -# define Tracevv(x) {if (verbose>1) fprintf x ;} -# define Tracec(c,x) {if (verbose && (c)) fprintf x ;} -# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -typedef uLong (*check_func) OF((uLong check, Bytef *buf, uInt len)); - -/* voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size)); */ -/* void zcfree OF((voidpf opaque, voidpf ptr)); */ - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr, size) \ - (*((strm)->zfree))((strm)->opaque, (voidpf)(addr), (size)) -#define TRY_FREE(s, p, n) {if (p) ZFREE(s, p, n);} - -/* deflate.h -- internal compression state - * Copyright (C) 1995 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/*+++++*/ -/* infblock.h -- header to use infblock.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_blocks_state; -typedef struct inflate_blocks_state FAR inflate_blocks_statef; - -local inflate_blocks_statef * inflate_blocks_new OF(( - z_stream *z, - check_func c, /* check function */ - uInt w)); /* window size */ - -local int inflate_blocks OF(( - inflate_blocks_statef *, - z_stream *, - int)); /* initial return code */ - -local void inflate_blocks_reset OF(( - inflate_blocks_statef *, - z_stream *, - uLongf *)); /* check value on output */ - -local int inflate_blocks_free OF(( - inflate_blocks_statef *, - z_stream *, - uLongf *)); /* check value on output */ - -local int inflate_addhistory OF(( - inflate_blocks_statef *, - z_stream *)); - -local int inflate_packet_flush OF(( - inflate_blocks_statef *)); - -/*+++++*/ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Huffman code lookup table entry--this entry is four bytes for machines - that have 16-bit pointers (e.g. PC's in the small or medium model). */ - -typedef struct inflate_huft_s FAR inflate_huft; - -struct inflate_huft_s { - union { - struct { - Byte Exop; /* number of extra bits or operation */ - Byte Bits; /* number of bits in this code or subcode */ - } what; - uInt Nalloc; /* number of these allocated here */ - Bytef *pad; /* pad structure to a power of 2 (4 bytes for */ - } word; /* 16-bit, 8 bytes for 32-bit machines) */ - union { - uInt Base; /* literal, length base, or distance base */ - inflate_huft *Next; /* pointer to next level of table */ - } more; -}; - -#ifdef DEBUG_ZLIB - local uInt inflate_hufts; -#endif - -local int inflate_trees_bits OF(( - uIntf *, /* 19 code lengths */ - uIntf *, /* bits tree desired/actual depth */ - inflate_huft * FAR *, /* bits tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_dynamic OF(( - uInt, /* number of literal/length codes */ - uInt, /* number of distance codes */ - uIntf *, /* that many (total) code lengths */ - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *, /* distance tree result */ - z_stream *)); /* for zalloc, zfree functions */ - -local int inflate_trees_fixed OF(( - uIntf *, /* literal desired/actual bit depth */ - uIntf *, /* distance desired/actual bit depth */ - inflate_huft * FAR *, /* literal/length tree result */ - inflate_huft * FAR *)); /* distance tree result */ - -local int inflate_trees_free OF(( - inflate_huft *, /* tables to free */ - z_stream *)); /* for zfree function */ - - -/*+++++*/ -/* infcodes.h -- header to use infcodes.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -struct inflate_codes_state; -typedef struct inflate_codes_state FAR inflate_codes_statef; - -local inflate_codes_statef *inflate_codes_new OF(( - uInt, uInt, - inflate_huft *, inflate_huft *, - z_stream *)); - -local int inflate_codes OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -local void inflate_codes_free OF(( - inflate_codes_statef *, - z_stream *)); - - -/*+++++*/ -/* inflate.c -- zlib interface to inflate modules - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* inflate private state */ -struct internal_state { - - /* mode */ - enum { - METHOD, /* waiting for method byte */ - FLAG, /* waiting for flag byte */ - BLOCKS, /* decompressing blocks */ - CHECK4, /* four check bytes to go */ - CHECK3, /* three check bytes to go */ - CHECK2, /* two check bytes to go */ - CHECK1, /* one check byte to go */ - DONE, /* finished check, done */ - BAD} /* got an error--stay here */ - mode; /* current inflate mode */ - - /* mode dependent information */ - union { - uInt method; /* if FLAGS, method byte */ - struct { - uLong was; /* computed check value */ - uLong need; /* stream check value */ - } check; /* if CHECK, check values to compare */ - uInt marker; /* if BAD, inflateSync's marker bytes count */ - } sub; /* submode */ - - /* mode independent information */ - int nowrap; /* flag for no wrapper */ - uInt wbits; /* log2(window size) (8..15, defaults to 15) */ - inflate_blocks_statef - *blocks; /* current inflate_blocks state */ - -}; - - -int inflateReset(z) -z_stream *z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - z->total_in = z->total_out = 0; - z->msg = Z_NULL; - z->state->mode = z->state->nowrap ? BLOCKS : METHOD; - inflate_blocks_reset(z->state->blocks, z, &c); - Trace((stderr, "inflate: reset\n")); - return Z_OK; -} - - -int inflateEnd(z) -z_stream *z; -{ - uLong c; - - if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->blocks != Z_NULL) - inflate_blocks_free(z->state->blocks, z, &c); - ZFREE(z, z->state, sizeof(struct internal_state)); - z->state = Z_NULL; - Trace((stderr, "inflate: end\n")); - return Z_OK; -} - - -int inflateInit2(z, w) -z_stream *z; -int w; -{ - /* initialize state */ - if (z == Z_NULL) - return Z_STREAM_ERROR; -/* if (z->zalloc == Z_NULL) z->zalloc = zcalloc; */ -/* if (z->zfree == Z_NULL) z->zfree = zcfree; */ - if ((z->state = (struct internal_state FAR *) - ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL) - return Z_MEM_ERROR; - z->state->blocks = Z_NULL; - - /* handle undocumented nowrap option (no zlib header or check) */ - z->state->nowrap = 0; - if (w < 0) - { - w = - w; - z->state->nowrap = 1; - } - - /* set window size */ - if (w < 8 || w > 15) - { - inflateEnd(z); - return Z_STREAM_ERROR; - } - z->state->wbits = (uInt)w; - - /* create inflate_blocks state */ - if ((z->state->blocks = - inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, 1 << w)) - == Z_NULL) - { - inflateEnd(z); - return Z_MEM_ERROR; - } - Trace((stderr, "inflate: allocated\n")); - - /* reset state */ - inflateReset(z); - return Z_OK; -} - - -int inflateInit(z) -z_stream *z; -{ - return inflateInit2(z, DEF_WBITS); -} - - -#define NEEDBYTE {if(z->avail_in==0)goto empty;r=Z_OK;} -#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++) - -int inflate(z, f) -z_stream *z; -int f; -{ - int r; - uInt b; - - if (z == Z_NULL || z->next_in == Z_NULL) - return Z_STREAM_ERROR; - r = Z_BUF_ERROR; - while (1) switch (z->state->mode) - { - case METHOD: - NEEDBYTE - if (((z->state->sub.method = NEXTBYTE) & 0xf) != DEFLATED) - { - z->state->mode = BAD; - z->msg = "unknown compression method"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if ((z->state->sub.method >> 4) + 8 > z->state->wbits) - { - z->state->mode = BAD; - z->msg = "invalid window size"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - z->state->mode = FLAG; - case FLAG: - NEEDBYTE - if ((b = NEXTBYTE) & 0x20) - { - z->state->mode = BAD; - z->msg = "invalid reserved bit"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - if (((z->state->sub.method << 8) + b) % 31) - { - z->state->mode = BAD; - z->msg = "incorrect header check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib header ok\n")); - z->state->mode = BLOCKS; - case BLOCKS: - r = inflate_blocks(z->state->blocks, z, r); - if (f == Z_PACKET_FLUSH && z->avail_in == 0 && z->avail_out != 0) - r = inflate_packet_flush(z->state->blocks); - if (r == Z_DATA_ERROR) - { - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - break; - } - if (r != Z_STREAM_END) - return r; - r = Z_OK; - inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was); - if (z->state->nowrap) - { - z->state->mode = DONE; - break; - } - z->state->mode = CHECK4; - case CHECK4: - NEEDBYTE - z->state->sub.check.need = (uLong)NEXTBYTE << 24; - z->state->mode = CHECK3; - case CHECK3: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 16; - z->state->mode = CHECK2; - case CHECK2: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE << 8; - z->state->mode = CHECK1; - case CHECK1: - NEEDBYTE - z->state->sub.check.need += (uLong)NEXTBYTE; - - if (z->state->sub.check.was != z->state->sub.check.need) - { - z->state->mode = BAD; - z->msg = "incorrect data check"; - z->state->sub.marker = 5; /* can't try inflateSync */ - break; - } - Trace((stderr, "inflate: zlib check ok\n")); - z->state->mode = DONE; - case DONE: - return Z_STREAM_END; - case BAD: - return Z_DATA_ERROR; - default: - return Z_STREAM_ERROR; - } - - empty: - if (f != Z_PACKET_FLUSH) - return r; - z->state->mode = BAD; - z->state->sub.marker = 0; /* can try inflateSync */ - return Z_DATA_ERROR; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ - -int inflateIncomp(z) -z_stream *z; -{ - if (z->state->mode != BLOCKS) - return Z_DATA_ERROR; - return inflate_addhistory(z->state->blocks, z); -} - - -int inflateSync(z) -z_stream *z; -{ - uInt n; /* number of bytes to look at */ - Bytef *p; /* pointer to bytes */ - uInt m; /* number of marker bytes found in a row */ - uLong r, w; /* temporaries to save total_in and total_out */ - - /* set up */ - if (z == Z_NULL || z->state == Z_NULL) - return Z_STREAM_ERROR; - if (z->state->mode != BAD) - { - z->state->mode = BAD; - z->state->sub.marker = 0; - } - if ((n = z->avail_in) == 0) - return Z_BUF_ERROR; - p = z->next_in; - m = z->state->sub.marker; - - /* search */ - while (n && m < 4) - { - if (*p == (Byte)(m < 2 ? 0 : 0xff)) - m++; - else if (*p) - m = 0; - else - m = 4 - m; - p++, n--; - } - - /* restore */ - z->total_in += p - z->next_in; - z->next_in = p; - z->avail_in = n; - z->state->sub.marker = m; - - /* return no joy or set up to restart on a new block */ - if (m != 4) - return Z_DATA_ERROR; - r = z->total_in; w = z->total_out; - inflateReset(z); - z->total_in = r; z->total_out = w; - z->state->mode = BLOCKS; - return Z_OK; -} - -#undef NEEDBYTE -#undef NEXTBYTE - -/*+++++*/ -/* infutil.h -- types and macros common to blocks and codes - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* inflate blocks semi-private state */ -struct inflate_blocks_state { - - /* mode */ - enum { - TYPE, /* get type bits (3, including end bit) */ - LENS, /* get lengths for stored */ - STORED, /* processing stored block */ - TABLE, /* get table lengths */ - BTREE, /* get bit lengths tree for a dynamic block */ - DTREE, /* get length, distance trees for a dynamic block */ - CODES, /* processing fixed or dynamic block */ - DRY, /* output remaining window bytes */ - DONEB, /* finished last block, done */ - BADB} /* got a data error--stuck here */ - mode; /* current inflate_block mode */ - - /* mode dependent information */ - union { - uInt left; /* if STORED, bytes left to copy */ - struct { - uInt table; /* table lengths (14 bits) */ - uInt index; /* index into blens (or border) */ - uIntf *blens; /* bit lengths of codes */ - uInt bb; /* bit length tree depth */ - inflate_huft *tb; /* bit length decoding tree */ - int nblens; /* # elements allocated at blens */ - } trees; /* if DTREE, decoding info for trees */ - struct { - inflate_huft *tl, *td; /* trees to free */ - inflate_codes_statef - *codes; - } decode; /* if CODES, current state */ - } sub; /* submode */ - uInt last; /* true if this block is the last block */ - - /* mode independent information */ - uInt bitk; /* bits in bit buffer */ - uLong bitb; /* bit buffer */ - Bytef *window; /* sliding window */ - Bytef *end; /* one byte after sliding window */ - Bytef *read; /* window read pointer */ - Bytef *write; /* window write pointer */ - check_func checkfn; /* check function */ - uLong check; /* check on output */ - -}; - - -/* defines for inflate input/output */ -/* update pointers and return */ -#define UPDBITS {s->bitb=b;s->bitk=k;} -#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;} -#define UPDOUT {s->write=q;} -#define UPDATE {UPDBITS UPDIN UPDOUT} -#define LEAVE {UPDATE return inflate_flush(s,z,r);} -/* get bytes and bits */ -#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;} -#define NEEDBYTE {if(n)r=Z_OK;else LEAVE} -#define NEXTBYTE (n--,*p++) -#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<>=(j);k-=(j);} -/* output bytes */ -#define WAVAIL (qread?s->read-q-1:s->end-q) -#define LOADOUT {q=s->write;m=WAVAIL;} -#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=WAVAIL;}} -#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT} -#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;} -#define OUTBYTE(a) {*q++=(Byte)(a);m--;} -/* load local pointers */ -#define LOAD {LOADIN LOADOUT} - -/* - * The IBM 150 firmware munges the data right after _etext[]. This - * protects it. -- Cort - */ -local uInt protect_mask[] = {0, 0, 0, 0, 0, 0, 0, 0, 0 ,0 ,0 ,0}; -/* And'ing with mask[n] masks the lower n bits */ -local uInt inflate_mask[] = { - 0x0000, - 0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff, - 0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff -}; - -/* copy as much as possible from the sliding window to the output area */ -local int inflate_flush OF(( - inflate_blocks_statef *, - z_stream *, - int)); - -/*+++++*/ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -local int inflate_fast OF(( - uInt, - uInt, - inflate_huft *, - inflate_huft *, - inflate_blocks_statef *, - z_stream *)); - - -/*+++++*/ -/* infblock.c -- interpret and process block types to last block - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* Table for deflate from PKZIP's appnote.txt. */ -local uInt border[] = { /* Order of the bit length code lengths */ - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - -/* - Notes beyond the 1.93a appnote.txt: - - 1. Distance pointers never point before the beginning of the output - stream. - 2. Distance pointers can point back across blocks, up to 32k away. - 3. There is an implied maximum of 7 bits for the bit length table and - 15 bits for the actual data. - 4. If only one code exists, then it is encoded using one bit. (Zero - would be more efficient, but perhaps a little confusing.) If two - codes exist, they are coded using one bit each (0 and 1). - 5. There is no way of sending zero distance codes--a dummy must be - sent if there are none. (History: a pre 2.0 version of PKZIP would - store blocks with no distance codes, but this was discovered to be - too harsh a criterion.) Valid only for 1.93a. 2.04c does allow - zero distance codes, which is sent as one code of zero bits in - length. - 6. There are up to 286 literal/length codes. Code 256 represents the - end-of-block. Note however that the static length tree defines - 288 codes just to fill out the Huffman codes. Codes 286 and 287 - cannot be used though, since there is no length base or extra bits - defined for them. Similarily, there are up to 30 distance codes. - However, static trees define 32 codes (all 5 bits) to fill out the - Huffman codes, but the last two had better not show up in the data. - 7. Unzip can check dynamic Huffman blocks for complete code sets. - The exception is that a single code would not be complete (see #4). - 8. The five bits following the block type is really the number of - literal codes sent minus 257. - 9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits - (1+6+6). Therefore, to output three times the length, you output - three codes (1+1+1), whereas to output four times the same length, - you only need two codes (1+3). Hmm. - 10. In the tree reconstruction algorithm, Code = Code + Increment - only if BitLength(i) is not zero. (Pretty obvious.) - 11. Correction: 4 Bits: # of Bit Length codes - 4 (4 - 19) - 12. Note: length code 284 can represent 227-258, but length code 285 - really is 258. The last length deserves its own, short code - since it gets used a lot in very redundant files. The length - 258 is special since 258 - 3 (the min match length) is 255. - 13. The literal/length and distance code bit lengths are read as a - single stream of lengths. It is possible (and advantageous) for - a repeat code (16, 17, or 18) to go across the boundary between - the two sets of lengths. - */ - - -local void inflate_blocks_reset(s, z, c) -inflate_blocks_statef *s; -z_stream *z; -uLongf *c; -{ - if (s->checkfn != Z_NULL) - *c = s->check; - if (s->mode == BTREE || s->mode == DTREE) - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); - if (s->mode == CODES) - { - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - } - s->mode = TYPE; - s->bitk = 0; - s->bitb = 0; - s->read = s->write = s->window; - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(0L, Z_NULL, 0); - Trace((stderr, "inflate: blocks reset\n")); -} - - -local inflate_blocks_statef *inflate_blocks_new(z, c, w) -z_stream *z; -check_func c; -uInt w; -{ - inflate_blocks_statef *s; - - if ((s = (inflate_blocks_statef *)ZALLOC - (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL) - return s; - if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL) - { - ZFREE(z, s, sizeof(struct inflate_blocks_state)); - return Z_NULL; - } - s->end = s->window + w; - s->checkfn = c; - s->mode = TYPE; - Trace((stderr, "inflate: blocks allocated\n")); - inflate_blocks_reset(s, z, &s->check); - return s; -} - - -local int inflate_blocks(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt t; /* temporary storage */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input based on current state */ - while (1) switch (s->mode) - { - case TYPE: - NEEDBITS(3) - t = (uInt)b & 7; - s->last = t & 1; - switch (t >> 1) - { - case 0: /* stored */ - Trace((stderr, "inflate: stored block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - t = k & 7; /* go to byte boundary */ - DUMPBITS(t) - s->mode = LENS; /* get length of stored block */ - break; - case 1: /* fixed */ - Trace((stderr, "inflate: fixed codes block%s\n", - s->last ? " (last)" : "")); - { - uInt bl, bd; - inflate_huft *tl, *td; - - inflate_trees_fixed(&bl, &bd, &tl, &td); - s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z); - if (s->sub.decode.codes == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.decode.tl = Z_NULL; /* don't try to free these */ - s->sub.decode.td = Z_NULL; - } - DUMPBITS(3) - s->mode = CODES; - break; - case 2: /* dynamic */ - Trace((stderr, "inflate: dynamic codes block%s\n", - s->last ? " (last)" : "")); - DUMPBITS(3) - s->mode = TABLE; - break; - case 3: /* illegal */ - DUMPBITS(3) - s->mode = BADB; - z->msg = "invalid block type"; - r = Z_DATA_ERROR; - LEAVE - } - break; - case LENS: - NEEDBITS(32) - if (((~b) >> 16) != (b & 0xffff)) - { - s->mode = BADB; - z->msg = "invalid stored block lengths"; - r = Z_DATA_ERROR; - LEAVE - } - s->sub.left = (uInt)b & 0xffff; - b = k = 0; /* dump bits */ - Tracev((stderr, "inflate: stored length %u\n", s->sub.left)); - s->mode = s->sub.left ? STORED : TYPE; - break; - case STORED: - if (n == 0) - LEAVE - NEEDOUT - t = s->sub.left; - if (t > n) t = n; - if (t > m) t = m; - zmemcpy(q, p, t); - p += t; n -= t; - q += t; m -= t; - if ((s->sub.left -= t) != 0) - break; - Tracev((stderr, "inflate: stored end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - s->mode = s->last ? DRY : TYPE; - break; - case TABLE: - NEEDBITS(14) - s->sub.trees.table = t = (uInt)b & 0x3fff; -#ifndef PKZIP_BUG_WORKAROUND - if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) - { - s->mode = BADB; - z->msg = "too many length or distance symbols"; - r = Z_DATA_ERROR; - LEAVE - } -#endif - t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f); - if (t < 19) - t = 19; - if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL) - { - r = Z_MEM_ERROR; - LEAVE - } - s->sub.trees.nblens = t; - DUMPBITS(14) - s->sub.trees.index = 0; - Tracev((stderr, "inflate: table sizes ok\n")); - s->mode = BTREE; - case BTREE: - while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10)) - { - NEEDBITS(3) - s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7; - DUMPBITS(3) - } - while (s->sub.trees.index < 19) - s->sub.trees.blens[border[s->sub.trees.index++]] = 0; - s->sub.trees.bb = 7; - t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb, - &s->sub.trees.tb, z); - if (t != Z_OK) - { - r = t; - if (r == Z_DATA_ERROR) - s->mode = BADB; - LEAVE - } - s->sub.trees.index = 0; - Tracev((stderr, "inflate: bits tree ok\n")); - s->mode = DTREE; - case DTREE: - while (t = s->sub.trees.table, - s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)) - { - inflate_huft *h; - uInt i, j, c; - - t = s->sub.trees.bb; - NEEDBITS(t) - h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]); - t = h->word.what.Bits; - c = h->more.Base; - if (c < 16) - { - DUMPBITS(t) - s->sub.trees.blens[s->sub.trees.index++] = c; - } - else /* c == 16..18 */ - { - i = c == 18 ? 7 : c - 14; - j = c == 18 ? 11 : 3; - NEEDBITS(t + i) - DUMPBITS(t) - j += (uInt)b & inflate_mask[i]; - DUMPBITS(i) - i = s->sub.trees.index; - t = s->sub.trees.table; - if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || - (c == 16 && i < 1)) - { - s->mode = BADB; - z->msg = "invalid bit length repeat"; - r = Z_DATA_ERROR; - LEAVE - } - c = c == 16 ? s->sub.trees.blens[i - 1] : 0; - do { - s->sub.trees.blens[i++] = c; - } while (--j); - s->sub.trees.index = i; - } - } - inflate_trees_free(s->sub.trees.tb, z); - s->sub.trees.tb = Z_NULL; - { - uInt bl, bd; - inflate_huft *tl, *td; - inflate_codes_statef *c; - - bl = 9; /* must be <= 9 for lookahead assumptions */ - bd = 6; /* must be <= 9 for lookahead assumptions */ - t = s->sub.trees.table; - t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), - s->sub.trees.blens, &bl, &bd, &tl, &td, z); - if (t != Z_OK) - { - if (t == (uInt)Z_DATA_ERROR) - s->mode = BADB; - r = t; - LEAVE - } - Tracev((stderr, "inflate: trees ok\n")); - if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL) - { - inflate_trees_free(td, z); - inflate_trees_free(tl, z); - r = Z_MEM_ERROR; - LEAVE - } - ZFREE(z, s->sub.trees.blens, s->sub.trees.nblens * sizeof(uInt)); - s->sub.decode.codes = c; - s->sub.decode.tl = tl; - s->sub.decode.td = td; - } - s->mode = CODES; - case CODES: - UPDATE - if ((r = inflate_codes(s, z, r)) != Z_STREAM_END) - return inflate_flush(s, z, r); - r = Z_OK; - inflate_codes_free(s->sub.decode.codes, z); - inflate_trees_free(s->sub.decode.td, z); - inflate_trees_free(s->sub.decode.tl, z); - LOAD - Tracev((stderr, "inflate: codes end, %lu total out\n", - z->total_out + (q >= s->read ? q - s->read : - (s->end - s->read) + (q - s->window)))); - if (!s->last) - { - s->mode = TYPE; - break; - } - if (k > 7) /* return unused byte, if any */ - { - Assert(k < 16, "inflate_codes grabbed too many bytes") - k -= 8; - n++; - p--; /* can always return one */ - } - s->mode = DRY; - case DRY: - FLUSH - if (s->read != s->write) - LEAVE - s->mode = DONEB; - case DONEB: - r = Z_STREAM_END; - LEAVE - case BADB: - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -local int inflate_blocks_free(s, z, c) -inflate_blocks_statef *s; -z_stream *z; -uLongf *c; -{ - inflate_blocks_reset(s, z, c); - ZFREE(z, s->window, s->end - s->window); - ZFREE(z, s, sizeof(struct inflate_blocks_state)); - Trace((stderr, "inflate: blocks freed\n")); - return Z_OK; -} - -/* - * This subroutine adds the data at next_in/avail_in to the output history - * without performing any output. The output buffer must be "caught up"; - * i.e. no pending output (hence s->read equals s->write), and the state must - * be BLOCKS (i.e. we should be willing to see the start of a series of - * BLOCKS). On exit, the output will also be caught up, and the checksum - * will have been updated if need be. - */ -local int inflate_addhistory(s, z) -inflate_blocks_statef *s; -z_stream *z; -{ - uLong b; /* bit buffer */ /* NOT USED HERE */ - uInt k; /* bits in bit buffer */ /* NOT USED HERE */ - uInt t; /* temporary storage */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - - if (s->read != s->write) - return Z_STREAM_ERROR; - if (s->mode != TYPE) - return Z_DATA_ERROR; - - /* we're ready to rock */ - LOAD - /* while there is input ready, copy to output buffer, moving - * pointers as needed. - */ - while (n) { - t = n; /* how many to do */ - /* is there room until end of buffer? */ - if (t > m) t = m; - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, t); - zmemcpy(q, p, t); - q += t; - p += t; - n -= t; - z->total_out += t; - s->read = q; /* drag read pointer forward */ -/* WRAP */ /* expand WRAP macro by hand to handle s->read */ - if (q == s->end) { - s->read = q = s->window; - m = WAVAIL; - } - } - UPDATE - return Z_OK; -} - - -/* - * At the end of a Deflate-compressed PPP packet, we expect to have seen - * a `stored' block type value but not the (zero) length bytes. - */ -local int inflate_packet_flush(s) - inflate_blocks_statef *s; -{ - if (s->mode != LENS) - return Z_DATA_ERROR; - s->mode = TYPE; - return Z_OK; -} - - -/*+++++*/ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - - -local int huft_build OF(( - uIntf *, /* code lengths in bits */ - uInt, /* number of codes */ - uInt, /* number of "simple" codes */ - uIntf *, /* list of base values for non-simple codes */ - uIntf *, /* list of extra bits for non-simple codes */ - inflate_huft * FAR*,/* result: starting table */ - uIntf *, /* maximum lookup bits (returns actual) */ - z_stream *)); /* for zalloc function */ - -local voidpf falloc OF(( - voidpf, /* opaque pointer (not used) */ - uInt, /* number of items */ - uInt)); /* size of item */ - -local void ffree OF(( - voidpf q, /* opaque pointer (not used) */ - voidpf p, /* what to free (not used) */ - uInt n)); /* number of bytes (not used) */ - -/* Tables for deflate from PKZIP's appnote.txt. */ -local uInt cplens[] = { /* Copy lengths for literal codes 257..285 */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - /* actually lengths - 2; also see note #13 above about 258 */ -local uInt cplext[] = { /* Extra bits for literal codes 257..285 */ - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, - 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 192, 192}; /* 192==invalid */ -local uInt cpdist[] = { /* Copy offsets for distance codes 0..29 */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577}; -local uInt cpdext[] = { /* Extra bits for distance codes */ - 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, - 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, - 12, 12, 13, 13}; - -/* - Huffman code decoding is performed using a multi-level table lookup. - The fastest way to decode is to simply build a lookup table whose - size is determined by the longest code. However, the time it takes - to build this table can also be a factor if the data being decoded - is not very long. The most common codes are necessarily the - shortest codes, so those codes dominate the decoding time, and hence - the speed. The idea is you can have a shorter table that decodes the - shorter, more probable codes, and then point to subsidiary tables for - the longer codes. The time it costs to decode the longer codes is - then traded against the time it takes to make longer tables. - - This results of this trade are in the variables lbits and dbits - below. lbits is the number of bits the first level table for literal/ - length codes can decode in one step, and dbits is the same thing for - the distance codes. Subsequent tables are also less than or equal to - those sizes. These values may be adjusted either when all of the - codes are shorter than that, in which case the longest code length in - bits is used, or when the shortest code is *longer* than the requested - table size, in which case the length of the shortest code in bits is - used. - - There are two different values for the two tables, since they code a - different number of possibilities each. The literal/length table - codes 286 possible values, or in a flat code, a little over eight - bits. The distance table codes 30 possible values, or a little less - than five bits, flat. The optimum values for speed end up being - about one bit more than those, so lbits is 8+1 and dbits is 5+1. - The optimum values may differ though from machine to machine, and - possibly even between compilers. Your mileage may vary. - */ - - -/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */ -#define BMAX 15 /* maximum bit length of any code */ -#define N_MAX 288 /* maximum number of codes in any set */ - -#ifdef DEBUG_ZLIB - uInt inflate_hufts; -#endif - -local int huft_build(b, n, s, d, e, t, m, zs) -uIntf *b; /* code lengths in bits (all assumed <= BMAX) */ -uInt n; /* number of codes (assumed <= N_MAX) */ -uInt s; /* number of simple-valued codes (0..s-1) */ -uIntf *d; /* list of base values for non-simple codes */ -uIntf *e; /* list of extra bits for non-simple codes */ -inflate_huft * FAR *t; /* result: starting table */ -uIntf *m; /* maximum lookup bits, returns actual */ -z_stream *zs; /* for zalloc function */ -/* Given a list of code lengths and a maximum table size, make a set of - tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR - if the given code set is incomplete (the tables are still built in this - case), Z_DATA_ERROR if the input is invalid (all zero length codes or an - over-subscribed set of lengths), or Z_MEM_ERROR if not enough memory. */ -{ - - uInt a; /* counter for codes of length k */ - uInt c[BMAX+1]; /* bit length count table */ - uInt f; /* i repeats in table every f entries */ - int g; /* maximum code length */ - int h; /* table level */ - register uInt i; /* counter, current code */ - register uInt j; /* counter */ - register int k; /* number of bits in current code */ - int l; /* bits per table (returned in m) */ - register uIntf *p; /* pointer into c[], b[], or v[] */ - inflate_huft *q; /* points to current table */ - struct inflate_huft_s r; /* table entry for structure assignment */ - inflate_huft *u[BMAX]; /* table stack */ - uInt v[N_MAX]; /* values in order of bit length */ - register int w; /* bits before this table == (l * h) */ - uInt x[BMAX+1]; /* bit offsets, then code stack */ - uIntf *xp; /* pointer into x */ - int y; /* number of dummy codes added */ - uInt z; /* number of entries in current table */ - - - /* Generate counts for each bit length */ - p = c; -#define C0 *p++ = 0; -#define C2 C0 C0 C0 C0 -#define C4 C2 C2 C2 C2 - C4 /* clear c[]--assume BMAX+1 is 16 */ - p = b; i = n; - do { - c[*p++]++; /* assume all entries <= BMAX */ - } while (--i); - if (c[0] == n) /* null input--all zero length codes */ - { - *t = (inflate_huft *)Z_NULL; - *m = 0; - return Z_OK; - } - - - /* Find minimum and maximum length, bound *m by those */ - l = *m; - for (j = 1; j <= BMAX; j++) - if (c[j]) - break; - k = j; /* minimum code length */ - if ((uInt)l < j) - l = j; - for (i = BMAX; i; i--) - if (c[i]) - break; - g = i; /* maximum code length */ - if ((uInt)l > i) - l = i; - *m = l; - - - /* Adjust last length count to fill out codes, if needed */ - for (y = 1 << j; j < i; j++, y <<= 1) - if ((y -= c[j]) < 0) - return Z_DATA_ERROR; - if ((y -= c[i]) < 0) - return Z_DATA_ERROR; - c[i] += y; - - - /* Generate starting offsets into the value table for each length */ - x[1] = j = 0; - p = c + 1; xp = x + 2; - while (--i) { /* note that i == g from above */ - *xp++ = (j += *p++); - } - - - /* Make a table of values in order of bit lengths */ - p = b; i = 0; - do { - if ((j = *p++) != 0) - v[x[j]++] = i; - } while (++i < n); - - - /* Generate the Huffman codes and for each, make the table entries */ - x[0] = i = 0; /* first Huffman code is zero */ - p = v; /* grab values in bit order */ - h = -1; /* no tables yet--level -1 */ - w = -l; /* bits decoded == (l * h) */ - u[0] = (inflate_huft *)Z_NULL; /* just to keep compilers happy */ - q = (inflate_huft *)Z_NULL; /* ditto */ - z = 0; /* ditto */ - - /* go through the bit lengths (k already is bits in shortest code) */ - for (; k <= g; k++) - { - a = c[k]; - while (a--) - { - /* here i is the Huffman code of length k bits for value *p */ - /* make tables up to required level */ - while (k > w + l) - { - h++; - w += l; /* previous table always l bits */ - - /* compute minimum size table less than or equal to l bits */ - z = (z = g - w) > (uInt)l ? l : z; /* table size upper limit */ - if ((f = 1 << (j = k - w)) > a + 1) /* try a k-w bit table */ - { /* too few codes for k-w bit table */ - f -= a + 1; /* deduct codes from patterns left */ - xp = c + k; - if (j < z) - while (++j < z) /* try smaller tables up to z bits */ - { - if ((f <<= 1) <= *++xp) - break; /* enough codes to use up j bits */ - f -= *xp; /* else deduct codes from patterns */ - } - } - z = 1 << j; /* table entries for j-bit table */ - - /* allocate and link in new table */ - if ((q = (inflate_huft *)ZALLOC - (zs,z + 1,sizeof(inflate_huft))) == Z_NULL) - { - if (h) - inflate_trees_free(u[0], zs); - return Z_MEM_ERROR; /* not enough memory */ - } - q->word.Nalloc = z + 1; -#ifdef DEBUG_ZLIB - inflate_hufts += z + 1; -#endif - *t = q + 1; /* link to list for huft_free() */ - *(t = &(q->next)) = Z_NULL; - u[h] = ++q; /* table starts after link */ - - /* connect to last table, if there is one */ - if (h) - { - x[h] = i; /* save pattern for backing up */ - r.bits = (Byte)l; /* bits to dump before this table */ - r.exop = (Byte)j; /* bits in this table */ - r.next = q; /* pointer to this table */ - j = i >> (w - l); /* (get around Turbo C bug) */ - u[h-1][j] = r; /* connect to last table */ - } - } - - /* set up table entry in r */ - r.bits = (Byte)(k - w); - if (p >= v + n) - r.exop = 128 + 64; /* out of values--invalid code */ - else if (*p < s) - { - r.exop = (Byte)(*p < 256 ? 0 : 32 + 64); /* 256 is end-of-block */ - r.base = *p++; /* simple code is just the value */ - } - else - { - r.exop = (Byte)e[*p - s] + 16 + 64; /* non-simple--look up in lists */ - r.base = d[*p++ - s]; - } - - /* fill code-like entries with r */ - f = 1 << (k - w); - for (j = i >> w; j < z; j += f) - q[j] = r; - - /* backwards increment the k-bit code i */ - for (j = 1 << (k - 1); i & j; j >>= 1) - i ^= j; - i ^= j; - - /* backup over finished tables */ - while ((i & ((1 << w) - 1)) != x[h]) - { - h--; /* don't need to update q */ - w -= l; - } - } - } - - - /* Return Z_BUF_ERROR if we were given an incomplete table */ - return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK; -} - - -local int inflate_trees_bits(c, bb, tb, z) -uIntf *c; /* 19 code lengths */ -uIntf *bb; /* bits tree desired/actual depth */ -inflate_huft * FAR *tb; /* bits tree result */ -z_stream *z; /* for zfree function */ -{ - int r; - - r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL, tb, bb, z); - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed dynamic bit lengths tree"; - else if (r == Z_BUF_ERROR) - { - inflate_trees_free(*tb, z); - z->msg = "incomplete dynamic bit lengths tree"; - r = Z_DATA_ERROR; - } - return r; -} - - -local int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, z) -uInt nl; /* number of literal/length codes */ -uInt nd; /* number of distance codes */ -uIntf *c; /* that many (total) code lengths */ -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -z_stream *z; /* for zfree function */ -{ - int r; - - /* build literal/length tree */ - if ((r = huft_build(c, nl, 257, cplens, cplext, tl, bl, z)) != Z_OK) - { - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) - { - inflate_trees_free(*tl, z); - z->msg = "incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - return r; - } - - /* build distance tree */ - if ((r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, z)) != Z_OK) - { - if (r == Z_DATA_ERROR) - z->msg = "oversubscribed literal/length tree"; - else if (r == Z_BUF_ERROR) { -#ifdef PKZIP_BUG_WORKAROUND - r = Z_OK; - } -#else - inflate_trees_free(*td, z); - z->msg = "incomplete literal/length tree"; - r = Z_DATA_ERROR; - } - inflate_trees_free(*tl, z); - return r; -#endif - } - - /* done */ - return Z_OK; -} - - -/* build fixed tables only once--keep them here */ -local int fixed_lock = 0; -local int fixed_built = 0; -#define FIXEDH 530 /* number of hufts used by fixed tables */ -local uInt fixed_left = FIXEDH; -local inflate_huft fixed_mem[FIXEDH]; -local uInt fixed_bl; -local uInt fixed_bd; -local inflate_huft *fixed_tl; -local inflate_huft *fixed_td; - - -local voidpf falloc(q, n, s) -voidpf q; /* opaque pointer (not used) */ -uInt n; /* number of items */ -uInt s; /* size of item */ -{ - Assert(s == sizeof(inflate_huft) && n <= fixed_left, - "inflate_trees falloc overflow"); - if (q) s++; /* to make some compilers happy */ - fixed_left -= n; - return (voidpf)(fixed_mem + fixed_left); -} - - -local void ffree(q, p, n) -voidpf q; -voidpf p; -uInt n; -{ - Assert(0, "inflate_trees ffree called!"); - if (q) q = p; /* to make some compilers happy */ -} - - -local int inflate_trees_fixed(bl, bd, tl, td) -uIntf *bl; /* literal desired/actual bit depth */ -uIntf *bd; /* distance desired/actual bit depth */ -inflate_huft * FAR *tl; /* literal/length tree result */ -inflate_huft * FAR *td; /* distance tree result */ -{ - /* build fixed tables if not built already--lock out other instances */ - while (++fixed_lock > 1) - fixed_lock--; - if (!fixed_built) - { - int k; /* temporary variable */ - unsigned c[288]; /* length list for huft_build */ - z_stream z; /* for falloc function */ - - /* set up fake z_stream for memory routines */ - z.zalloc = falloc; - z.zfree = ffree; - z.opaque = Z_NULL; - - /* literal table */ - for (k = 0; k < 144; k++) - c[k] = 8; - for (; k < 256; k++) - c[k] = 9; - for (; k < 280; k++) - c[k] = 7; - for (; k < 288; k++) - c[k] = 8; - fixed_bl = 7; - huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl, &z); - - /* distance table */ - for (k = 0; k < 30; k++) - c[k] = 5; - fixed_bd = 5; - huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd, &z); - - /* done */ - fixed_built = 1; - } - fixed_lock--; - *bl = fixed_bl; - *bd = fixed_bd; - *tl = fixed_tl; - *td = fixed_td; - return Z_OK; -} - - -local int inflate_trees_free(t, z) -inflate_huft *t; /* table to free */ -z_stream *z; /* for zfree function */ -/* Free the malloc'ed tables built by huft_build(), which makes a linked - list of the tables it made, with the links in a dummy first entry of - each table. */ -{ - register inflate_huft *p, *q; - - /* Go through linked list, freeing from the malloced (t[-1]) address. */ - p = t; - while (p != Z_NULL) - { - q = (--p)->next; - ZFREE(z, p, p->word.Nalloc * sizeof(inflate_huft)); - p = q; - } - return Z_OK; -} - -/*+++++*/ -/* infcodes.c -- process literals and length/distance pairs - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* inflate codes private state */ -struct inflate_codes_state { - - /* mode */ - enum { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - START, /* x: set up for LEN */ - LEN, /* i: get length/literal/eob next */ - LENEXT, /* i: getting length extra (have base) */ - DIST, /* i: get distance next */ - DISTEXT, /* i: getting distance extra */ - COPY, /* o: copying bytes in window, waiting for space */ - LIT, /* o: got literal, waiting for output space */ - WASH, /* o: got eob, possibly still output waiting */ - END, /* x: got eob and all data flushed */ - BADCODE} /* x: got error */ - mode; /* current inflate_codes mode */ - - /* mode dependent information */ - uInt len; - union { - struct { - inflate_huft *tree; /* pointer into tree */ - uInt need; /* bits needed */ - } code; /* if LEN or DIST, where in tree */ - uInt lit; /* if LIT, literal */ - struct { - uInt get; /* bits to get for extra */ - uInt dist; /* distance back to copy from */ - } copy; /* if EXT or COPY, where and how much */ - } sub; /* submode */ - - /* mode independent information */ - Byte lbits; /* ltree bits decoded per branch */ - Byte dbits; /* dtree bits decoder per branch */ - inflate_huft *ltree; /* literal/length/eob tree */ - inflate_huft *dtree; /* distance tree */ - -}; - - -local inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z) -uInt bl, bd; -inflate_huft *tl, *td; -z_stream *z; -{ - inflate_codes_statef *c; - - if ((c = (inflate_codes_statef *) - ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL) - { - c->mode = START; - c->lbits = (Byte)bl; - c->dbits = (Byte)bd; - c->ltree = tl; - c->dtree = td; - Tracev((stderr, "inflate: codes new\n")); - } - return c; -} - - -local int inflate_codes(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt j; /* temporary storage */ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - Bytef *f; /* pointer to copy strings from */ - inflate_codes_statef *c = s->sub.decode.codes; /* codes state */ - - /* copy input/output information to locals (UPDATE macro restores) */ - LOAD - - /* process input and output based on current state */ - while (1) switch (c->mode) - { /* waiting for "i:"=input, "o:"=output, "x:"=nothing */ - case START: /* x: set up for LEN */ -#ifndef SLOW - if (m >= 258 && n >= 10) - { - UPDATE - r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z); - LOAD - if (r != Z_OK) - { - c->mode = r == Z_STREAM_END ? WASH : BADCODE; - break; - } - } -#endif /* !SLOW */ - c->sub.code.need = c->lbits; - c->sub.code.tree = c->ltree; - c->mode = LEN; - case LEN: /* i: get length/literal/eob next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e == 0) /* literal */ - { - c->sub.lit = t->base; - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", t->base)); - c->mode = LIT; - break; - } - if (e & 16) /* length */ - { - c->sub.copy.get = e & 15; - c->len = t->base; - c->mode = LENEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - if (e & 32) /* end of block */ - { - Tracevv((stderr, "inflate: end of block\n")); - c->mode = WASH; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = "invalid literal/length code"; - r = Z_DATA_ERROR; - LEAVE - case LENEXT: /* i: getting length extra (have base) */ - j = c->sub.copy.get; - NEEDBITS(j) - c->len += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - c->sub.code.need = c->dbits; - c->sub.code.tree = c->dtree; - Tracevv((stderr, "inflate: length %u\n", c->len)); - c->mode = DIST; - case DIST: /* i: get distance next */ - j = c->sub.code.need; - NEEDBITS(j) - t = c->sub.code.tree + ((uInt)b & inflate_mask[j]); - DUMPBITS(t->bits) - e = (uInt)(t->exop); - if (e & 16) /* distance */ - { - c->sub.copy.get = e & 15; - c->sub.copy.dist = t->base; - c->mode = DISTEXT; - break; - } - if ((e & 64) == 0) /* next table */ - { - c->sub.code.need = e; - c->sub.code.tree = t->next; - break; - } - c->mode = BADCODE; /* invalid code */ - z->msg = "invalid distance code"; - r = Z_DATA_ERROR; - LEAVE - case DISTEXT: /* i: getting distance extra */ - j = c->sub.copy.get; - NEEDBITS(j) - c->sub.copy.dist += (uInt)b & inflate_mask[j]; - DUMPBITS(j) - Tracevv((stderr, "inflate: distance %u\n", c->sub.copy.dist)); - c->mode = COPY; - case COPY: /* o: copying bytes in window, waiting for space */ -#ifndef __TURBOC__ /* Turbo C bug for following expression */ - f = (uInt)(q - s->window) < c->sub.copy.dist ? - s->end - (c->sub.copy.dist - (q - s->window)) : - q - c->sub.copy.dist; -#else - f = q - c->sub.copy.dist; - if ((uInt)(q - s->window) < c->sub.copy.dist) - f = s->end - (c->sub.copy.dist - (q - s->window)); -#endif - while (c->len) - { - NEEDOUT - OUTBYTE(*f++) - if (f == s->end) - f = s->window; - c->len--; - } - c->mode = START; - break; - case LIT: /* o: got literal, waiting for output space */ - NEEDOUT - OUTBYTE(c->sub.lit) - c->mode = START; - break; - case WASH: /* o: got eob, possibly more output */ - FLUSH - if (s->read != s->write) - LEAVE - c->mode = END; - case END: - r = Z_STREAM_END; - LEAVE - case BADCODE: /* x: got error */ - r = Z_DATA_ERROR; - LEAVE - default: - r = Z_STREAM_ERROR; - LEAVE - } -} - - -local void inflate_codes_free(c, z) -inflate_codes_statef *c; -z_stream *z; -{ - ZFREE(z, c, sizeof(struct inflate_codes_state)); - Tracev((stderr, "inflate: codes free\n")); -} - -/*+++++*/ -/* inflate_util.c -- data and routines common to blocks and codes - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* copy as much as possible from the sliding window to the output area */ -local int inflate_flush(s, z, r) -inflate_blocks_statef *s; -z_stream *z; -int r; -{ - uInt n; - Bytef *p, *q; - - /* local copies of source and destination pointers */ - p = z->next_out; - q = s->read; - - /* compute number of bytes to copy as far as end of window */ - n = (uInt)((q <= s->write ? s->write : s->end) - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); - - /* copy as far as end of window */ - zmemcpy(p, q, n); - p += n; - q += n; - - /* see if more to copy at beginning of window */ - if (q == s->end) - { - /* wrap pointers */ - q = s->window; - if (s->write == s->end) - s->write = s->window; - - /* compute bytes to copy */ - n = (uInt)(s->write - q); - if (n > z->avail_out) n = z->avail_out; - if (n && r == Z_BUF_ERROR) r = Z_OK; - - /* update counters */ - z->avail_out -= n; - z->total_out += n; - - /* update check information */ - if (s->checkfn != Z_NULL) - s->check = (*s->checkfn)(s->check, q, n); - - /* copy */ - zmemcpy(p, q, n); - p += n; - q += n; - } - - /* update pointers */ - z->next_out = p; - s->read = q; - - /* done */ - return r; -} - - -/*+++++*/ -/* inffast.c -- process literals and length/distance pairs fast - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* simplify the use of the inflate_huft type with some defines */ -#define base more.Base -#define next more.Next -#define exop word.what.Exop -#define bits word.what.Bits - -/* macros for bit input with no checking and for returning unused bytes */ -#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<>3);p-=c;k&=7;} - -/* Called with number of bytes left to write in window at least 258 - (the maximum string length) and number of input bytes available - at least ten. The ten bytes are six bytes for the longest length/ - distance pair plus four bytes for overloading the bit buffer. */ - -local int inflate_fast(bl, bd, tl, td, s, z) -uInt bl, bd; -inflate_huft *tl, *td; -inflate_blocks_statef *s; -z_stream *z; -{ - inflate_huft *t; /* temporary pointer */ - uInt e; /* extra bits or operation */ - uLong b; /* bit buffer */ - uInt k; /* bits in bit buffer */ - Bytef *p; /* input data pointer */ - uInt n; /* bytes available there */ - Bytef *q; /* output window write pointer */ - uInt m; /* bytes to end of window or read pointer */ - uInt ml; /* mask for literal/length tree */ - uInt md; /* mask for distance tree */ - uInt c; /* bytes to copy */ - uInt d; /* distance back to copy from */ - Bytef *r; /* copy source pointer */ - - /* load input, output, bit values */ - LOAD - - /* initialize masks */ - ml = inflate_mask[bl]; - md = inflate_mask[bd]; - - /* do until not enough input or output space for fast loop */ - do { /* assume called with m >= 258 && n >= 10 */ - /* get literal/length code */ - GRABBITS(20) /* max bits for literal/length code */ - if ((e = (t = tl + ((uInt)b & ml))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - continue; - } - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits for length */ - e &= 15; - c = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * length %u\n", c)); - - /* decode distance base of block to copy */ - GRABBITS(15); /* max bits for distance code */ - e = (t = td + ((uInt)b & md))->exop; - do { - DUMPBITS(t->bits) - if (e & 16) - { - /* get extra bits to add to distance base */ - e &= 15; - GRABBITS(e) /* get extra bits (up to 13) */ - d = t->base + ((uInt)b & inflate_mask[e]); - DUMPBITS(e) - Tracevv((stderr, "inflate: * distance %u\n", d)); - - /* do the copy */ - m -= c; - if ((uInt)(q - s->window) >= d) /* offset before dest */ - { /* just copy */ - r = q - d; - *q++ = *r++; c--; /* minimum count is three, */ - *q++ = *r++; c--; /* so unroll loop a little */ - } - else /* else offset after destination */ - { - e = d - (q - s->window); /* bytes from offset to end */ - r = s->end - e; /* pointer to offset */ - if (c > e) /* if source crosses, */ - { - c -= e; /* copy to end of window */ - do { - *q++ = *r++; - } while (--e); - r = s->window; /* copy rest from start of window */ - } - } - do { /* copy all or what's left */ - *q++ = *r++; - } while (--c); - break; - } - else if ((e & 64) == 0) - e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop; - else - { - z->msg = "invalid distance code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - break; - } - if ((e & 64) == 0) - { - if ((e = (t = t->next + ((uInt)b & inflate_mask[e]))->exop) == 0) - { - DUMPBITS(t->bits) - Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ? - "inflate: * literal '%c'\n" : - "inflate: * literal 0x%02x\n", t->base)); - *q++ = (Byte)t->base; - m--; - break; - } - } - else if (e & 32) - { - Tracevv((stderr, "inflate: * end of block\n")); - UNGRAB - UPDATE - return Z_STREAM_END; - } - else - { - z->msg = "invalid literal/length code"; - UNGRAB - UPDATE - return Z_DATA_ERROR; - } - } while (1); - } while (m >= 258 && n >= 10); - - /* not enough input or output--restore pointers and return */ - UNGRAB - UPDATE - return Z_OK; -} - - -/*+++++*/ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zutil.c,v 1.8 1995/05/03 17:27:12 jloup Exp */ - -char *zlib_version = ZLIB_VERSION; - -char *z_errmsg[] = { -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -""}; - - -/*+++++*/ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: adler32.c,v 1.6 1995/05/03 17:27:08 jloup Exp */ - -#define BASE 65521L /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf) {s1 += *buf++; s2 += s1;} -#define DO2(buf) DO1(buf); DO1(buf); -#define DO4(buf) DO2(buf); DO2(buf); -#define DO8(buf) DO4(buf); DO4(buf); -#define DO16(buf) DO8(buf); DO8(buf); - -/* ========================================================================= */ -uLong adler32(adler, buf, len) - uLong adler; - Bytef *buf; - uInt len; -{ - unsigned long s1 = adler & 0xffff; - unsigned long s2 = (adler >> 16) & 0xffff; - int k; - - if (buf == Z_NULL) return 1L; - - while (len > 0) { - k = len < NMAX ? len : NMAX; - len -= k; - while (k >= 16) { - DO16(buf); - k -= 16; - } - if (k != 0) do { - DO1(buf); - } while (--k); - s1 %= BASE; - s2 %= BASE; - } - return (s2 << 16) | s1; -} diff -Nru a/arch/ppc/coffboot/zlib.h b/arch/ppc/coffboot/zlib.h --- a/arch/ppc/coffboot/zlib.h Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,432 +0,0 @@ -/* $Id: zlib.h,v 1.1 1997/07/31 07:16:15 paulus Exp $ */ - -/* - * This file is derived from zlib.h and zconf.h from the zlib-0.95 - * distribution by Jean-loup Gailly and Mark Adler, with some additions - * by Paul Mackerras to aid in implementing Deflate compression and - * decompression for PPP packets. - */ - -/* - * ==FILEVERSION 960122== - * - * This marker is used by the Linux installation script to determine - * whether an up-to-date version of this file is already installed. - */ - -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 0.95, Aug 16th, 1995. - - Copyright (C) 1995 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - gzip@prep.ai.mit.edu madler@alumni.caltech.edu - */ - -#ifndef _ZLIB_H -#define _ZLIB_H - -/* #include "zconf.h" */ /* included directly here */ - -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* From: zconf.h,v 1.12 1995/05/03 17:27:12 jloup Exp */ - -/* - The library does not install any signal handler. It is recommended to - add at least a handler for SIGSEGV when decompressing; the library checks - the consistency of the input data whenever possible but may go nuts - for some forms of corrupted input. - */ - -/* - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more - * than 64k bytes at a time (needed on systems with 16-bit int). - * Compile with -DUNALIGNED_OK if it is OK to access shorts or ints - * at addresses which are not a multiple of their size. - * Under DOS, -DFAR=far or -DFAR=__far may be needed. - */ - -#ifndef STDC -# if defined(MSDOS) || defined(__STDC__) || defined(__cplusplus) -# define STDC -# endif -#endif - -#ifdef __MWERKS__ /* Metrowerks CodeWarrior declares fileno() in unix.h */ -# include -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif -#endif - -#ifndef FAR -# define FAR -#endif - -/* Maximum value for windowBits in deflateInit2 and inflateInit2 */ -#ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ -#endif - -/* The memory requirements for deflate are (in bytes): - 1 << (windowBits+2) + 1 << (memLevel+9) - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values) - plus a few kilobytes for small objects. For example, if you want to reduce - the default memory requirements from 256K to 128K, compile with - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7" - Of course this will generally degrade compression (there's no free lunch). - - The memory requirements for inflate are (in bytes) 1 << windowBits - that is, 32K for windowBits=15 (default value) plus a few kilobytes - for small objects. -*/ - - /* Type declarations */ - -#ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif -#endif - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -typedef Byte FAR Bytef; -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -#ifdef STDC - typedef void FAR *voidpf; - typedef void *voidp; -#else - typedef Byte FAR *voidpf; - typedef Byte *voidp; -#endif - -/* end of original zconf.h */ - -#define ZLIB_VERSION "0.95P" - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed - data. This version of the library supports only one compression method - (deflation) but other algorithms may be added later and will have the same - stream interface. - - For compression the application must provide the output buffer and - may optionally provide the input buffer for optimization. For decompression, - the application must provide the input buffer and may optionally provide - the output buffer for optimization. - - Compression can be done in a single step if the buffers are large - enough (for example if an input file is mmap'ed), or can be done by - repeated calls of the compression function. In the latter case, the - application must provide more input and/or consume the output - (providing more output space) before each call. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address, uInt nbytes)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidp opaque; /* private data object passed to zalloc and zfree */ - - Byte data_type; /* best guess about the data type: ascii or binary */ - -} z_stream; - -/* - The application must update next_in and avail_in when avail_in has - dropped to zero. It must update next_out and avail_out when avail_out - has dropped to zero. The application must initialize zalloc, zfree and - opaque before calling the init function. All other fields are set by the - compression library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, - pointers returned by zalloc for objects of exactly 65536 bytes *must* - have their offset normalized to zero. The default allocation function - provided by this library ensures this (see zutil.c). To reduce memory - requirements and avoid any allocation of 64K objects, at the expense of - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or - progress reports. After compression, total_in holds the total size of - the uncompressed data and may be saved for use in the decompressor - (particularly if the decompressor wants to decompress everything in - a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_FULL_FLUSH 2 -#define Z_SYNC_FLUSH 3 /* experimental: partial_flush + byte align */ -#define Z_FINISH 4 -#define Z_PACKET_FLUSH 5 -/* See deflate() below for the usage of these constants */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -/* error codes for the compression/decompression functions */ - -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_DEFAULT_STRATEGY 0 - -#define Z_BINARY 0 -#define Z_ASCII 1 -#define Z_UNKNOWN 2 -/* Used to set the data_type field */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -extern char *zlib_version; -/* The application can compare zlib_version and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - */ - - /* basic functions */ - -extern int inflateInit OF((z_stream *strm)); -/* - Initializes the internal stream state for decompression. The fields - zalloc and zfree must be initialized before by the caller. If zalloc and - zfree are set to Z_NULL, inflateInit updates them to use default allocation - functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory. msg is set to null if there is no error message. - inflateInit does not perform any decompression: this will be done by - inflate(). -*/ - - -extern int inflate OF((z_stream *strm, int flush)); -/* - Performs one or both of the following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing - will resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() always provides as much output as possible - (until there is no more input data or no more space in the output buffer). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming - more output, and updating the next_* and avail_* values accordingly. - The application can consume the uncompressed output when it wants, for - example when the output buffer is full (avail_out == 0), or after each - call of inflate(). - - If the parameter flush is set to Z_PARTIAL_FLUSH or Z_PACKET_FLUSH, - inflate flushes as much output as possible to the output buffer. The - flushing behavior of inflate is not specified for values of the flush - parameter other than Z_PARTIAL_FLUSH, Z_PACKET_FLUSH or Z_FINISH, but the - current implementation actually flushes as much output as possible - anyway. For Z_PACKET_FLUSH, inflate checks that once all the input data - has been consumed, it is expecting to see the length field of a stored - block; if not, it returns Z_DATA_ERROR. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step - (a single call of inflate), the parameter flush should be set to - Z_FINISH. In this case all pending input is processed and all pending - output is flushed; avail_out must be large enough to hold all the - uncompressed data. (The size of the uncompressed data may have been saved - by the compressor for this purpose.) The next operation on this stream must - be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine - may be used for the single inflate() call. - - inflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if the end of the - compressed data has been reached and all uncompressed output has been - produced, Z_DATA_ERROR if the input data was corrupted, Z_STREAM_ERROR if - the stream structure was inconsistent (for example if next_in or next_out - was NULL), Z_MEM_ERROR if there was not enough memory, Z_BUF_ERROR if no - progress is possible or if there was not enough room in the output buffer - when Z_FINISH is used. In the Z_DATA_ERROR case, the application may then - call inflateSync to look for a good compression block. */ - - -extern int inflateEnd OF((z_stream *strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any - pending output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - /* advanced functions */ - -extern int inflateInit2 OF((z_stream *strm, - int windowBits)); -/* - This is another version of inflateInit with more compression options. The - fields next_out, zalloc and zfree must be initialized before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library (the value 16 will be allowed soon). The - default value is 15 if inflateInit is used instead. If a compressed stream - with a larger window size is given as input, inflate() will return with - the error code Z_DATA_ERROR instead of trying to allocate a larger window. - - If next_out is not null, the library will use this buffer for the history - buffer; the buffer must either be large enough to hold the entire output - data, or have at least 1< diff -Nru a/arch/ppc/kernel/apus_pci.c b/arch/ppc/kernel/apus_pci.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/apus_pci.c Mon May 21 17:07:05 2001 @@ -0,0 +1,189 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Copyright (C) Michel Dänzer + * + * APUS PCI routines. + * + * Currently, only B/CVisionPPC cards (Permedia2) are supported. + * + * Thanks to Geert Uytterhoeven for the idea: + * Read values from given config space(s) for the first devices, -1 otherwise + * + */ + +#include +#ifdef CONFIG_AMIGA + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "apus_pci.h" + + +/* These definitions are mostly adapted from pm2fb.c */ + +#undef APUS_PCI_MASTER_DEBUG +#ifdef APUS_PCI_MASTER_DEBUG +#define DPRINTK(a,b...) printk(KERN_DEBUG "apus_pci: %s: " a, __FUNCTION__ , ## b) +#else +#define DPRINTK(a,b...) +#endif + +/* + * The _DEFINITIVE_ memory mapping/unmapping functions. + * This is due to the fact that they're changing soooo often... + */ +#define DEFW() wmb() +#define DEFR() rmb() +#define DEFRW() mb() + +#define DEVNO(d) ((d)>>3) +#define FNNO(d) ((d)&7) + + +extern unsigned long powerup_PCI_present; + +static struct pci_controller *apus_hose; + + +__apus +void *pci_io_base(unsigned int bus) +{ + return 0; +} + + +#define cfg_read(val, addr, type, op) *val = op((type)(addr)) +#define cfg_write(val, addr, type, op) op((val), (type *)(addr)); DEFW() +#define cfg_read_bad *val = ~0; +#define cfg_write_bad ; +#define cfg_read_val(val) *val +#define cfg_write_val(val) val + +#define APUS_PCI_OP(rw, size, type, op, mask) \ +__apus int \ +apus_pcibios_##rw##_config_##size(struct pci_dev *dev, int offset, type val) \ +{ \ + int fnno = FNNO(dev->devfn); \ + int devno = DEVNO(dev->devfn); \ + \ + if (dev->bus->number > 0 || devno != 1) { \ + cfg_##rw##_bad; \ + return PCIBIOS_DEVICE_NOT_FOUND; \ + } \ + /* base address + function offset + offset ^ endianness conversion */ \ + cfg_##rw(val, apus_hose->cfg_data + (fnno<<5) + (offset ^ mask), \ + type, op); \ + \ + DPRINTK(#op " b: 0x%x, d: 0x%x, f: 0x%x, o: 0x%x, v: 0x%x\n", \ + dev->bus->number, dev->devfn>>3, dev->devfn&7, \ + offset, cfg_##rw##_val(val)); \ + return PCIBIOS_SUCCESSFUL; \ +} + +APUS_PCI_OP(read, byte, u8 *, readb, 3) +APUS_PCI_OP(read, word, u16 *, readw, 2) +APUS_PCI_OP(read, dword, u32 *, readl, 0) +APUS_PCI_OP(write, byte, u8, writeb, 3) +APUS_PCI_OP(write, word, u16, writew, 2) +APUS_PCI_OP(write, dword, u32, writel, 0) + + +static struct pci_ops apus_pci_ops = { + apus_pcibios_read_config_byte, + apus_pcibios_read_config_word, + apus_pcibios_read_config_dword, + apus_pcibios_write_config_byte, + apus_pcibios_write_config_word, + apus_pcibios_write_config_dword +}; + +static struct resource pci_mem = { "B/CVisionPPC PCI mem", CVPPC_FB_APERTURE_ONE, CVPPC_PCI_CONFIG, IORESOURCE_MEM }; + +void __init +apus_pcibios_fixup(void) +{ +/* struct pci_dev *dev = pci_find_slot(0, 1<<3); + unsigned int reg, val, offset;*/ + + /* FIXME: interrupt? */ + /*dev->interrupt = xxx;*/ + + request_resource(&iomem_resource, &pci_mem); + printk("%s: PCI mem resource requested\n", __FUNCTION__); +} + +static void __init apus_pcibios_fixup_bus(struct pci_bus *bus) +{ + bus->resource[1] = &pci_mem; +} + + +/* + * This is from pm2fb.c again + * + * Check if PCI (B/CVisionPPC) is available, initialize it and set up + * the pcibios_* pointers + */ + + +void __init +apus_setup_pci_ptrs(void) +{ + if (!powerup_PCI_present) { + DPRINTK("no PCI bridge detected\n"); + return; + } + DPRINTK("Phase5 B/CVisionPPC PCI bridge detected.\n"); + + apus_hose = pcibios_alloc_controller(); + if (!apus_hose) { + printk("apus_pci: Can't allocate PCI controller structure\n"); + return; + } + + if (!(apus_hose->cfg_data = ioremap(CVPPC_PCI_CONFIG, 256))) { + printk("apus_pci: unable to map PCI config region\n"); + return; + } + + if (!(apus_hose->cfg_addr = ioremap(CSPPC_PCI_BRIDGE, 256))) { + printk("apus_pci: unable to map PCI bridge\n"); + return; + } + + writel(CSPPCF_BRIDGE_BIG_ENDIAN, apus_hose->cfg_addr + CSPPC_BRIDGE_ENDIAN); + DEFW(); + + writel(CVPPC_REGS_REGION, apus_hose->cfg_data+ PCI_BASE_ADDRESS_0); + DEFW(); + writel(CVPPC_FB_APERTURE_ONE, apus_hose->cfg_data + PCI_BASE_ADDRESS_1); + DEFW(); + writel(CVPPC_FB_APERTURE_TWO, apus_hose->cfg_data + PCI_BASE_ADDRESS_2); + DEFW(); + writel(CVPPC_ROM_ADDRESS, apus_hose->cfg_data + PCI_ROM_ADDRESS); + DEFW(); + + writel(0xef000000 | PCI_COMMAND_IO | PCI_COMMAND_MEMORY | + PCI_COMMAND_MASTER, apus_hose->cfg_data + PCI_COMMAND); + DEFW(); + + apus_hose->first_busno = 0; + apus_hose->last_busno = 0; + apus_hose->ops = &apus_pci_ops; + ppc_md.pcibios_fixup = apus_pcibios_fixup; + ppc_md.pcibios_fixup_bus = apus_pcibios_fixup_bus; + + return; +} + +#endif /* CONFIG_AMIGA */ diff -Nru a/arch/ppc/kernel/apus_pci.h b/arch/ppc/kernel/apus_pci.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/ppc/kernel/apus_pci.h Mon May 21 17:07:05 2001 @@ -0,0 +1,40 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* + * Phase5 CybervisionPPC (TVP4020) definitions for the Permedia2 framebuffer + * driver. + * + * Copyright (c) 1998-1999 Ilario Nardinocchi (nardinoc@CS.UniBO.IT) + * -------------------------------------------------------------------------- + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file README.legal in the main directory of this archive + * for more details. + */ + +#ifndef APUS_PCI_H +#define APUS_PCI_H + + +#include "pci.h" + + +#define CSPPC_PCI_BRIDGE 0xfffe0000 +#define CSPPC_BRIDGE_ENDIAN 0x0000 +#define CSPPC_BRIDGE_INT 0x0010 + +#define CVPPC_PCI_CONFIG 0xfffc0000 +#define CVPPC_ROM_ADDRESS 0xe2000001 +#define CVPPC_REGS_REGION 0xef000000 +#define CVPPC_FB_APERTURE_ONE 0xe0000000 +#define CVPPC_FB_APERTURE_TWO 0xe1000000 +#define CVPPC_FB_SIZE 0x00800000 + +/* CVPPC_BRIDGE_ENDIAN */ +#define CSPPCF_BRIDGE_BIG_ENDIAN 0x02 + +/* CVPPC_BRIDGE_INT */ +#define CSPPCF_BRIDGE_ACTIVE_INT2 0x01 + + +#endif /* APUS_PCI_H */ diff -Nru a/arch/ppc/kernel/apus_setup.c b/arch/ppc/kernel/apus_setup.c --- a/arch/ppc/kernel/apus_setup.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/apus_setup.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/kernel/apus_setup.c * * Copyright (C) 1998, 1999 Jesper Skov diff -Nru a/arch/ppc/kernel/bitops.c b/arch/ppc/kernel/bitops.c --- a/arch/ppc/kernel/bitops.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/bitops.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/checks.c Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #include #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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/chrp_pci.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * CHRP pci routines. */ diff -Nru a/arch/ppc/kernel/chrp_setup.c b/arch/ppc/kernel/chrp_setup.c --- a/arch/ppc/kernel/chrp_setup.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/chrp_setup.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/kernel/setup.c * * Copyright (C) 1995 Linus Torvalds diff -Nru a/arch/ppc/kernel/chrp_time.c b/arch/ppc/kernel/chrp_time.c --- a/arch/ppc/kernel/chrp_time.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/chrp_time.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/i386/kernel/time.c * * Copyright (C) 1991, 1992, 1995 Linus Torvalds 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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/entry.S b/arch/ppc/kernel/entry.S --- a/arch/ppc/kernel/entry.S Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/entry.S Mon May 21 17:07:04 2001 @@ -1,8 +1,7 @@ /* - * arch/ppc/kernel/entry.S - * - * $Id: entry.S,v 1.4 1999/09/14 05:18:14 dmalek Exp $ - * + * BK Id: %F% %I% %G% %U% %#% + */ +/* * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * Rewritten by Cort Dougan (cort@fsmlabs.com) for PReP diff -Nru a/arch/ppc/kernel/error_log.c b/arch/ppc/kernel/error_log.c --- a/arch/ppc/kernel/error_log.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/error_log.c Mon May 21 17:07:05 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * arch/ppc/kernel/error_log.c * * Copyright (c) 2000 Tilmann Bitterberg diff -Nru a/arch/ppc/kernel/error_log.h b/arch/ppc/kernel/error_log.h --- a/arch/ppc/kernel/error_log.h Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/error_log.h Mon May 21 17:07:05 2001 @@ -1,3 +1,6 @@ +/* + * 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/feature.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * arch/ppc/kernel/feature.c * * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) diff -Nru a/arch/ppc/kernel/find_name.c b/arch/ppc/kernel/find_name.c --- a/arch/ppc/kernel/find_name.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/find_name.c Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/galaxy_pci.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * * Copyright (c) 2000 Grant Erickson * All rights reserved. diff -Nru a/arch/ppc/kernel/gemini_pci.c b/arch/ppc/kernel/gemini_pci.c --- a/arch/ppc/kernel/gemini_pci.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/gemini_pci.c Mon May 21 17:07:05 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/gemini_prom.S Mon May 21 17:07:05 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * arch/ppc/kernel/gemini_prom.S * * Not really prom support code (yet), but sort of anti-prom code. The current diff -Nru a/arch/ppc/kernel/gemini_setup.c b/arch/ppc/kernel/gemini_setup.c --- a/arch/ppc/kernel/gemini_setup.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/gemini_setup.c Mon May 21 17:07:05 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/kernel/setup.c * * Copyright (C) 1995 Linus Torvalds diff -Nru a/arch/ppc/kernel/hashtable.S b/arch/ppc/kernel/hashtable.S --- a/arch/ppc/kernel/hashtable.S Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,723 +0,0 @@ -/* - * 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 "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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/head.S Mon May 21 17:07:04 2001 @@ -1,8 +1,7 @@ /* - * arch/ppc/kernel/head.S - * - * $Id: head.S,v 1.154 1999/10/12 00:33:31 cort Exp $ - * + * BK Id: %F% %I% %G% %U% %#% + */ +/* * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * @@ -26,11 +25,12 @@ * */ +#include #include "ppc_asm.h" #include #include -#include #include +#include #ifdef CONFIG_APUS #include @@ -175,7 +175,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 */ @@ -310,9 +310,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 @@ -352,9 +351,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 @@ -503,10 +501,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 */ @@ -514,21 +515,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 @@ -574,10 +577,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 */ @@ -585,22 +591,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 @@ -644,10 +651,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 */ @@ -655,22 +665,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 @@ -1384,7 +1391,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 @@ -1490,7 +1497,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 +1508,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 diff -Nru a/arch/ppc/kernel/head_4xx.S b/arch/ppc/kernel/head_4xx.S --- a/arch/ppc/kernel/head_4xx.S Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/head_4xx.S Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Copyright (c) 1995-1996 Gary Thomas * Initial PowerPC version. * Copyright (c) 1996 Cort Dougan diff -Nru a/arch/ppc/kernel/head_8xx.S b/arch/ppc/kernel/head_8xx.S --- a/arch/ppc/kernel/head_8xx.S Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/head_8xx.S Mon May 21 17:07:03 2001 @@ -1,8 +1,9 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * arch/ppc/kernel/except_8xx.S * - * $Id: head_8xx.S,v 1.4 1999/09/18 18:43:19 dmalek Exp $ - * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP @@ -499,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). */ @@ -507,6 +513,7 @@ #else li r21, 0x00f0 rlwimi r20, r21, 0, 24, 28 + #endif #ifdef CONFIG_8xx_CPU6 li r3, 0x3d80 @@ -601,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 */ @@ -940,6 +947,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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/i8259.c Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #include #include diff -Nru a/arch/ppc/kernel/i8259.h b/arch/ppc/kernel/i8259.h --- a/arch/ppc/kernel/i8259.h Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/i8259.h Mon May 21 17:07:03 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #ifndef _PPC_KERNEL_i8259_H #define _PPC_KERNEL_i8259_H diff -Nru a/arch/ppc/kernel/idle.c b/arch/ppc/kernel/idle.c --- a/arch/ppc/kernel/idle.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/idle.c Mon May 21 17:07:04 2001 @@ -1,6 +1,7 @@ /* - * $Id: idle.c,v 1.68 1999/10/15 18:16:03 cort Exp $ - * + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Idle daemon for PowerPC. Idle daemon will handle any action * that needs to be taken when the system becomes idle. * diff -Nru a/arch/ppc/kernel/indirect_pci.c b/arch/ppc/kernel/indirect_pci.c --- a/arch/ppc/kernel/indirect_pci.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/indirect_pci.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Support for indirect PCI bridges. * * Copyright (C) 1998 Gabriel Paubert. diff -Nru a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c --- a/arch/ppc/kernel/irq.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/irq.c Mon May 21 17:07:04 2001 @@ -1,6 +1,7 @@ /* - * $Id: irq.c,v 1.113 1999/09/17 17:22:56 cort Exp $ - * + * BK Id: %F% %I% %G% %U% %#% + */ +/* * arch/ppc/kernel/irq.c * * Derived from arch/i386/kernel/irq.c @@ -91,6 +92,10 @@ static int cache_bitmask = 0; 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) { 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/local_irq.h Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #ifndef _PPC_KERNEL_LOCAL_IRQ_H #define _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 Mon May 21 17:07:05 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/m8260_setup.c Mon May 21 17:07:04 2001 @@ -1,6 +1,7 @@ /* - * $Id: m8xx_setup.c,v 1.4 1999/09/18 18:40:36 dmalek Exp $ - * + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/kernel/setup.c * * Copyright (C) 1995 Linus Torvalds @@ -51,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)]; @@ -72,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) { @@ -111,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) { @@ -145,7 +132,7 @@ startaddr = simple_strtoul(&cmd[10], NULL, 0); } - m8260_gorom((uint)__pa(__res), startaddr); + m8260_gorom((unsigned int)__pa(__res), startaddr); } void @@ -283,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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/m8xx_setup.c Mon May 21 17:07:04 2001 @@ -1,6 +1,7 @@ /* - * $Id: m8xx_setup.c,v 1.4 1999/09/18 18:40:36 dmalek Exp $ - * + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/kernel/setup.c * * Copyright (C) 1995 Linus Torvalds @@ -260,7 +261,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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/misc.S Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * This file contains miscellaneous low-level functions. * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * @@ -335,9 +338,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 @@ -357,28 +360,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 @@ -1093,6 +1074,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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/mk_defs.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * This program is used to generate definitions needed by * assembly language modules. * @@ -114,5 +117,6 @@ 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)); 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/oak_setup.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * * Copyright (c) 1999-2000 Grant Erickson * diff -Nru a/arch/ppc/kernel/oak_setup.h b/arch/ppc/kernel/oak_setup.h --- a/arch/ppc/kernel/oak_setup.h Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/oak_setup.h Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * * Copyright (c) 1999-2000 Grant Erickson * diff -Nru a/arch/ppc/kernel/open_pic.c b/arch/ppc/kernel/open_pic.c --- a/arch/ppc/kernel/open_pic.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/open_pic.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * arch/ppc/kernel/open_pic.c -- OpenPIC Interrupt Handling * * Copyright (C) 1997 Geert Uytterhoeven @@ -44,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); @@ -432,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; @@ -443,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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/open_pic.h Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * arch/ppc/kernel/open_pic.h -- OpenPIC Interrupt Handling * * Copyright (C) 1997 Geert Uytterhoeven @@ -15,6 +18,14 @@ #include #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; 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/open_pic_defs.h Mon May 21 17:07:05 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/openpic.h -- OpenPIC definitions * * Copyright (C) 1997 Geert Uytterhoeven @@ -41,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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/pci-dma.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/pci.c Mon May 21 17:07:04 2001 @@ -1,5 +1,7 @@ /* - * $Id: pci.c,v 1.64 1999/09/17 18:01:53 cort Exp $ + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Common pmac/prep/chrp pci routines. -- Cort */ @@ -26,7 +28,7 @@ #include "pci.h" -#define DEBUG +#undef DEBUG #ifdef DEBUG #define DBG(x...) printk(x) @@ -38,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 @@ -131,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 @@ -343,6 +348,10 @@ (!ppc_md.pcibios_enable_device_hook || !ppc_md.pcibios_enable_device_hook(dev, 1))) pci_assign_resource(dev, idx); + if (!r->start && r->end && + (!ppc_md.pcibios_enable_device_hook || + !ppc_md.pcibios_enable_device_hook(dev, 1))) + pci_assign_resource(dev, idx); } if (0) { /* don't assign ROMs */ @@ -385,6 +394,8 @@ return 0; } +static int next_controller_index; + struct pci_controller * __init pcibios_alloc_controller(void) { @@ -396,6 +407,8 @@ *hose_tail = hose; hose_tail = &hose->next; + hose->index = next_controller_index++; + return hose; } @@ -710,7 +723,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(); @@ -752,6 +769,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) { @@ -887,7 +923,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) @@ -897,6 +933,142 @@ #endif } +/* + * Return the index of the PCI controller for device pdev. + */ +int pci_controller_num(struct pci_dev *dev) +{ + struct pci_controller *hose = (struct pci_controller *) dev->sysdata; + + return hose->index; +} + +/* + * Platform support for /proc/bus/pci/X/Y mmap()s, + * modelled on the sparc64 implementation by Dave Miller. + * -- paulus. + */ + +/* + * Adjust vm_pgoff of VMA such that it is the physical page offset + * corresponding to the 32-bit pci bus offset for DEV requested by the user. + * + * Basically, the user finds the base address for his device which he wishes + * to mmap. They read the 32-bit value from the config space base register, + * add whatever PAGE_SIZE multiple offset they wish, and feed this into the + * offset parameter of mmap on /proc/bus/pci/XXX for that device. + * + * Returns negative error code on failure, zero on success. + */ +static __inline__ int +__pci_mmap_make_offset(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state) +{ + struct pci_controller *hose = (struct pci_controller *) dev->sysdata; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + int i, res_bit; + + if (hose == 0) + return -EINVAL; /* should never happen */ + + /* If memory, add on the PCI bridge address offset */ + if (mmap_state == pci_mmap_mem) { + offset += hose->pci_mem_offset; + res_bit = IORESOURCE_MEM; + } else { + offset += (unsigned long)hose->io_base_virt - isa_io_base; + res_bit = IORESOURCE_IO; + } + + /* + * Check that the offset requested corresponds to one of the + * resources of the device. + */ + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { + struct resource *rp = &dev->resource[i]; + int flags = rp->flags; + + /* treat ROM as memory (should be already) */ + if (i == PCI_ROM_RESOURCE) + flags |= IORESOURCE_MEM; + + /* Active and same type? */ + if ((flags & res_bit) == 0) + continue; + + /* In the range of this resource? */ + if (offset < (rp->start & PAGE_MASK) || offset > rp->end) + continue; + + /* found it! construct the final physical address */ + if (mmap_state == pci_mmap_io) + offset += isa_io_base; + + vma->vm_pgoff = offset >> PAGE_SHIFT; + return 0; + } + + return -EINVAL; +} + +/* + * Set vm_flags of VMA, as appropriate for this architecture, for a pci device + * mapping. + */ +static __inline__ void +__pci_mmap_set_flags(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state) +{ + vma->vm_flags |= VM_SHM | VM_LOCKED | VM_IO; +} + +/* + * Set vm_page_prot of VMA, as appropriate for this architecture, for a pci + * device mapping. + */ +static __inline__ void +__pci_mmap_set_pgprot(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine) +{ + int prot = pgprot_val(vma->vm_page_prot); + + /* XXX would be nice to have a way to ask for write-through */ + prot |= _PAGE_NO_CACHE; + if (!write_combine) + prot |= _PAGE_GUARDED; + vma->vm_page_prot = __pgprot(prot); +} + +/* + * Perform the actual remap of the pages for a PCI device mapping, as + * appropriate for this architecture. The region in the process to map + * is described by vm_start and vm_end members of VMA, the base physical + * address is found in vm_pgoff. + * The pci device structure is provided so that architectures may make mapping + * decisions on a per-device or per-bus basis. + * + * Returns a negative error code on failure, zero on success. + */ +int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, + int write_combine) +{ + int ret; + + ret = __pci_mmap_make_offset(dev, vma, mmap_state); + if (ret < 0) + return ret; + + __pci_mmap_set_flags(dev, vma, mmap_state); + __pci_mmap_set_pgprot(dev, vma, mmap_state, write_combine); + + ret = remap_page_range(vma->vm_start, vma->vm_pgoff << PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot); + + return ret; +} + + /* Obsolete functions. Should be removed once the symbios driver * is fixed */ @@ -931,12 +1103,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 @@ -944,12 +1116,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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/pci.h Mon May 21 17:07:03 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #ifndef __PPC_KERNEL_PCI_H__ #define __PPC_KERNEL_PCI_H__ @@ -20,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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/pmac_backlight.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Miscellaneous procedures for dealing with the PowerMac hardware. * Contains support for the backlight. * diff -Nru a/arch/ppc/kernel/pmac_nvram.c b/arch/ppc/kernel/pmac_nvram.c --- a/arch/ppc/kernel/pmac_nvram.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/pmac_nvram.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Miscellaneous procedures for dealing with the PowerMac hardware. */ #include diff -Nru a/arch/ppc/kernel/pmac_pci.c b/arch/ppc/kernel/pmac_pci.c --- a/arch/ppc/kernel/pmac_pci.c Mon May 21 17:07:05 2001 +++ b/arch/ppc/kernel/pmac_pci.c Mon May 21 17:07:05 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Support for PCI bridges found on Power Macintoshes. * At present the "bandit" and "chaos" bridges are supported. * Fortunately you access configuration space in the same diff -Nru a/arch/ppc/kernel/pmac_pic.c b/arch/ppc/kernel/pmac_pic.c --- a/arch/ppc/kernel/pmac_pic.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/pmac_pic.c Mon May 21 17:07:03 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #include #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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/pmac_pic.h Mon May 21 17:07:03 2001 @@ -1,3 +1,6 @@ +/* + * 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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/pmac_setup.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/kernel/setup.c * * PowerPC version diff -Nru a/arch/ppc/kernel/pmac_time.c b/arch/ppc/kernel/pmac_time.c --- a/arch/ppc/kernel/pmac_time.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/pmac_time.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Support for periodic interrupts (100 per second) and for getting * the current time from the RTC on Power Macintoshes. * diff -Nru a/arch/ppc/kernel/ppc-stub.c b/arch/ppc/kernel/ppc-stub.c --- a/arch/ppc/kernel/ppc-stub.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/ppc-stub.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ -/* $Id: ppc-stub.c,v 1.6 1999/08/12 22:18:11 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * ppc-stub.c: KGDB support for the Linux kernel. * * adapted from arch/sparc/kernel/sparc-stub.c for the PowerPC diff -Nru a/arch/ppc/kernel/ppc4xx_pic.c b/arch/ppc/kernel/ppc4xx_pic.c --- a/arch/ppc/kernel/ppc4xx_pic.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/ppc4xx_pic.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * * Copyright (c) 1999 Grant Erickson * diff -Nru a/arch/ppc/kernel/ppc4xx_pic.h b/arch/ppc/kernel/ppc4xx_pic.h --- a/arch/ppc/kernel/ppc4xx_pic.h Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/ppc4xx_pic.h Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * * Copyright (c) 1999 Grant Erickson * diff -Nru a/arch/ppc/kernel/ppc8260_pic.c b/arch/ppc/kernel/ppc8260_pic.c --- a/arch/ppc/kernel/ppc8260_pic.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/ppc8260_pic.c Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #include #include diff -Nru a/arch/ppc/kernel/ppc8260_pic.h b/arch/ppc/kernel/ppc8260_pic.h --- a/arch/ppc/kernel/ppc8260_pic.h Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/ppc8260_pic.h Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #ifndef _PPC_KERNEL_PPC8260_H #define _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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/ppc8xx_pic.c Mon May 21 17:07:03 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/ppc8xx_pic.h Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/ppc_asm.h Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * arch/ppc/kernel/ppc_asm.h * * Definitions used by various bits of low-level assembly code on PowerPC. diff -Nru a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c --- a/arch/ppc/kernel/ppc_htab.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/ppc_htab.c Mon May 21 17:07:04 2001 @@ -1,6 +1,7 @@ /* - * $Id: ppc_htab.c,v 1.29 1999/09/10 05:05:50 paulus Exp $ - * + * BK Id: %F% %I% %G% %U% %#% + */ +/* * PowerPC hash table management proc entry. Will show information * about the current hash table and will allow changes to it. * @@ -40,9 +41,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 @@ -109,7 +113,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]; @@ -159,30 +163,43 @@ */ 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; - } + unsigned int ctx, mctx; + + if (!ptr->v) + continue; + /* make sure someone is using this context/vsid */ + /* first undo the esid skew */ + mctx = ((ptr->vsid - (ptr->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++; + break; } - if ( !valid ) - { - zombie_ptes++; - continue; + } + if ( !valid ) { + if (zombie_ptes++ == 0){ + struct task_struct *q; + + printk("zombie pte %x %x, vsid=%x mctx=%x\n", + ((unsigned int *)ptr)[0], + ((unsigned int *)ptr)[1], + ptr->vsid, mctx); + printk("contexts in use:\n"); + for_each_task(q) { + if (q->mm == NULL) continue; + printk("%ld (%lx)\n", + q->mm->context, + (q->mm->context * 897) & 0xfffff); + } } - /* user not allowed read or write */ - if (ptr->pp == PP_RWXX) - kptes++; - else - uptes++; - if (ptr->h == 1) - overflow++; } } @@ -194,29 +211,31 @@ "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); 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; diff -Nru a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c --- a/arch/ppc/kernel/ppc_ksyms.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/ppc_ksyms.c Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #include #include #include @@ -90,20 +93,13 @@ EXPORT_SYMBOL(kernel_flag); #endif /* CONFIG_SMP */ -#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) -EXPORT_SYMBOL_NOVERS(isa_io_base); -EXPORT_SYMBOL_NOVERS(isa_mem_base); -EXPORT_SYMBOL_NOVERS(pci_dram_offset); -#endif EXPORT_SYMBOL(ISA_DMA_THRESHOLD); EXPORT_SYMBOL_NOVERS(DMA_MODE_READ); EXPORT_SYMBOL(DMA_MODE_WRITE); -#ifndef CONFIG_8xx #if defined(CONFIG_ALL_PPC) EXPORT_SYMBOL(_prep_type); EXPORT_SYMBOL(ucSystemType); #endif -#endif #if !__INLINE_BITOPS EXPORT_SYMBOL(set_bit); @@ -173,6 +169,9 @@ #endif #ifdef CONFIG_PCI +EXPORT_SYMBOL_NOVERS(isa_io_base); +EXPORT_SYMBOL_NOVERS(isa_mem_base); +EXPORT_SYMBOL_NOVERS(pci_dram_offset); EXPORT_SYMBOL(pci_alloc_consistent); EXPORT_SYMBOL(pci_free_consistent); #endif /* CONFIG_PCI */ @@ -214,9 +213,6 @@ EXPORT_SYMBOL(synchronize_irq); #endif -#ifndef CONFIG_MACH_SPECIFIC -EXPORT_SYMBOL(_machine); -#endif EXPORT_SYMBOL(ppc_md); #ifdef CONFIG_ADB @@ -247,11 +243,10 @@ EXPORT_SYMBOL(set_backlight_enable); EXPORT_SYMBOL(register_backlight_controller); #endif /* CONFIG_PMAC_BACKLIGHT */ -#ifndef CONFIG_MACH_SPECIFIC -EXPORT_SYMBOL_NOVERS(have_of); -#endif /* CONFIG_MACH_SPECIFIC */ #if defined(CONFIG_ALL_PPC) +EXPORT_SYMBOL_NOVERS(have_of); EXPORT_SYMBOL_NOVERS(sys_ctrler); +EXPORT_SYMBOL(_machine); EXPORT_SYMBOL(find_devices); EXPORT_SYMBOL(find_type_devices); EXPORT_SYMBOL(find_compatible_devices); @@ -365,11 +360,10 @@ EXPORT_SYMBOL(do_softirq); 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 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 Mon May 21 17:07:05 2001 @@ -0,0 +1,72 @@ +/* + * 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 + +/* + * 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)) + +EXPORT_SYMBOL(get_property); + +__init +unsigned long +prom_init(int r3, int r4, prom_entry dummy) +{ + 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; +} + +__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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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> 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; } @@ -709,16 +711,16 @@ prom_alloc_htab(); #endif -#ifdef CONFIG_SMP - prom_hold_cpus(mem); -#endif - mem = check_display(mem); prom_print(RELOC("copying OF device tree...")); mem = copy_device_tree(mem, mem + (1<<20)); prom_print(RELOC("done\n")); +#ifdef CONFIG_SMP + prom_hold_cpus(mem); +#endif + RELOC(klimit) = (char *) (mem - offset); /* If we are already running at 0xc0000000, we assume we were loaded by @@ -1264,10 +1266,7 @@ np->name = get_property(np, "name", 0); np->type = get_property(np, "device_type", 0); -#if 0 - np->n_addr_cells = naddrc; - np->n_size_cells = nsizec; -#endif + /* get the device addresses and interrupts */ if (ifunc != NULL) { mem_start = ifunc(np, mem_start, naddrc, nsizec); @@ -1283,16 +1282,6 @@ ip = (int *) get_property(np, "#size-cells", 0); if (ip != NULL) nsizec = *ip; -#if 0 - if (np->parent == NULL) { - /* - * Set the n_addr/size_cells on the root to its - * own values, rather than 0. - */ - np->n_addr_cells = naddrc; - np->n_size_cells = nsizec; - } -#endif /* the f50 sets the name to 'display' and 'compatible' to what we * expect for the name -- Cort @@ -2018,13 +2007,12 @@ { struct property *pp; - for (pp = np->properties; pp != 0; pp = pp->next) { - if (name && strcmp(pp->name, name) == 0) { + 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/ptrace.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/kernel/ptrace.c * * PowerPC version @@ -25,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. */ @@ -156,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; @@ -190,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; @@ -312,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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/qspan_pci.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * QSpan pci routines. * Most 8xx boards use the QSpan PCI bridge. The config address register * is located 0x500 from the base of the bridge control/status registers. diff -Nru a/arch/ppc/kernel/residual.c b/arch/ppc/kernel/residual.c --- a/arch/ppc/kernel/residual.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/residual.c Mon May 21 17:07:04 2001 @@ -1,6 +1,7 @@ /* - * $Id: residual.c,v 1.17 1999/09/27 18:40:23 cort Exp $ - * + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Code to deal with the PReP residual data. * * Written by: Cort Dougan (cort@cs.nmt.edu) 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 2001 @@ -0,0 +1,692 @@ +/* + * 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" + +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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/semaphore.c Mon May 21 17:07:04 2001 @@ -1,6 +1,7 @@ /* - * $Id: semaphore.c,v 1.1 1999/08/31 15:11:44 cort Exp $ - * + * BK Id: %F% %I% %G% %U% %#% + */ +/* * PowerPC-specific semaphore code. * * Copyright (C) 1999 Cort Dougan diff -Nru a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c --- a/arch/ppc/kernel/setup.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/setup.c Mon May 21 17:07:04 2001 @@ -1,5 +1,7 @@ /* - * $Id: setup.c,v 1.160 1999/10/08 01:56:38 paulus Exp $ + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Common prep/pmac/chrp boot and setup code. */ @@ -43,7 +45,7 @@ #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, @@ -55,30 +57,90 @@ 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); + #ifdef CONFIG_XMON extern void xmon_map_scc(void); #endif @@ -92,10 +154,10 @@ unsigned long ISA_DMA_THRESHOLD; unsigned long DMA_MODE_READ, DMA_MODE_WRITE; -#ifndef CONFIG_MACH_SPECIFIC +#ifdef CONFIG_ALL_PPC int _machine = 0; int have_of = 0; -#endif /* CONFIG_MACH_SPECIFIC */ +#endif /* CONFIG_ALL_PPC */ #ifdef CONFIG_MAGIC_SYSRQ unsigned long SYSRQ_KEY; @@ -179,35 +241,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) { @@ -216,6 +258,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)]) @@ -266,8 +311,11 @@ 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()); +#ifdef CONFIG_TAU + temp = cpu_temp_both(i); + len += sprintf(len+buffer, "temperature \t: %d-%d C\n", + temp & 0xff, temp >> 16); +#endif break; case 0x0009: /* 604e/604r */ case 0x000A: @@ -287,6 +335,11 @@ len += sprintf(len+buffer, ", altivec supported"); #endif /* CONFIG_ALTIVEC */ len += sprintf(len+buffer, ")\n"); +#ifdef CONFIG_TAU + temp = cpu_temp_both(i); + len += sprintf(len+buffer, "temperature \t: %d-%d C\n", + temp & 0xff, temp >> 16); +#endif break; case 0x0020: len += sprintf(len+buffer, "403G"); @@ -411,7 +464,7 @@ return len; } -#ifndef CONFIG_MACH_SPECIFIC +#ifdef CONFIG_ALL_PPC void __init intuit_machine_type(void) { @@ -433,7 +486,7 @@ } } } -#endif /* CONFIG_MACH_SPECIFIC */ +#endif /* CONFIG_ALL_PPC */ /* * Find out what kind of machine we're on and save any data we need @@ -447,36 +500,26 @@ if ( ppc_md.progress ) ppc_md.progress("id mach(): start", 0x100); -#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) && !defined(CONFIG_8260) -#ifndef CONFIG_MACH_SPECIFIC +#if defined(CONFIG_ALL_PPC) /* if we didn't get any bootinfo telling us what we are... */ if ( _machine == 0 ) { - /* boot loader will tell us if we're APUS */ - if ( r3 == 0x61707573 ) - { - _machine = _MACH_apus; - r3 = 0; - } /* prep boot loader tells us if we're prep or not */ - else if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) + if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) { _machine = _MACH_prep; } else have_of = 1; } -#endif /* CONFIG_MACH_SPECIFIC */ if ( have_of ) { /* prom_init has already been called from __start */ if (boot_infos) relocate_nodes(); -#ifndef CONFIG_MACH_SPECIFIC /* we need to set _machine before calling finish_device_tree */ if (_machine == 0) intuit_machine_type(); -#endif /* CONFIG_MACH_SPECIFIC */ finish_device_tree(); /* * If we were booted via quik, r3 points to the physical @@ -488,16 +531,18 @@ * are used for initrd_start and initrd_size, * otherwise they contain 0xdeadbeef. */ - cmd_line[0] = 0; 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) { /* booted by BootX - check for ramdisk */ - if (boot_infos->kernelParamsOffset != 0) + if (boot_infos->kernelParamsOffset != 0) { + cmd_line[0] = 0; strncpy(cmd_line, (char *) boot_infos + boot_infos->kernelParamsOffset, sizeof(cmd_line)); + } #ifdef CONFIG_BLK_DEV_INITRD if (boot_infos->ramDisk) { initrd_start = (unsigned long) boot_infos @@ -521,17 +566,20 @@ initrd_below_start_ok = 1; } #endif - cmd_line[0] = 0; chosen = find_devices("chosen"); if (chosen != NULL) { p = get_property(chosen, "bootargs", NULL); - if (p != NULL) + if (p && *p) { + cmd_line[0] = 0; strncpy(cmd_line, p, sizeof(cmd_line)); + } } } cmd_line[sizeof(cmd_line) - 1] = 0; } +#endif /* CONFIG_ALL_PPC */ +#if defined(CONFIG_ALL_PPC) switch (_machine) { case _MACH_Pmac: @@ -543,36 +591,46 @@ case _MACH_chrp: chrp_init(r3, r4, r5, r6, r7); break; -#ifdef CONFIG_APUS - case _MACH_apus: - apus_init(r3, r4, r5, r6, r7); - break; -#endif -#ifdef CONFIG_GEMINI - case _MACH_gemini: - gemini_init(r3, r4, r5, r6, r7); - break; -#endif 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_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/machine type has been identified for identify_machine()!" +#endif /* Check for nobats option (used in mapin_ram). */ if (strstr(cmd_line, "nobats")) { extern int __map_without_bats; __map_without_bats = 1; } -#else -#if defined(CONFIG_4xx) - oak_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); -#else -#error "No board type has been defined for identify_machine()!" -#endif /* CONFIG_4xx */ -#endif /* !CONFIG_4xx && !CONFIG_8xx */ /* Look for mem= option on command line */ if (strstr(cmd_line, "mem=")) { @@ -604,6 +662,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; @@ -643,12 +708,17 @@ initrd_end = data[0] + rec->size; break; #endif /* CONFIG_BLK_DEV_INITRD */ -#ifndef CONFIG_MACH_SPECIFIC +#ifdef CONFIG_ALL_PPC case BI_MACHTYPE: _machine = data[0]; have_of = data[1]; break; -#endif /* CONFIG_MACH_SPECIFIC */ +#endif /* CONFIG_ALL_PPC */ +#ifdef CONFIG_SPRUCE + case BI_MEMSIZE: + boot_mem_size = data[0]; + break; +#endif /* CONFIG_SPRUCE */ } } diff -Nru a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c --- a/arch/ppc/kernel/signal.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/signal.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/kernel/signal.c * * PowerPC version diff -Nru a/arch/ppc/kernel/sleep.S b/arch/ppc/kernel/sleep.S --- a/arch/ppc/kernel/sleep.S Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/sleep.S Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * This file contains sleep low-level functions for PowerBook G3. * Copyright (C) 1999 Benjamin Herrenschmidt (benh@kernel.crashing.org) * and Paul Mackerras (paulus@cs.anu.edu.au). @@ -191,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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/smp.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Smp support for ppc. * * Written by Cort Dougan (cort@cs.nmt.edu) borrowing a great diff -Nru a/arch/ppc/kernel/softemu8xx.c b/arch/ppc/kernel/softemu8xx.c --- a/arch/ppc/kernel/softemu8xx.c Mon May 21 17:07:05 2001 +++ b/arch/ppc/kernel/softemu8xx.c Mon May 21 17:07:05 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Software emulation of some PPC instructions for the 8xx core. * * Copyright (C) 1998 Dan Malek (dmalek@jlc.net) 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 2001 +++ b/arch/ppc/kernel/syscalls.c Mon May 21 17:07:05 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/kernel/sys_ppc.c * * PowerPC version 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 Mon May 21 17:07:05 2001 @@ -0,0 +1,231 @@ +/* + * 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); + + tau_initialized = 1; +} + +int __init TAU_init(void) +{ + switch (PVR_VER(_get_PVR())){ + case 0x0008: /* 740/750 */ + case 0x1008: /* 750P */ + case 0x000C: /* G4 */ + break; + default: + printk("Thermal assist unit not available\n"); + 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"); + + 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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/kernel/time.c Mon May 21 17:07:03 2001 @@ -1,5 +1,7 @@ /* - * $Id: time.c,v 1.57 1999/10/21 03:08:16 cort Exp $ + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Common time routines among all ppc machines. * * Written by Cort Dougan (cort@cs.nmt.edu) to merge 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/traps.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/kernel/traps.c * * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) @@ -372,12 +375,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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/walnut_setup.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * * Copyright (c) 1999-2000 Grant Erickson * diff -Nru a/arch/ppc/kernel/walnut_setup.h b/arch/ppc/kernel/walnut_setup.h --- a/arch/ppc/kernel/walnut_setup.h Mon May 21 17:07:05 2001 +++ b/arch/ppc/kernel/walnut_setup.h Mon May 21 17:07:05 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * * Copyright (c) 1999-2000 Grant Erickson * diff -Nru a/arch/ppc/kernel/xics.c b/arch/ppc/kernel/xics.c --- a/arch/ppc/kernel/xics.c Mon May 21 17:07:05 2001 +++ b/arch/ppc/kernel/xics.c Mon May 21 17:07:05 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * arch/ppc/kernel/xics.c * * Copyright 2000 IBM Corporation. diff -Nru a/arch/ppc/kernel/xics.h b/arch/ppc/kernel/xics.h --- a/arch/ppc/kernel/xics.h Mon May 21 17:07:04 2001 +++ b/arch/ppc/kernel/xics.h Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * arch/ppc/kernel/xics.h * * Copyright 2000 IBM Corporation. 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:05 2001 @@ -0,0 +1,381 @@ +/* + * 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" + +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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/lib/Makefile Mon May 21 17:07:04 2001 @@ -1,3 +1,5 @@ +# 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/lib/checksum.S Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * This file contains assembly-language implementations * of IP-style 1's complement checksum routines. * diff -Nru a/arch/ppc/lib/locks.c b/arch/ppc/lib/locks.c --- a/arch/ppc/lib/locks.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/lib/locks.c Mon May 21 17:07:03 2001 @@ -1,6 +1,7 @@ /* - * $Id: locks.c,v 1.25 1999/09/10 10:40:13 davem Exp $ - * + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Locks for smp ppc * * Written by Cort Dougan (cort@cs.nmt.edu) diff -Nru a/arch/ppc/lib/strcase.c b/arch/ppc/lib/strcase.c --- a/arch/ppc/lib/strcase.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/lib/strcase.c Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #include int strcasecmp(const char *s1, const char *s2) diff -Nru a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S --- a/arch/ppc/lib/string.S Mon May 21 17:07:04 2001 +++ b/arch/ppc/lib/string.S Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * String handling functions for PowerPC. * * Copyright (C) 1996 Paul Mackerras. diff -Nru a/arch/ppc/math-emu/Makefile b/arch/ppc/math-emu/Makefile --- a/arch/ppc/math-emu/Makefile Mon May 21 17:07:03 2001 +++ b/arch/ppc/math-emu/Makefile Mon May 21 17:07:03 2001 @@ -1,3 +1,5 @@ +# 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/double.h Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fabs.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fabs.c,v 1.1 1999/08/23 18:59:21 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:05 2001 +++ b/arch/ppc/math-emu/fadd.c Mon May 21 17:07:05 2001 @@ -1,6 +1,6 @@ -/* $Id: fadd.c,v 1.1 1999/08/23 18:59:22 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fadds.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fadds.c,v 1.1 1999/08/23 18:59:25 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/math-emu/fcmpo.c Mon May 21 17:07:03 2001 @@ -1,6 +1,6 @@ -/* $Id: fcmpo.c,v 1.1 1999/08/23 18:59:26 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fcmpu.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fcmpu.c,v 1.1 1999/08/23 18:59:28 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fctiw.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fctiw.c,v 1.1 1999/08/23 18:59:30 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:05 2001 +++ b/arch/ppc/math-emu/fctiwz.c Mon May 21 17:07:05 2001 @@ -1,6 +1,6 @@ -/* $Id: fctiwz.c,v 1.1 1999/08/23 18:59:31 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fdiv.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fdiv.c,v 1.1 1999/08/23 18:59:33 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fdivs.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fdivs.c,v 1.1 1999/08/23 18:59:35 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fmadd.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fmadd.c,v 1.1 1999/08/23 18:59:36 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fmadds.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fmadds.c,v 1.1 1999/08/23 18:59:38 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fmr.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fmr.c,v 1.1 1999/08/23 18:59:40 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/math-emu/fmsub.c Mon May 21 17:07:03 2001 @@ -1,6 +1,6 @@ -/* $Id: fmsub.c,v 1.1 1999/08/23 18:59:41 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fmsubs.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fmsubs.c,v 1.1 1999/08/23 18:59:42 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fmul.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fmul.c,v 1.1 1999/08/23 18:59:44 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fmuls.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fmuls.c,v 1.1 1999/08/23 18:59:45 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fnabs.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fnabs.c,v 1.1 1999/08/23 18:59:47 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/math-emu/fneg.c Mon May 21 17:07:03 2001 @@ -1,6 +1,6 @@ -/* $Id: fneg.c,v 1.1 1999/08/23 18:59:48 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/math-emu/fnmadd.c Mon May 21 17:07:03 2001 @@ -1,6 +1,6 @@ -/* $Id: fnmadd.c,v 1.1 1999/08/23 18:59:50 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fnmadds.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fnmadds.c,v 1.1 1999/08/23 18:59:51 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/math-emu/fnmsub.c Mon May 21 17:07:03 2001 @@ -1,6 +1,6 @@ -/* $Id: fnmsub.c,v 1.1 1999/08/23 18:59:53 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fnmsubs.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fnmsubs.c,v 1.1 1999/08/23 18:59:54 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fres.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fres.c,v 1.1 1999/08/23 18:59:56 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/frsp.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: frsp.c,v 1.1 1999/08/23 18:59:57 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/frsqrte.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: frsqrte.c,v 1.1 1999/08/23 18:59:58 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fsel.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fsel.c,v 1.1 1999/08/23 18:59:59 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/math-emu/fsqrt.c Mon May 21 17:07:03 2001 @@ -1,6 +1,6 @@ -/* $Id: fsqrt.c,v 1.1 1999/08/23 19:00:01 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fsqrts.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fsqrts.c,v 1.1 1999/08/23 19:00:03 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fsub.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fsub.c,v 1.1 1999/08/23 19:00:05 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/fsubs.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: fsubs.c,v 1.1 1999/08/23 19:00:07 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/lfd.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: lfd.c,v 1.1 1999/08/23 19:00:08 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/lfs.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: lfs.c,v 1.1 1999/08/23 19:00:10 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/math.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ -/* $Id: math.c,v 1.1 1999/08/23 19:00:11 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * arch/ppc/math-emu/math.c * * Copyright (C) 1999 Eddie C. Dost (ecd@atecom.com) diff -Nru a/arch/ppc/math-emu/mcrfs.c b/arch/ppc/math-emu/mcrfs.c --- a/arch/ppc/math-emu/mcrfs.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/math-emu/mcrfs.c Mon May 21 17:07:03 2001 @@ -1,6 +1,6 @@ -/* $Id: mcrfs.c,v 1.1 1999/08/23 19:00:13 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/mffs.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: mffs.c,v 1.1 1999/08/23 19:00:14 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/mtfsb0.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: mtfsb0.c,v 1.1 1999/08/23 19:00:16 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/math-emu/mtfsb1.c Mon May 21 17:07:03 2001 @@ -1,6 +1,6 @@ -/* $Id: mtfsb1.c,v 1.1 1999/08/23 19:00:17 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/math-emu/mtfsf.c Mon May 21 17:07:03 2001 @@ -1,6 +1,6 @@ -/* $Id: mtfsf.c,v 1.1 1999/08/23 19:00:19 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/mtfsfi.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: mtfsfi.c,v 1.1 1999/08/23 19:00:20 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/op-1.h Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/op-2.h Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/op-4.h Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Basic four-word fraction declaration and manipulation. * * When adding quadword support for 32 bit machines, we need 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/op-common.h Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #define _FP_DECL(wc, X) \ _FP_I_TYPE X##_c, X##_s, X##_e; \ 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/sfp-machine.h Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ /* Machine-dependent software floating-point definitions. PPC version. Copyright (C) 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. diff -Nru a/arch/ppc/math-emu/single.h b/arch/ppc/math-emu/single.h --- a/arch/ppc/math-emu/single.h Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/single.h Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/soft-fp.h Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * 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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/stfd.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: stfd.c,v 1.1 1999/08/23 19:00:33 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/math-emu/stfiwx.c Mon May 21 17:07:03 2001 @@ -1,6 +1,6 @@ -/* $Id: stfiwx.c,v 1.1 1999/08/23 19:00:34 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/stfs.c Mon May 21 17:07:04 2001 @@ -1,6 +1,6 @@ -/* $Id: stfs.c,v 1.1 1999/08/23 19:00:35 cort Exp $ +/* + * BK Id: %F% %I% %G% %U% %#% */ - #include #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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/types.c Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ #include "soft-fp.h" #include "double.h" diff -Nru a/arch/ppc/math-emu/udivmodti4.c b/arch/ppc/math-emu/udivmodti4.c --- a/arch/ppc/math-emu/udivmodti4.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/math-emu/udivmodti4.c Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ /* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny. */ #include "soft-fp.h" diff -Nru a/arch/ppc/mbxboot/Makefile b/arch/ppc/mbxboot/Makefile --- a/arch/ppc/mbxboot/Makefile Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,124 +0,0 @@ -# -# arch/ppc/mbxboot/Makefile -# -# This file is subject to the terms and conditions of the GNU General Public -# License. See the file "COPYING" in the main directory of this archive -# for more details. -# -# Copyright (C) 1994 by Linus Torvalds -# Adapted for PowerPC by Gary Thomas -# modified by Cort (cort@cs.nmt.edu) -# -.c.s: - $(CC) $(CFLAGS) -S -o $*.s $< -.s.o: - $(AS) -o $*.o $< -.c.o: - $(CC) $(CFLAGS) -DINITRD_OFFSET=$(IOFF) -DINITRD_SIZE=$(ISZ) -DZIMAGE_OFFSET=$(ZOFF) -DZIMAGE_SIZE=$(ZSZ) -c -o $*.o $< -.S.s: - $(CPP) $(AFLAGS) -traditional -o $*.o $< -.S.o: - $(CC) $(AFLAGS) -traditional -c -o $*.o $< - -ZOFF = 0 -ZSZ = 0 -IOFF = 0 -ISZ = 0 - -TFTPIMAGE=/tftpboot/zImage.embedded - -ifdef CONFIG_8xx -ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00180000 -OBJECTS := head.o misc.o ../coffboot/zlib.o m8xx_tty.o -CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8xx -endif - -ifdef CONFIG_8260 -ZLINKFLAGS = -T ../vmlinux.lds -Ttext 0x00400000 -OBJECTS := head_8260.o misc.o ../coffboot/zlib.o m8260_tty.o embed_config.o -CFLAGS = $(CPPFLAGS) -O2 -DSTDC_HEADERS -fno-builtin -DCONFIG_8260 -endif - -OBJCOPY_ARGS = -O elf32-powerpc - -ifeq ($(CONFIG_MBX),y) -OBJECTS += pci.o qspan_pci.o -CFLAGS += -DCONFIG_MBX -endif -ifeq ($(CONFIG_RPXLITE),y) -CFLAGS += -DCONFIG_RPXLITE -OBJECTS += iic.o embed_config.o -endif -ifeq ($(CONFIG_RPXCLASSIC),y) -CFLAGS += -DCONFIG_RPXCLASSIC -OBJECTS += iic.o embed_config.o pci.o qspan_pci.o -endif -ifeq ($(CONFIG_BSEIP),y) -CFLAGS += -DCONFIG_BSEIP -OBJECTS += iic.o embed_config.o -endif - -all: zImage - -zvmlinux.initrd: zvmlinux - $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp1 $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=initrd=ramdisk.image.gz \ - --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.initrd.tmp1 zvmlinux.initrd1 - $(CC) $(CFLAGS) -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd1 initrd` \ - -DINITRD_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd1 initrd` \ - -DZIMAGE_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd1 image` \ - -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux.initrd1 image` \ - -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \ - --add-section=initrd=ramdisk.image.gz \ - --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.initrd.tmp $@ - -zImage: zvmlinux - ln -sf zvmlinux zImage - -zImage.initrd: zvmlinux.initrd - ln -sf zvmlinux.initrd zImage.initrd - -zvmlinux: $(OBJECTS) ../coffboot/vmlinux.gz -# -# build the boot loader image and then compute the offset into it -# for the kernel image -# - $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.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) zvmlinux image` \ - -DZIMAGE_SIZE=`sh size $(OBJDUMP) zvmlinux image` \ - -c -o misc.o misc.c - $(LD) $(ZLINKFLAGS) -o zvmlinux.tmp $(OBJECTS) - $(OBJCOPY) $(OBJCOPY_ARGS) -R .comment --add-section=image=../coffboot/vmlinux.gz \ - zvmlinux.tmp $@ - rm zvmlinux.tmp - -znetboot : zImage - cp zImage $(TFTPIMAGE) - -znetboot.initrd : zImage.initrd - cp zImage.initrd $(TFTPIMAGE) - -clean: - rm -f vmlinux* zvmlinux* zImage* - -fastdep: - $(TOPDIR)/scripts/mkdep *.[Sch] > .depend - -dep: - $(CPP) $(CPPFLAGS) -M *.S *.c > .depend - -# just here to match coffboot/Makefile -vmlinux.coff: - -vmlinux.coff.initrd: diff -Nru a/arch/ppc/mbxboot/embed_config.c b/arch/ppc/mbxboot/embed_config.c --- a/arch/ppc/mbxboot/embed_config.c Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,253 +0,0 @@ - -/* Board specific functions for those embedded 8xx boards that do - * not have boot monitor support for board information. - */ -#include -#include -#ifdef CONFIG_8xx -#include -#endif -#ifdef CONFIG_8260 -#include -#endif - - -/* IIC functions. - * These are just the basic master read/write operations so we can - * examine serial EEPROM. - */ -extern void iic_read(uint devaddr, u_char *buf, uint offset, uint count); -extern u_char aschex_to_byte(u_char *cp); - -/* Supply a default Ethernet address for those eval boards that don't - * ship with one. This is an address from the MBX board I have, so - * it is unlikely you will find it on your network. - */ -static ushort def_enet_addr[] = { 0x0800, 0x3e26, 0x1559 }; - -#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) - -static void rpx_eth(bd_t *bd, u_char *cp); -static void rpx_brate(bd_t *bd, u_char *cp); -static void rpx_memsize(bd_t *bd, u_char *cp); -static void rpx_cpuspeed(bd_t *bd, u_char *cp); - -/* Read the EEPROM on the RPX-Lite board. -*/ -void -rpx_cfg(bd_t *bd) -{ - u_char eebuf[256], *cp; - - /* Read the first 256 bytes of the EEPROM. I think this - * is really all there is, and I hope if it gets bigger the - * info we want is still up front. - */ -#if 1 - iic_read(0xa8, eebuf, 0, 128); - iic_read(0xa8, &eebuf[128], 128, 128); - { - int i; - cp = (u_char *)0xfa000000; - - for (i=0; i<256; i++) - *cp++ = eebuf[i]; - } - - /* We look for two things, the Ethernet address and the - * serial baud rate. The records are separated by - * newlines. - */ - cp = eebuf; - for (;;) { - if (*cp == 'E') { - cp++; - if (*cp == 'A') { - cp += 2; - rpx_eth(bd, cp); - } - } - if (*cp == 'S') { - cp++; - if (*cp == 'B') { - cp += 2; - rpx_brate(bd, cp); - } - } - if (*cp == 'D') { - cp++; - if (*cp == '1') { - cp += 2; - rpx_memsize(bd, cp); - } - } - if (*cp == 'H') { - cp++; - if (*cp == 'Z') { - cp += 2; - rpx_cpuspeed(bd, cp); - } - } - - /* Scan to the end of the record. - */ - while ((*cp != '\n') && (*cp != 0xff)) - cp++; - - /* If the next character is a 0 or ff, we are done. - */ - cp++; - if ((*cp == 0) || (*cp == 0xff)) - break; - } - bd->bi_memstart = 0; - -#else - /* For boards without initialized EEPROM. - */ - bd->bi_memstart = 0; - bd->bi_memsize = (8 * 1024 * 1024); - bd->bi_intfreq = 48; - bd->bi_busfreq = 48; - bd->bi_baudrate = 9600; -#endif -} - -static void -rpx_eth(bd_t *bd, u_char *cp) -{ - int i; - - for (i=0; i<6; i++) { - bd->bi_enetaddr[i] = aschex_to_byte(cp); - cp += 2; - } -} - -static void -rpx_brate(bd_t *bd, u_char *cp) -{ - uint rate; - - rate = 0; - - while (*cp != '\n') { - rate *= 10; - rate += (*cp) - '0'; - cp++; - } - - bd->bi_baudrate = rate * 100; -} - -static void -rpx_memsize(bd_t *bd, u_char *cp) -{ - uint size; - - size = 0; - - while (*cp != '\n') { - size *= 10; - size += (*cp) - '0'; - cp++; - } - - bd->bi_memsize = size * 1024 * 1024; -} - -static void -rpx_cpuspeed(bd_t *bd, u_char *cp) -{ - uint num, den; - - num = den = 0; - - while (*cp != '\n') { - num *= 10; - num += (*cp) - '0'; - cp++; - if (*cp == '/') { - cp++; - den = (*cp) - '0'; - break; - } - } - - /* I don't know why the RPX just can't state the actual - * CPU speed..... - */ - if (den) { - num /= den; - num *= den; - } - bd->bi_intfreq = bd->bi_busfreq = num; - - /* The 8xx can only run a maximum 50 MHz bus speed (until - * Motorola changes this :-). Greater than 50 MHz parts - * run internal/2 for bus speed. - */ - if (num > 50) - bd->bi_busfreq /= 2; -} -#endif /* RPXLITE || RPXCLASSIC */ - -#ifdef CONFIG_BSEIP -/* Build a board information structure for the BSE ip-Engine. - * There is more to come since we will add some environment - * variables and a function to read them. - */ -void -bseip_cfg(bd_t *bd) -{ - u_char *cp; - int i; - - /* Baud rate and processor speed will eventually come - * from the environment variables. - */ - bd->bi_baudrate = 9600; - - /* Get the Ethernet station address from the Flash ROM. - */ - cp = (u_char *)0xfe003ffa; - for (i=0; i<6; i++) { - bd->bi_enetaddr[i] = *cp++; - } - - /* The rest of this should come from the environment as well. - */ - bd->bi_memstart = 0; - bd->bi_memsize = (16 * 1024 * 1024); - bd->bi_intfreq = 48; - bd->bi_busfreq = 48; -} -#endif /* BSEIP */ - -#ifdef CONFIG_EST8260 -void -embed_config(bd_t *bd) -{ - u_char *cp; - int i; - -#if 0 - /* This is actually provided by my boot rom. I have it - * here for those people that may load the kernel with - * a JTAG/COP tool and not the rom monitor. - */ - bd->bi_baudrate = 115200; - bd->bi_intfreq = 200; - bd->bi_busfreq = 66; - bd->bi_cpmfreq = 66; - bd->bi_brgfreq = 33; - bd->bi_memsize = 16 * 1024 * 1024; -#endif - - cp = (u_char *)def_enet_addr; - for (i=0; i<6; i++) { - bd->bi_enetaddr[i] = *cp++; - } -} -#endif /* EST8260 */ - diff -Nru a/arch/ppc/mbxboot/gzimage.c b/arch/ppc/mbxboot/gzimage.c --- a/arch/ppc/mbxboot/gzimage.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,8 +0,0 @@ -/* - * gzimage.c - * - * Dummy file to allow a compressed zImage to be added - * into a linker section, accessed by the boot coode - */ - -char dummy_for_gzimage; diff -Nru a/arch/ppc/mbxboot/head.S b/arch/ppc/mbxboot/head.S --- a/arch/ppc/mbxboot/head.S Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,249 +0,0 @@ -#include -#include "../kernel/ppc_defs.h" -#include "../kernel/ppc_asm.tmpl" -#include -#include - - .text - -/* - * $Id: head.S,v 1.6 1999/09/15 00:02:25 dmalek Exp $ - * - * This code is loaded by the ROM loader at some arbitrary location. - * Move it to high memory so that it can load the kernel at 0x0000. - * - * This is a three step process that will also work when booting from - * a Flash PROM normally located in high memory. - * - * First, the entire image is loaded into some high memory address. - * This is usually at or above 0x02000000. This is done by a network - * boot function supported by the board or a debugger over BDM port. - * - * Second, the start up function here will relocate the decompress - * function to run at the link address of 0x01000000. - * - * Last, the decompression function will reloate the initrd, zImage, and - * the residual data to locations under 8 Meg. This is necessary because - * the embedded kernel start up uses 8 Meg translations to access physical - * space before the MMU is enabled. Finally, the zImage is uncompressed - * to location 0 and we jump to it. - * - * On the MBX, - * R1 - Stack pointer at a high memory address. - * R3 - Pointer to Board Information Block. - * R4 - Pointer to argument string. - * Interrupts masked, cache and MMU disabled. - * - * ...and the first and second functions listed above are - * done for us (it knows ELF images). - * - * For other embedded boards we build the Board Information Block. - */ - - .globl start -start: - bl start_ -start_: -#ifndef CONFIG_MBX - lis r11, local_bd_info@h - ori r11, r11, local_bd_info@l -#else - mr r11, r3 -#endif - - mfmsr r3 /* Turn off interrupts */ - li r4,0 - ori r4,r4,MSR_EE - andc r3,r3,r4 - mtmsr r3 - -/* 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 -#if 0 - cmp 0,r3,r4 - beq start_ldr /* Branch if loaded OK */ -#endif - -/* - * no matter where we're loaded, move ourselves to -Ttext address - * This computes the sizes we need to determine other things. - */ - 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: -/* Most 8xx boards don't boot up with the I-cache enabled. Do that - * now because the decompress runs much faster that way. - */ - lis r3, IDC_INVALL@h - mtspr IC_CST, r3 - lis r3, IDC_ENABLE@h - mtspr IC_CST, r3 - -/* Clear all of BSS */ - 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 - - 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 - - /* Perform configuration of the various boards. This is done - * by reading some configuration data from EEPROM and building - * the board information structure. - */ - mr r3, r11 - mr r21, r11 - mr r22, r8 - mr r23, r7 - mr r24, r6 - -#if defined(CONFIG_RPXLITE) || defined(CONFIG_RPXCLASSIC) - bl rpx_cfg - mr r3, r21 -#endif -#ifdef CONFIG_BSEIP - bl bseip_cfg - mr r3, r21 -#endif - bl serial_init /* Init MBX serial port */ - - mr r11, r21 - mr r8, r22 - mr r7, r23 - mr r6, r24 - -#ifdef CONFIG_MBX - lis r18, 0xfa200000@h /* Disable Ethernet SCC */ - li r0, 0 - stw r0, 0x0a00(r18) - - /* On the MBX (or anything that will TFTP load an ELF image), - * we have to find the intermediate address. The ELF loader - * only moves the Linux boostrap/decompress, not the zImage. - */ -#define ILAP_ADDRESS 0xfa000020 - lis r8, ILAP_ADDRESS@h - lwz r8, ILAP_ADDRESS@l(r8) - addis r8, r8, 1 /* Add 64K */ -#endif - - mr r3,r8 /* Load point */ - mr r4,r7 /* Program length */ - mr r5,r6 /* Checksum */ - mr r6,r11 /* Residual data */ - bl decompress_kernel - - /* changed to use r3 (as firmware does) for kernel - as ptr to residual -- Cort*/ - 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) - - /* The world starts from the beginning. - */ - li r9,0x0 - mtlr r9 - - /* Invalidate the instruction cache because we just copied a - * bunch of kernel instructions. - */ - lis r9, IDC_INVALL@h - mtspr IC_CST, r9 - - blr -hang: - b hang - -/* - * Delay for a number of microseconds - * -- Use the BUS timer (assumes 66MHz) - */ - .globl udelay -udelay: - 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_MSR -_get_MSR: - mfmsr r3 - blr - -.globl _put_MSR -_put_MSR: - mtmsr r3 - blr - - .comm .stack,4096*2,4 -#ifndef CONFIG_MBX -local_bd_info: - .long 0 - .long 0x01000000 - .long 64 - .long 64 - .long 0 - .long 0 - .long 0 -#endif diff -Nru a/arch/ppc/mbxboot/head_8260.S b/arch/ppc/mbxboot/head_8260.S --- a/arch/ppc/mbxboot/head_8260.S Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,258 +0,0 @@ -#include "../kernel/ppc_defs.h" -#include "../kernel/ppc_asm.tmpl" -#include -#include - - .text - -/* - * $Id: head.S,v 1.33 1999/09/08 01:06:58 cort Exp $ - * - * Boot loader philosophy: - * - * ROM loads us to some arbitrary location - * ROM loads these registers: - * - * R3 = Pointer to the board configuration data - * R5 = Pointer to Open Firmware data - * - * ROM jumps to start/start_ - * Move the boot code to the link address (4 MB) - * Call decompress_kernel() - * Relocate the initrd, zimage and residual data to 4 MB - * Decompress the kernel to 0 - * Jump to the kernel entry - * -- Cort - */ - .globl start -start: - bl start_ -start_: - mr r11,r3 /* Save pointer to residual/board data */ - mr r25,r5 /* Save OFW pointer */ - li r3,MSR_IP /* Establish default MSR value */ - mtmsr r3 - -/* 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 */ - 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 - - /* Speed us up a little. - */ - bl flush_instruction_cache - -/* Run loader */ - mr r3,r8 /* Load point */ - mr r4,r7 /* Program length */ - mr r5,r6 /* Checksum */ - mr r6,r11 /* Residual data */ - mr r7,r25 /* OFW interfaces */ - bl decompress_kernel - - /* changed to use r3 (as firmware does) for kernel - as ptr to residual -- Cort*/ - 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) - - /* tell kernel we're prep */ - /* - * get start address of kernel code which is stored as a coff - * entry. see boot/head.S -- Cort - */ - li r9,0x4 - mtlr r9 - lis r10,0xdeadc0de@h - ori r10,r10,0xdeadc0de@l - li r9,0 - stw r10,0(r9) -/* - * The Radstone firmware maps PCI memory at 0xc0000000 using BAT2 - * so disable BATs before setting this to avoid a clash - */ - li r8,0 - mtspr DBAT0U,r8 - mtspr DBAT1U,r8 - mtspr DBAT2U,r8 - mtspr DBAT3U,r8 - mtspr IBAT0U,r8 - mtspr IBAT1U,r8 - mtspr IBAT2U,r8 - mtspr IBAT3U,r8 - - 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/mbxboot/iic.c b/arch/ppc/mbxboot/iic.c --- a/arch/ppc/mbxboot/iic.c Mon May 21 17:07:05 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,259 +0,0 @@ - -/* Minimal support functions to read configuration from IIC EEPROMS - * on MPC8xx boards. Originally written for RPGC RPX-Lite. - * Dan Malek (dmalek@jlc.net). - */ -#include -#include -#include "asm/mpc8xx.h" -#include "../8xx_io/commproc.h" - - -/* IIC functions. - * These are just the basic master read/write operations so we can - * examine serial EEPROM. - */ -void iic_read(uint devaddr, u_char *buf, uint offset, uint count); -u_char aschex_to_byte(u_char *cp); - -static int iic_init_done; - -static void -iic_init() -{ - volatile iic_t *iip; - volatile i2c8xx_t *i2c; - volatile cbd_t *tbdf, *rbdf; - volatile cpm8xx_t *cp; - volatile immap_t *immap; - uint dpaddr; - - immap = (immap_t *)IMAP_ADDR; - cp = (cpm8xx_t *)&(immap->im_cpm); - - /* Reset the CPM. This is necessary on the 860 processors - * that may have started the SCC1 ethernet without relocating - * the IIC. - * This also stops the Ethernet in case we were loaded by a - * BOOTP rom monitor. - */ - cp->cp_cpcr = (CPM_CR_RST | CPM_CR_FLG); - - /* Wait for it. - */ - while (cp->cp_cpcr & (CPM_CR_RST | CPM_CR_FLG)); - - /* Remove any microcode patches. We will install our own - * later. - */ - cp->cp_cpmcr1 = 0; - cp->cp_cpmcr2 = 0; - cp->cp_cpmcr3 = 0; - cp->cp_cpmcr4 = 0; - cp->cp_rccr = 0; - - iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; - i2c = (i2c8xx_t *)&(immap->im_i2c); - - /* Initialize Port B IIC pins. - */ - cp->cp_pbpar |= 0x00000030; - cp->cp_pbdir |= 0x00000030; - cp->cp_pbodr |= 0x00000030; - - /* Initialize the parameter ram. - */ - - /* Allocate space for a two transmit and one receive buffer - * descriptor in the DP ram. - * For now, this address seems OK, but it may have to - * change with newer versions of the firmware. - */ - dpaddr = 0x0840; - - /* Set up the IIC parameters in the parameter ram. - */ - iip->iic_tbase = dpaddr; - iip->iic_rbase = dpaddr + (2 * sizeof(cbd_t)); - - iip->iic_tfcr = SMC_EB; - iip->iic_rfcr = SMC_EB; - - /* This should really be done by the reader/writer. - */ - iip->iic_mrblr = 128; - - /* Initialize Tx/Rx parameters. - */ - 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; - - /* Enable SDMA. - */ - immap->im_siu_conf.sc_sdcr = 1; - - iic_init_done = 1; -} - -/* Read from IIC. - * Caller provides device address, memory buffer, and byte count. - */ -static u_char iitemp[32]; - -void -iic_read(uint devaddr, u_char *buf, uint offset, uint count) -{ - volatile iic_t *iip; - volatile i2c8xx_t *i2c; - volatile cbd_t *tbdf, *rbdf; - volatile cpm8xx_t *cp; - volatile immap_t *immap; - u_char *tb; - uint dpaddr, temp; - - /* If the interface has not been initialized, do that now. - */ - if (!iic_init_done) - iic_init(); - - immap = (immap_t *)IMAP_ADDR; - cp = (cpm8xx_t *)&(immap->im_cpm); - - iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; - i2c = (i2c8xx_t *)&(immap->im_i2c); - - tbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_tbase]; - rbdf = (cbd_t *)&cp->cp_dpmem[iip->iic_rbase]; - - /* Send a "dummy write" operation. This is a write request with - * only the offset sent, followed by another start condition. - * This will ensure we start reading from the first location - * of the EEPROM. - */ - tb = iitemp; - tb = (u_char *)(((uint)tb + 15) & ~15); - tbdf->cbd_bufaddr = tb; - *tb = devaddr & 0xfe; /* Device address */ - *(tb+1) = offset; /* Offset */ - tbdf->cbd_datlen = 2; /* Length */ - tbdf->cbd_sc = - BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START; - - i2c->i2c_i2mod = 1; /* Enable */ - i2c->i2c_i2cer = 0xff; - i2c->i2c_i2com = 0x81; /* Start master */ - - /* Wait for IIC transfer. - */ -#if 0 - while ((i2c->i2c_i2cer & 3) == 0); - - if (tbdf->cbd_sc & BD_SC_READY) - printf("IIC ra complete but tbuf ready\n"); -#else - temp = 10000000; - while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0)) - temp--; -#if 0 - /* We can't do this...there is no serial port yet! - */ - if (temp == 0) { - printf("Timeout reading EEPROM\n"); - return; - } -#endif -#endif - - /* Chip errata, clear enable. - */ - i2c->i2c_i2mod = 0; - - /* 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). - */ - tbdf->cbd_bufaddr = tb; - *tb = devaddr | 1; /* Device address */ - rbdf->cbd_bufaddr = (uint)buf; /* Desination buffer */ - tbdf->cbd_datlen = rbdf->cbd_datlen = count + 1; /* Length */ - tbdf->cbd_sc = BD_SC_READY | BD_SC_LAST | BD_SC_WRAP | BD_IIC_START; - rbdf->cbd_sc = BD_SC_EMPTY | BD_SC_WRAP; - - /* Chip bug, set enable here. - */ - i2c->i2c_i2mod = 1; /* Enable */ - i2c->i2c_i2cer = 0xff; - i2c->i2c_i2com = 0x81; /* Start master */ - - /* Wait for IIC transfer. - */ -#if 0 - while ((i2c->i2c_i2cer & 1) == 0); - - if (rbdf->cbd_sc & BD_SC_EMPTY) - printf("IIC read complete but rbuf empty\n"); -#else - temp = 10000000; - while ((tbdf->cbd_sc & BD_SC_READY) && (temp != 0)) - temp--; -#endif - - /* Chip errata, clear enable. - */ - i2c->i2c_i2mod = 0; -} - -/* Because I didn't find anything that would do this....... -*/ -u_char -aschex_to_byte(u_char *cp) -{ - u_char byte, c; - - c = *cp++; - - if ((c >= 'A') && (c <= 'F')) { - c -= 'A'; - c += 10; - } - else if ((c >= 'a') && (c <= 'f')) { - c -= 'a'; - c += 10; - } - else { - c -= '0'; - } - - byte = c * 16; - - c = *cp; - - if ((c >= 'A') && (c <= 'F')) { - c -= 'A'; - c += 10; - } - else if ((c >= 'a') && (c <= 'f')) { - c -= 'a'; - c += 10; - } - else { - c -= '0'; - } - - byte += c; - - return(byte); -} diff -Nru a/arch/ppc/mbxboot/m8260_tty.c b/arch/ppc/mbxboot/m8260_tty.c --- a/arch/ppc/mbxboot/m8260_tty.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,201 +0,0 @@ - - -/* Minimal serial functions needed to send messages out the serial - * port on SMC1. - */ -#include -#include "asm/mpc8260.h" -#include "asm/cpm_8260.h" - -uint no_print; -extern char *params[]; -extern int nparams; -static u_char cons_hold[128], *sgptr; -static int cons_hold_cnt; - -void -serial_init(bd_t *bd) -{ - volatile smc_t *sp; - volatile smc_uart_t *up; - volatile cbd_t *tbdf, *rbdf; - volatile immap_t *ip; - volatile iop8260_t *io; - volatile cpm8260_t *cp; - uint dpaddr, memaddr; - - ip = (immap_t *)IMAP_ADDR; - - sp = (smc_t*)&(ip->im_smc[0]); - *(ushort *)(&ip->im_dprambase[PROFF_SMC1_BASE]) = PROFF_SMC1; - up = (smc_uart_t *)&ip->im_dprambase[PROFF_SMC1]; - - cp = &ip->im_cpm; - io = &ip->im_ioport; - - /* Disable transmitter/receiver. - */ - sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - - /* Use Port D for SMC1 instead of other functions. - */ - io->iop_ppard |= 0x00c00000; - io->iop_pdird |= 0x00400000; - io->iop_pdird &= ~0x00800000; - io->iop_psord &= ~0x00c00000; - - /* Allocate space for two buffer descriptors in the DP ram. - * For now, this address seems OK, but it may have to - * change with newer versions of the firmware. - */ - dpaddr = 0x0800; - - /* Grab a few bytes from the top of memory. - */ -#if 1 - memaddr = (bd->bi_memsize - 256) & ~15; -#else - memaddr = 0x0f002c00; -#endif - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - rbdf = (cbd_t *)&ip->im_dprambase[dpaddr]; - rbdf->cbd_bufaddr = memaddr; - rbdf->cbd_sc = 0; - tbdf = rbdf + 1; - tbdf->cbd_bufaddr = memaddr+128; - tbdf->cbd_sc = 0; - - /* Set up the uart parameters in the parameter ram. - */ - up->smc_rbase = dpaddr; - up->smc_tbase = dpaddr+sizeof(cbd_t); - up->smc_rfcr = CPMFCR_EB; - up->smc_tfcr = CPMFCR_EB; - up->smc_brklen = 0; - up->smc_brkec = 0; - up->smc_brkcr = 0; - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Mask all interrupts and remove anything pending. - */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; - - /* Set up the baud rate generator. - */ - ip->im_clkrst.car_sccr = 0; /* DIV 4 BRG */ - ip->im_cpmux.cmx_smr = 0; - ip->im_brgc1 = - ((((bd->bi_brgfreq * 1000000)/16) / bd->bi_baudrate) << 1) | - CPM_BRG_EN; - - /* Make the first buffer the only buffer. - */ - tbdf->cbd_sc |= BD_SC_WRAP; - rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; - -#if 0 - /* Single character receive. - */ - up->smc_mrblr = 1; - up->smc_maxidl = 0; -#else - up->smc_mrblr = 128; - up->smc_maxidl = 8; -#endif - - /* Initialize Tx/Rx parameters. - */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_SMC1_PAGE, CPM_CR_SMC1_SBLOCK, 0, CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - /* Enable transmitter/receiver. - */ - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; -} - -void -serial_putchar(const char c) -{ - volatile cbd_t *tbdf; - volatile char *buf; - volatile smc_uart_t *up; - volatile immap_t *ip; - extern bd_t *board_info; - - ip = (immap_t *)IMAP_ADDR; - up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); - tbdf = (cbd_t *)&ip->im_dprambase[up->smc_tbase]; - - /* Wait for last character to go. - */ - buf = (char *)tbdf->cbd_bufaddr; - while (tbdf->cbd_sc & BD_SC_READY); - - *buf = c; - tbdf->cbd_datlen = 1; - tbdf->cbd_sc |= BD_SC_READY; -} - -char -serial_getc() -{ - char c; - - if (cons_hold_cnt <= 0) { - cons_hold_cnt = serial_readbuf(cons_hold); - sgptr = cons_hold; - } - c = *sgptr++; - cons_hold_cnt--; - - return(c); -} - -int -serial_readbuf(u_char *cbuf) -{ - volatile cbd_t *rbdf; - volatile char *buf; - volatile smc_uart_t *up; - volatile immap_t *ip; - int i, nc; - - ip = (immap_t *)IMAP_ADDR; - - up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); - rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; - - /* Wait for character to show up. - */ - buf = (char *)rbdf->cbd_bufaddr; - while (rbdf->cbd_sc & BD_SC_EMPTY); - nc = rbdf->cbd_datlen; - for (i=0; icbd_sc |= BD_SC_EMPTY; - - return(nc); -} - -int -serial_tstc() -{ - volatile cbd_t *rbdf; - volatile smc_uart_t *up; - volatile immap_t *ip; - - ip = (immap_t *)IMAP_ADDR; - up = (smc_uart_t *)&(ip->im_dprambase[PROFF_SMC1]); - rbdf = (cbd_t *)&ip->im_dprambase[up->smc_rbase]; - - return(!(rbdf->cbd_sc & BD_SC_EMPTY)); -} - diff -Nru a/arch/ppc/mbxboot/m8xx_tty.c b/arch/ppc/mbxboot/m8xx_tty.c --- a/arch/ppc/mbxboot/m8xx_tty.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,276 +0,0 @@ - - -/* Minimal serial functions needed to send messages out the serial - * port on the MBX console. - * - * The MBX uxes SMC1 for the serial port. We reset the port and use - * only the first BD that EPPC-Bug set up as a character FIFO. - * - * Later versions (at least 1.4, maybe earlier) of the MBX EPPC-Bug - * use COM1 instead of SMC1 as the console port. This kinda sucks - * for the rest of the kernel, so here we force the use of SMC1 again. - */ -#include -#include -#include -#include -#include "../8xx_io/commproc.h" - -#ifdef CONFIG_MBX -#define MBX_CSR1 ((volatile u_char *)0xfa100000) -#define CSR1_COMEN (u_char)0x02 -#endif - -#ifdef TQM_SMC2_CONSOLE -#define PROFF_CONS PROFF_SMC2 -#define CPM_CR_CH_CONS CPM_CR_CH_SMC2 -#define SMC_INDEX 1 -static volatile iop8xx_t *iopp = (iop8xx_t *)&(((immap_t *)IMAP_ADDR)->im_ioport); -#else -#define PROFF_CONS PROFF_SMC1 -#define CPM_CR_CH_CONS CPM_CR_CH_SMC1 -#define SMC_INDEX 0 -#endif - -static cpm8xx_t *cpmp = (cpm8xx_t *)&(((immap_t *)IMAP_ADDR)->im_cpm); - -void -serial_init(bd_t *bd) -{ - volatile smc_t *sp; - volatile smc_uart_t *up; - volatile cbd_t *tbdf, *rbdf; - volatile cpm8xx_t *cp; - uint dpaddr, memaddr; - - cp = cpmp; - sp = (smc_t*)&(cp->cp_smc[SMC_INDEX]); - up = (smc_uart_t *)&cp->cp_dparam[PROFF_CONS]; - - /* Disable transmitter/receiver. - */ - sp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN); - -#ifndef CONFIG_MBX - { - /* Initialize SMCx and use it for the console port. - */ - - /* Enable SDMA. - */ - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; - -#ifdef TQM_SMC2_CONSOLE - /* Use Port A for SMC2 instead of other functions. - */ - iopp->iop_papar |= 0x00c0; - iopp->iop_padir &= ~0x00c0; - iopp->iop_paodr &= ~0x00c0; -#else - /* Use Port B for SMCs instead of other functions. - */ - cp->cp_pbpar |= 0x00000cc0; - cp->cp_pbdir &= ~0x00000cc0; - cp->cp_pbodr &= ~0x00000cc0; -#endif - - /* Allocate space for two buffer descriptors in the DP ram. - * For now, this address seems OK, but it may have to - * change with newer versions of the firmware. - */ - dpaddr = 0x0800; - - /* Grab a few bytes from the top of memory for SMC FIFOs. - */ - memaddr = (bd->bi_memsize - 32) & ~15; - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; - rbdf->cbd_bufaddr = memaddr; - rbdf->cbd_sc = 0; - tbdf = rbdf + 1; - tbdf->cbd_bufaddr = memaddr+4; - tbdf->cbd_sc = 0; - - /* Set up the uart parameters in the parameter ram. - */ - up->smc_rbase = dpaddr; - up->smc_tbase = dpaddr+sizeof(cbd_t); - up->smc_rfcr = SMC_EB; - up->smc_tfcr = SMC_EB; - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Mask all interrupts and remove anything pending. - */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; - - /* Set up the baud rate generator. - * See 8xx_io/commproc.c for details. - * This wires BRG1 to SMC1 and BRG2 to SMC2; - */ - cp->cp_simode = 0x10000000; -#ifdef TQM_SMC2_CONSOLE - cp->cp_brgc2 = -#else - cp->cp_brgc1 = -#endif - ((((bd->bi_intfreq * 1000000)/16) / bd->bi_baudrate) << 1) | CPM_BRG_EN; - -#else /* CONFIG_MBX */ - if (*MBX_CSR1 & CSR1_COMEN) { - /* COM1 is enabled. Initialize SMC1 and use it for - * the console port. - */ - - /* Enable SDMA. - */ - ((immap_t *)IMAP_ADDR)->im_siu_conf.sc_sdcr = 1; - - /* Use Port B for SMCs instead of other functions. - */ - cp->cp_pbpar |= 0x00000cc0; - cp->cp_pbdir &= ~0x00000cc0; - cp->cp_pbodr &= ~0x00000cc0; - - /* Allocate space for two buffer descriptors in the DP ram. - * For now, this address seems OK, but it may have to - * change with newer versions of the firmware. - */ - dpaddr = 0x0800; - - /* Grab a few bytes from the top of memory. EPPC-Bug isn't - * running any more, so we can do this. - */ - memaddr = (bd->bi_memsize - 32) & ~15; - - /* Set the physical address of the host memory buffers in - * the buffer descriptors. - */ - rbdf = (cbd_t *)&cp->cp_dpmem[dpaddr]; - rbdf->cbd_bufaddr = memaddr; - rbdf->cbd_sc = 0; - tbdf = rbdf + 1; - tbdf->cbd_bufaddr = memaddr+4; - tbdf->cbd_sc = 0; - - /* Set up the uart parameters in the parameter ram. - */ - up->smc_rbase = dpaddr; - up->smc_tbase = dpaddr+sizeof(cbd_t); - up->smc_rfcr = SMC_EB; - up->smc_tfcr = SMC_EB; - - /* Set UART mode, 8 bit, no parity, one stop. - * Enable receive and transmit. - */ - sp->smc_smcmr = smcr_mk_clen(9) | SMCMR_SM_UART; - - /* Mask all interrupts and remove anything pending. - */ - sp->smc_smcm = 0; - sp->smc_smce = 0xff; - - /* Set up the baud rate generator. - * See 8xx_io/commproc.c for details. - */ - cp->cp_simode = 0x10000000; - cp->cp_brgc1 = - ((((bd->bi_intfreq * 1000000)/16) / 9600) << 1) | CPM_BRG_EN; - - /* Enable SMC1 for console output. - */ - *MBX_CSR1 &= ~CSR1_COMEN; - } - else { -#endif /* ndef CONFIG_MBX */ - /* SMCx is used as console port. - */ - tbdf = (cbd_t *)&cp->cp_dpmem[up->smc_tbase]; - rbdf = (cbd_t *)&cp->cp_dpmem[up->smc_rbase]; - - /* Issue a stop transmit, and wait for it. - */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, - CPM_CR_STOP_TX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - } - - /* Make the first buffer the only buffer. - */ - tbdf->cbd_sc |= BD_SC_WRAP; - rbdf->cbd_sc |= BD_SC_EMPTY | BD_SC_WRAP; - - /* Single character receive. - */ - up->smc_mrblr = 1; - up->smc_maxidl = 0; - - /* Initialize Tx/Rx parameters. - */ - cp->cp_cpcr = mk_cr_cmd(CPM_CR_CH_CONS, CPM_CR_INIT_TRX) | CPM_CR_FLG; - while (cp->cp_cpcr & CPM_CR_FLG); - - /* Enable transmitter/receiver. - */ - sp->smc_smcmr |= SMCMR_REN | SMCMR_TEN; -} - -void -serial_putchar(const char c) -{ - volatile cbd_t *tbdf; - volatile char *buf; - volatile smc_uart_t *up; - - up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; - tbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase]; - - /* Wait for last character to go. - */ - buf = (char *)tbdf->cbd_bufaddr; - while (tbdf->cbd_sc & BD_SC_READY); - - *buf = c; - tbdf->cbd_datlen = 1; - tbdf->cbd_sc |= BD_SC_READY; -} - -char -serial_getc() -{ - volatile cbd_t *rbdf; - volatile char *buf; - volatile smc_uart_t *up; - char c; - - up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; - rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; - - /* Wait for character to show up. - */ - buf = (char *)rbdf->cbd_bufaddr; - while (rbdf->cbd_sc & BD_SC_EMPTY); - c = *buf; - rbdf->cbd_sc |= BD_SC_EMPTY; - - return(c); -} - -int -serial_tstc() -{ - volatile cbd_t *rbdf; - volatile smc_uart_t *up; - - up = (smc_uart_t *)&cpmp->cp_dparam[PROFF_CONS]; - rbdf = (cbd_t *)&cpmp->cp_dpmem[up->smc_rbase]; - - return(!(rbdf->cbd_sc & BD_SC_EMPTY)); -} diff -Nru a/arch/ppc/mbxboot/misc.c b/arch/ppc/mbxboot/misc.c --- a/arch/ppc/mbxboot/misc.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,476 +0,0 @@ -/* - * misc.c - * - * $Id: misc.c,v 1.2 1999/09/14 05:55:29 dmalek Exp $ - * - * Adapted for PowerPC by Gary Thomas - * - * Rewritten by Cort Dougan (cort@cs.nmt.edu) - * One day to be replaced by a single bootloader for chrp/prep/pmac. -- Cort - */ - -#include -#include "../coffboot/zlib.h" -#include "asm/residual.h" -#include -#include -#include -#include -#include -#ifdef CONFIG_8xx -#include -#endif -#ifdef CONFIG_8260 -#include -#endif - -/* - * The following references are needed to cause the linker to pull in the - * gzimage.o and rdimage.o files. These object files are special, - * since they get placed into the .gzimage and .rdimage ELF sections - * of the zvmlinux and zvmlinux.initrd files. - */ -extern char dummy_for_gzimage; -extern char dummy_for_rdimage; - -/* - * Please send me load/board info and such data for hardware not - * listed here so I can keep track since things are getting tricky - * with the different load addrs with different firmware. This will - * help to avoid breaking the load/boot process. - * -- Cort - */ -char *avail_ram; -char *end_avail; - -/* See comment below..... -*/ -unsigned int initrd_offset, initrd_size; - -/* Because of the limited amount of memory on embedded, it presents - * loading problems. The biggest is that we load this boot program - * into a relatively low memory address, and the Linux kernel Bss often - * extends into this space when it get loaded. When the kernel starts - * and zeros the BSS space, it also writes over the information we - * save here and pass to the kernel (command line and board info). - * On these boards, we grab some known memory holes to hold this information. - */ -char cmd_buf[256]; -char *cmd_line = cmd_buf; - -char *root_string = "root=/dev/nfs rw"; -char *nfsaddrs_string = "nfsaddrs="; -char *nfsroot_string = "nfsroot="; -char *defroot_string = "/sys/mbxroot"; -char *ramroot_string = "root=/dev/ram"; -int do_ipaddrs(char **cmd_cp, int echo); -void do_nfsroot(char **cmd_cp, char *dp); -int strncmp(const char * cs,const char * ct,size_t count); -char *strrchr(const char * s, int c); - -bd_t hold_resid_buf; -bd_t *hold_residual = &hold_resid_buf; -unsigned long initrd_start = 0, initrd_end = 0; -char *zimage_start; -int zimage_size; - -void puts(const char *); -void putc(const char c); -void puthex(unsigned long val); -void _bcopy(char *src, char *dst, int len); -void * memcpy(void * __dest, __const void * __src, - int __n); -void gunzip(void *, int, unsigned char *, int *); - -void pause() -{ - puts("pause\n"); -} - -void exit() -{ - puts("exit\n"); - while(1); -} - -/* The MPC8xx is just the serial port. -*/ -tstc(void) -{ - return (serial_tstc()); -} - -getc(void) -{ - while (1) { - if (serial_tstc()) return (serial_getc()); - } -} - -void -putc(const char c) -{ - serial_putchar(c); -} - -void puts(const char *s) -{ - char c; - - while ( ( c = *s++ ) != '\0' ) { - serial_putchar(c); - if ( c == '\n' ) - serial_putchar('\r'); - } -} - -void * memcpy(void * __dest, __const void * __src, - int __n) -{ - int i; - char *d = (char *)__dest, *s = (char *)__src; - - for (i=0;i<__n;i++) d[i] = s[i]; -} - -int memcmp(__const void * __dest, __const void * __src, - int __n) -{ - int i; - char *d = (char *)__dest, *s = (char *)__src; - - for (i=0;i<__n;i++, d++, s++) - { - if (*d != *s) - { - return (*s - *d); - } - } - return (0); -} - -void error(char *x) -{ - puts("\n\n"); - puts(x); - puts("\n\n -- System halted"); - - while(1); /* Halt */ -} - -void *zalloc(void *x, unsigned items, unsigned size) -{ - void *p = avail_ram; - - size *= items; - size = (size + 7) & -8; - avail_ram += size; - if (avail_ram > end_avail) { - puts("oops... out of memory\n"); - pause(); - } - return p; -} - -void zfree(void *x, void *addr, unsigned nb) -{ -} - -#define HEAD_CRC 2 -#define EXTRA_FIELD 4 -#define ORIG_NAME 8 -#define COMMENT 0x10 -#define RESERVED 0xe0 - -#define DEFLATED 8 - - -void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) -{ - z_stream s; - int r, i, flags; - - /* skip header */ - i = 10; - flags = src[3]; - if (src[2] != DEFLATED || (flags & RESERVED) != 0) { - puts("bad gzipped data\n"); - exit(); - } - if ((flags & EXTRA_FIELD) != 0) - i = 12 + src[10] + (src[11] << 8); - if ((flags & ORIG_NAME) != 0) - while (src[i++] != 0) - ; - if ((flags & COMMENT) != 0) - while (src[i++] != 0) - ; - if ((flags & HEAD_CRC) != 0) - i += 2; - if (i >= *lenp) { - puts("gunzip: ran out of data in header\n"); - exit(); - } - - s.zalloc = zalloc; - s.zfree = zfree; - r = inflateInit2(&s, -MAX_WBITS); - if (r != Z_OK) { - puts("inflateInit2 returned %d\n"); - exit(); - } - s.next_in = src + i; - s.avail_in = *lenp - i; - s.next_out = dst; - s.avail_out = dstlen; - r = inflate(&s, Z_FINISH); - if (r != Z_OK && r != Z_STREAM_END) { - puts("inflate returned "); - puthex(r); - puts("\n"); - exit(); - } - *lenp = s.next_out - (unsigned char *) dst; - inflateEnd(&s); -} - -unsigned char sanity[0x2000]; - -unsigned long -decompress_kernel(unsigned long load_addr, int num_words, unsigned long cksum, bd_t *bp) -{ - int timer; - extern unsigned long start; - char *cp, ch; - unsigned long i; - char *dp; - -#ifdef CONFIG_8260 - /* I don't know why I didn't do it this way on the 8xx....... - */ - embed_config(bp); - serial_init(bp); -#endif - - /* These values must be variables. If not, the compiler optimizer - * will remove some code, causing the size of the code to vary - * when these values are zero. This is bad because we first - * compile with these zero to determine the size and offsets - * in an image, than compile again with these set to the proper - * discovered value.....Ya know, we used to read these from the - * header a long time ago..... - */ - initrd_offset = INITRD_OFFSET; - initrd_size = INITRD_SIZE; - - /* Grab some space for the command line and board info. Since - * we no longer use the ELF header, but it was loaded, grab - * that space. - */ -#ifdef CONFIG_MBX - cmd_line = (char *)(load_addr - 0x10000); - - /* To be like everyone else, we need one too, although this - * board information is passed from the boot rom. - */ - bp->bi_baudrate = 9600; -#else - cmd_line = (char *)(0x200000); -#endif - hold_residual = (bd_t *)(cmd_line + sizeof(cmd_buf)); - /* copy board data */ - if (bp) - memcpy(hold_residual,bp,sizeof(bd_t)); - - /* Set end of memory available to us. It is always the highest - * memory address provided by the board information. - */ - end_avail = (char *)(bp->bi_memsize); - - puts("loaded at: "); puthex(load_addr); - puts(" "); puthex((unsigned long)(load_addr + (4*num_words))); puts("\n"); - if ( (unsigned long)load_addr != (unsigned long)&start ) - { - puts("relocated to: "); puthex((unsigned long)&start); - puts(" "); - puthex((unsigned long)((unsigned long)&start + (4*num_words))); - puts("\n"); - } - - if ( bp ) - { - puts("board data at: "); puthex((unsigned long)bp); - puts(" "); - puthex((unsigned long)((unsigned long)bp + sizeof(bd_t))); - puts("\n"); - puts("relocated to: "); - puthex((unsigned long)hold_residual); - puts(" "); - puthex((unsigned long)((unsigned long)hold_residual + sizeof(bd_t))); - puts("\n"); - } - - /* we have to subtract 0x10000 here to correct for objdump including the - size of the elf header which we strip -- Cort */ - zimage_start = (char *)(load_addr - 0x10000 + ZIMAGE_OFFSET); - zimage_size = ZIMAGE_SIZE; - - if ( initrd_offset ) - initrd_start = load_addr - 0x10000 + initrd_offset; - else - initrd_start = 0; - initrd_end = initrd_size + initrd_start; - - /* - * setup avail_ram - this is the first part of ram usable - * by the uncompress code. -- Cort - */ - avail_ram = (char *)PAGE_ALIGN((unsigned long)zimage_start+zimage_size); - if ( ((load_addr+(num_words*4)) > (unsigned long) avail_ram) - && (load_addr <= 0x01000000) ) - avail_ram = (char *)(load_addr+(num_words*4)); - if ( (((unsigned long)&start+(num_words*4)) > (unsigned long) avail_ram) - && (load_addr <= 0x01000000) ) - avail_ram = (char *)((unsigned long)&start+(num_words*4)); - - /* relocate zimage */ - puts("zimage at: "); puthex((unsigned long)zimage_start); - puts(" "); puthex((unsigned long)(zimage_size+zimage_start)); puts("\n"); - /* - * There is no reason (yet) to relocate zImage for embedded boards. - * To support boot from flash rom on 8xx embedded boards, I - * assume if zimage start is over 16M we are booting from flash. - * In this case, avilable ram will start just above the space we - * have allocated for the command buffer and board information. - */ - if ((unsigned long)zimage_start > 0x01000000) - avail_ram = (char *)PAGE_ALIGN((unsigned long)hold_residual + sizeof(bd_t)); - - /* relocate initrd */ - if ( initrd_start ) - { - puts("initrd at: "); puthex(initrd_start); - puts(" "); puthex(initrd_end); puts("\n"); - - /* We only have to relocate initrd if we find it is in Flash - * rom. This is because the kernel thinks it can toss the - * pages into the free memory pool after it is done. Use - * the same 16M test. - */ - if ((unsigned long)initrd_start > 0x01000000) { - memcpy ((void *)PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE), - (void *)initrd_start, - initrd_size ); - initrd_start = PAGE_ALIGN(-PAGE_SIZE+(unsigned long)end_avail-INITRD_SIZE); - initrd_end = initrd_start + initrd_size; - end_avail = (char *)initrd_start; - puts("relocated to: "); puthex(initrd_start); - puts(" "); puthex(initrd_end); puts("\n"); - } - else { - avail_ram = (char *)PAGE_ALIGN((unsigned long)initrd_end); - } - } - - - puts("avail ram: "); puthex((unsigned long)avail_ram); puts(" "); - puthex((unsigned long)end_avail); puts("\n"); - - puts("\nLinux/PPC load: "); - timer = 0; - cp = cmd_line; - - 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; - - /* If the command line is not filled in, we will automatically - * create the default boot. - */ - if (cmd_line[0] == 0) { - - /* An initrd on these boards means we booted from Flash - * ROM and want to use the ramdisk as the root file system. - * Otherwise, we perform a diskless NFS boot. - */ - if (initrd_start) - dp = ramroot_string; - else - dp = root_string; - while (*dp != 0) - *cp++ = *dp++; - *cp = 0; - } - - puts("\n"); - - puts("Uncompressing Linux..."); - - gunzip(0, 0x400000, zimage_start, &zimage_size); - puts("done.\n"); - puts("Now booting the kernel\n"); - return (unsigned long)hold_residual; -} - -void puthex(unsigned long val) -{ - unsigned char buf[10]; - int i; - for (i = 7; i >= 0; i--) - { - buf[i] = "0123456789ABCDEF"[val & 0x0F]; - val >>= 4; - } - buf[8] = '\0'; - puts(buf); -} - -/* - * PCI/ISA I/O support - */ - -volatile unsigned char *ISA_io = (unsigned char *)0x80000000; -volatile unsigned char *ISA_mem = (unsigned char *)0xC0000000; - -void -outb(int port, char val) -{ - /* Ensure I/O operations complete */ - __asm__ volatile("eieio"); - ISA_io[port] = val; -} - -unsigned char -inb(int port) -{ - /* Ensure I/O operations complete */ - __asm__ volatile("eieio"); - return (ISA_io[port]); -} - -unsigned long -local_to_PCI(unsigned long addr) -{ - return ((addr & 0x7FFFFFFF) | 0x80000000); -} - -void -_bcopy(char *src, char *dst, int len) -{ - while (len--) *dst++ = *src++; -} diff -Nru a/arch/ppc/mbxboot/offset b/arch/ppc/mbxboot/offset --- a/arch/ppc/mbxboot/offset Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,4 +0,0 @@ -#!/bin/bash - -OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux| awk '{print $6}'` -echo "0x"$OFFSET diff -Nru a/arch/ppc/mbxboot/pci.c b/arch/ppc/mbxboot/pci.c --- a/arch/ppc/mbxboot/pci.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,252 +0,0 @@ -/* Stand alone funtions for QSpan Tundra support. - */ -#include -#include -#include -#include - -/* To map PCI devices, you first write 0xffffffff into the device - * base address registers. When the register is read back, the - * number of most significant '1' bits describes the amount of address - * space needed for mapping. If the most significant bit is not set, - * either the device does not use that address register, or it has - * a fixed address that we can't change. After the address is assigned, - * the command register has to be written to enable the card. - */ -typedef struct { - u_char pci_bus; - u_char pci_devfn; - ushort pci_command; - uint pci_addrs[6]; -} pci_map_t; - -/* We should probably dynamically allocate these structures. -*/ -#define MAX_PCI_DEVS 32 -int pci_dev_cnt; -pci_map_t pci_map[MAX_PCI_DEVS]; - -void pci_conf_write(int bus, int device, int func, int reg, uint writeval); -void pci_conf_read(int bus, int device, int func, int reg, void *readval); -void probe_addresses(int bus, int devfn); -void map_pci_addrs(void); - -/* This is a really stripped version of PCI bus scan. All we are - * looking for are devices that exist. - */ -pci_scanner(int addr_probe) -{ - unsigned int devfn, l, max, class, bus_number; - unsigned char cmd, irq, tmp, hdr_type, is_multi; - int reg; - - is_multi = 0; - bus_number = 0; - for (devfn = 0; devfn < 0xff; ++devfn) { - /* The device numbers are comprised of upper 5 bits of - * device number and lower 3 bits of multi-function number. - */ - if ((devfn & 7) && !is_multi) { - /* Don't scan multifunction addresses if this is - * not a multifunction device. - */ - continue; - } - - /* Read the header to determine card type. - */ - qs_pci_read_config_byte(bus_number, devfn, PCI_HEADER_TYPE, - &hdr_type); - - /* If this is a base device number, check the header to - * determine if it is mulifunction. - */ - if ((devfn & 7) == 0) - is_multi = hdr_type & 0x80; - - /* Check to see if the board is really in the slot. - */ - qs_pci_read_config_dword(bus_number, devfn, PCI_VENDOR_ID, &l); - /* some broken boards return 0 if a slot is empty: */ - if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff || - l == 0xffff0000) { - /* Nothing there. - */ - is_multi = 0; - continue; - } - - /* If we are not performing an address probe, - * just simply print out some information. - */ - if (!addr_probe) { - qs_pci_read_config_dword(bus_number, devfn, - PCI_CLASS_REVISION, &class); - - class >>= 8; /* upper 3 bytes */ - -#if 0 - printf("Found (%3d:%d): vendor 0x%04x, device 0x%04x, class 0x%06x\n", - (devfn >> 3), (devfn & 7), - (l & 0xffff), (l >> 16) & 0xffff, class); -#else - puts("Found ("); puthex(devfn >> 3); - puts(":"); puthex(devfn & 7); - puts("): vendor "); puthex(l & 0xffff); - puts(", device "); puthex((l >> 16) & 0xffff); - puts(", class "); puthex(class); puts("\n"); -#endif - } - else { - /* If this is a "normal" device, build address list. - */ - if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_NORMAL) - probe_addresses(bus_number, devfn); - } - } - - /* Now map the boards. - */ - if (addr_probe) - map_pci_addrs(); -} - -/* Probe addresses for the specified device. This is a destructive - * operation because it writes the registers. - */ -void -probe_addresses(bus, devfn) -{ - int i; - uint pciaddr; - ushort pcicmd; - pci_map_t *pm; - - if (pci_dev_cnt >= MAX_PCI_DEVS) { - puts("Too many PCI devices\n"); - return; - } - - pm = &pci_map[pci_dev_cnt++]; - - pm->pci_bus = bus; - pm->pci_devfn = devfn; - - for (i=0; i<6; i++) { - qs_pci_write_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), -1); - qs_pci_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), - &pciaddr); - pm->pci_addrs[i] = pciaddr; - qs_pci_read_config_word(bus, devfn, PCI_COMMAND, &pcicmd); - pm->pci_command = pcicmd; - } -} - -/* Map the cards into the PCI space. The PCI has separate memory - * and I/O spaces. In addition, some memory devices require mapping - * below 1M. The least significant 4 bits of the address register - * provide information. If this is an I/O device, only the LS bit - * is used to indicate that, so I/O devices can be mapped to a two byte - * boundard. Memory addresses can be mapped to a 32 byte boundary. - * The QSpan implementations usually have a 1Gbyte space for each - * memory and I/O spaces. - * - * This isn't a terribly fancy algorithm. I just map the spaces from - * the top starting with the largest address space. When finished, - * the registers are written and the card enabled. - * - * While the Tundra can map a large address space on most boards, we - * need to be careful because it may overlap other devices (like IMMR). - */ -#define MEMORY_SPACE_SIZE 0x20000000 -#define IO_SPACE_SIZE 0x20000000 - -void -map_pci_addrs() -{ - uint pci_mem_top, pci_mem_low; - uint pci_io_top; - uint addr_mask, reg_addr, space; - int i, j; - pci_map_t *pm; - - pci_mem_top = MEMORY_SPACE_SIZE; - pci_io_top = IO_SPACE_SIZE; - pci_mem_low = (1 * 1024 * 1024); /* Below one meg addresses */ - - /* We can't map anything more than the maximum space, but test - * for it anyway to catch devices out of range. - */ - addr_mask = 0x80000000; - - do { - space = (~addr_mask) + 1; /* Size of the space */ - for (i=0; ipci_addrs[j]; - if ((reg_addr & 0x80000000) == 0) - continue; - if (reg_addr & PCI_BASE_ADDRESS_SPACE_IO) { - if ((reg_addr & PCI_BASE_ADDRESS_IO_MASK) != addr_mask) - continue; - if (pci_io_top < space) { - puts("Out of PCI I/O space\n"); - } - else { - pci_io_top -= space; - pm->pci_addrs[j] = pci_io_top; - pm->pci_command |= PCI_COMMAND_IO; - } - } - else { - if ((reg_addr & PCI_BASE_ADDRESS_MEM_MASK) != addr_mask) - continue; - - /* Memory space. Test if below 1M. - */ - if (reg_addr & PCI_BASE_ADDRESS_MEM_TYPE_1M) { - if (pci_mem_low < space) { - puts("Out of PCI 1M space\n"); - } - else { - pci_mem_low -= space; - pm->pci_addrs[j] = pci_mem_low; - } - } - else { - if (pci_mem_top < space) { - puts("Out of PCI Mem space\n"); - } - else { - pci_mem_top -= space; - pm->pci_addrs[j] = pci_mem_top; - } - } - pm->pci_command |= PCI_COMMAND_MEMORY; - } - } - } - addr_mask >>= 1; - addr_mask |= 0x80000000; - } while (addr_mask != 0xfffffffe); - - /* Now, run the list one more time and map everything. - */ - for (i=0; ipci_bus, pm->pci_devfn, - PCI_BASE_ADDRESS_0 + (j * 4), pm->pci_addrs[j]); - } - - /* Enable memory or address mapping. - */ - qs_pci_write_config_word(pm->pci_bus, pm->pci_devfn, PCI_COMMAND, - pm->pci_command); - } -} - diff -Nru a/arch/ppc/mbxboot/qspan_pci.c b/arch/ppc/mbxboot/qspan_pci.c --- a/arch/ppc/mbxboot/qspan_pci.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,268 +0,0 @@ -/* - * LinuxPPC arch/ppc/kernel/qspan_pci.c Dan Malek (dmalek@jlc.net) - * - * QSpan Motorola bus to PCI bridge. The config address register - * is located 0x500 from the base of the bridge control/status registers. - * The data register is located at 0x504. - * This is a two step operation. First, the address register is written, - * then the data register is read/written as required. - * I don't know what to do about interrupts (yet). - */ - -#include -#include -#include -#include - -/* - * When reading the configuration space, if something does not respond - * the bus times out and we get a machine check interrupt. So, the - * good ol' exception tables come to mind to trap it and return some - * value. - * - * On an error we just return a -1, since that is what the caller wants - * returned if nothing is present. I copied this from __get_user_asm, - * with the only difference of returning -1 instead of EFAULT. - * There is an associated hack in the machine check trap code. - * - * The QSPAN is also a big endian device, that is it makes the PCI - * look big endian to us. This presents a problem for the Linux PCI - * functions, which assume little endian. For example, we see the - * first 32-bit word like this: - * ------------------------ - * | Device ID | Vendor ID | - * ------------------------ - * If we read/write as a double word, that's OK. But in our world, - * when read as a word, device ID is at location 0, not location 2 as - * the little endian PCI would believe. We have to switch bits in - * the PCI addresses given to us to get the data to/from the correct - * byte lanes. - * - * The QSPAN only supports 4 bits of "slot" in the dev_fn instead of 5. - * It always forces the MS bit to zero. Therefore, dev_fn values - * greater than 128 are returned as "no device found" errors. - * - * The QSPAN can only perform long word (32-bit) configuration cycles. - * The "offset" must have the two LS bits set to zero. Read operations - * require we read the entire word and then sort out what should be - * returned. Write operations other than long word require that we - * read the long word, update the proper word or byte, then write the - * entire long word back. - * - * PCI Bridge hack. We assume (correctly) that bus 0 is the primary - * PCI bus from the QSPAN. If we are called with a bus number other - * than zero, we create a Type 1 configuration access that a downstream - * PCI bridge will interpret. - */ - -#define __get_pci_config(x, addr, op) \ - __asm__ __volatile__( \ - "1: "op" %0,0(%1)\n" \ - " eieio\n" \ - "2:\n" \ - ".section .fixup,\"ax\"\n" \ - "3: li %0,-1\n" \ - " b 2b\n" \ - ".section __ex_table,\"a\"\n" \ - " .align 2\n" \ - " .long 1b,3b\n" \ - ".text" \ - : "=r"(x) : "r"(addr)) - -#define QS_CONFIG_ADDR ((volatile uint *)(PCI_CSR_ADDR + 0x500)) -#define QS_CONFIG_DATA ((volatile uint *)(PCI_CSR_ADDR + 0x504)) - -#define mk_config_addr(bus, dev, offset) \ - (((bus)<<16) | ((dev)<<8) | (offset & 0xfc)) - -#define mk_config_type1(bus, dev, offset) \ - mk_config_addr(bus, dev, offset) | 1; - -/* Initialize the QSpan device registers after power up. -*/ -qspan_init() -{ - uint *qptr; - - - - qptr = (uint *)PCI_CSR_ADDR; - - /* PCI Configuration/status. Upper bits written to clear - * pending interrupt or status. Lower bits enable QSPAN as - * PCI master, enable memory and I/O cycles, and enable PCI - * parity error checking. - * IMPORTANT: The last two bits of this word enable PCI - * master cycles into the QBus. The QSpan is broken and can't - * meet the timing specs of the PQ bus for this to work. Therefore, - * if you don't have external bus arbitration, you can't use - * this function. - */ -#ifdef EXTERNAL_PQ_ARB - qptr[1] = 0xf9000147; -#else - qptr[1] = 0xf9000144; -#endif - - /* PCI Misc configuration. Set PCI latency timer resolution - * of 8 cycles, set cache size to 4 x 32. - */ - qptr[3] = 0; - - /* Set up PCI Target address mapping. Enable, Posted writes, - * 2Gbyte space (processor memory controller determines actual size). - */ - qptr[64] = 0x8f000080; - - /* Map processor 0x80000000 to PCI 0x00000000. - * Processor address bit 1 determines I/O type access (0x80000000) - * or memory type access (0xc0000000). - */ - qptr[65] = 0x80000000; - - /* Enable error logging and clear any pending error status. - */ - qptr[80] = 0x90000000; - - qptr[512] = 0x000c0003; - - /* Set up Qbus slave image. - */ - qptr[960] = 0x01000000; - qptr[961] = 0x000000d1; - qptr[964] = 0x00000000; - qptr[965] = 0x000000d1; - -} - -/* Functions to support PCI bios-like features to read/write configuration - * space. If the function fails for any reason, a -1 (0xffffffff) value - * must be returned. - */ -#define DEVICE_NOT_FOUND (-1) -#define SUCCESSFUL 0 - -int qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char *val) -{ - uint temp; - u_char *cp; - - if ((bus > 7) || (dev_fn > 127)) { - *val = 0xff; - return DEVICE_NOT_FOUND; - } - - if (bus == 0) - *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); - else - *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); - __get_pci_config(temp, QS_CONFIG_DATA, "lwz"); - - offset ^= 0x03; - cp = ((u_char *)&temp) + (offset & 0x03); - *val = *cp; - return SUCCESSFUL; -} - -int qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short *val) -{ - uint temp; - ushort *sp; - - if ((bus > 7) || (dev_fn > 127)) { - *val = 0xffff; - return DEVICE_NOT_FOUND; - } - - if (bus == 0) - *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); - else - *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); - __get_pci_config(temp, QS_CONFIG_DATA, "lwz"); - offset ^= 0x02; - - sp = ((ushort *)&temp) + ((offset >> 1) & 1); - *val = *sp; - return SUCCESSFUL; -} - -int qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int *val) -{ - if ((bus > 7) || (dev_fn > 127)) { - *val = 0xffffffff; - return DEVICE_NOT_FOUND; - } - if (bus == 0) - *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); - else - *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); - __get_pci_config(*val, QS_CONFIG_DATA, "lwz"); - return SUCCESSFUL; -} - -int qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned char val) -{ - uint temp; - u_char *cp; - - if ((bus > 7) || (dev_fn > 127)) - return DEVICE_NOT_FOUND; - - qs_pci_read_config_dword(bus, dev_fn, offset, &temp); - - offset ^= 0x03; - cp = ((u_char *)&temp) + (offset & 0x03); - *cp = val; - - if (bus == 0) - *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); - else - *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); - *QS_CONFIG_DATA = temp; - - return SUCCESSFUL; -} - -int qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned short val) -{ - uint temp; - ushort *sp; - - if ((bus > 7) || (dev_fn > 127)) - return DEVICE_NOT_FOUND; - - qs_pci_read_config_dword(bus, dev_fn, offset, &temp); - - offset ^= 0x02; - sp = ((ushort *)&temp) + ((offset >> 1) & 1); - *sp = val; - - if (bus == 0) - *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); - else - *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); - *QS_CONFIG_DATA = temp; - - return SUCCESSFUL; -} - -int qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char offset, unsigned int val) -{ - if ((bus > 7) || (dev_fn > 127)) - return DEVICE_NOT_FOUND; - - if (bus == 0) - *QS_CONFIG_ADDR = mk_config_addr(bus, dev_fn, offset); - else - *QS_CONFIG_ADDR = mk_config_type1(bus, dev_fn, offset); - *(unsigned int *)QS_CONFIG_DATA = val; - - return SUCCESSFUL; -} - diff -Nru a/arch/ppc/mbxboot/rdimage.c b/arch/ppc/mbxboot/rdimage.c --- a/arch/ppc/mbxboot/rdimage.c Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,8 +0,0 @@ -/* - * rdimage.c - * - * Dummy file to allow a compressed initrd to be added - * into a linker section, accessed by the boot coode - */ - -char dummy_for_rdimage; diff -Nru a/arch/ppc/mbxboot/size b/arch/ppc/mbxboot/size --- a/arch/ppc/mbxboot/size Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,4 +0,0 @@ -#!/bin/bash - -OFFSET=`$1 -h $2 | grep $3 | grep -v zvmlinux | awk '{print $3}'` -echo "0x"$OFFSET diff -Nru a/arch/ppc/mm/4xx_tlb.c b/arch/ppc/mm/4xx_tlb.c --- a/arch/ppc/mm/4xx_tlb.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/mm/4xx_tlb.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * * Copyright (c) 1998-1999 TiVo, Inc. * Original implementation. diff -Nru a/arch/ppc/mm/4xx_tlb.h b/arch/ppc/mm/4xx_tlb.h --- a/arch/ppc/mm/4xx_tlb.h Mon May 21 17:07:04 2001 +++ b/arch/ppc/mm/4xx_tlb.h Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * * Copyright (c) 1999 Grant Erickson * diff -Nru a/arch/ppc/mm/Makefile b/arch/ppc/mm/Makefile --- a/arch/ppc/mm/Makefile Mon May 21 17:07:05 2001 +++ b/arch/ppc/mm/Makefile Mon May 21 17:07:05 2001 @@ -1,3 +1,5 @@ +# BK Id: %F% %I% %G% %U% %#% +# # # Makefile for the linux ppc-specific parts of the memory manager. # @@ -7,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 Mon May 21 17:07:04 2001 +++ b/arch/ppc/mm/extable.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * linux/arch/ppc/mm/extable.c * * from linux/arch/i386/mm/extable.c diff -Nru a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c --- a/arch/ppc/mm/fault.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/mm/fault.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * arch/ppc/mm/fault.c * * PowerPC version @@ -41,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 Mon May 21 17:07:05 2001 @@ -0,0 +1,629 @@ +/* + * 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 "../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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/mm/init.c Mon May 21 17:07:03 2001 @@ -1,6 +1,7 @@ /* - * $Id: init.c,v 1.195 1999/10/15 16:39:39 cort Exp $ - * + * BK Id: %F% %I% %G% %U% %#% + */ +/* * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * @@ -61,6 +62,7 @@ #include #include #include +#include #include "mem_pieces.h" @@ -72,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; @@ -186,12 +194,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; @@ -210,35 +212,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; @@ -481,14 +454,14 @@ 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 (mem_init_done && Hash != 0) + flush_hash_page(0, va, pg); } spin_unlock(&init_mm.page_table_lock); return err; } -#ifndef CONFIG_8xx +#if !defined(CONFIG_4xx) && !defined(CONFIG_8xx) /* * TLB flushing: * @@ -509,19 +482,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 */ } /* @@ -532,30 +500,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 @@ -564,10 +520,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 @@ -575,28 +542,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); @@ -604,59 +586,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. @@ -767,10 +696,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 @@ -838,16 +767,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; /* @@ -902,6 +874,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 */ @@ -993,7 +967,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 @@ -1011,6 +987,49 @@ 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; + 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; + 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 @@ -1031,6 +1050,8 @@ if (_machine == _MACH_Pmac || _machine == _MACH_chrp) map_bootx_text(); #endif + + mmu_context_init(); } #endif /* CONFIG_4xx */ @@ -1094,12 +1115,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; @@ -1207,8 +1222,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 @@ -1270,10 +1287,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) @@ -1282,10 +1299,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 @@ -1293,6 +1306,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; @@ -1319,7 +1345,7 @@ unsigned long kstart, ksize; /* - * Initially, available phyiscal memory is equivalent to all + * Initially, available physical memory is equivalent to all * physical memory. */ @@ -1355,4 +1381,76 @@ 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); +} + +/* + * 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); + } +} + +/* + * 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 Mon May 21 17:07:03 2001 +++ b/arch/ppc/mm/mem_pieces.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Copyright (c) 1996 Paul Mackerras * Changes to accomodate Power Macintoshes. * Cort Dougan diff -Nru a/arch/ppc/mm/mem_pieces.h b/arch/ppc/mm/mem_pieces.h --- a/arch/ppc/mm/mem_pieces.h Mon May 21 17:07:04 2001 +++ b/arch/ppc/mm/mem_pieces.h Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Copyright (c) 1996 Paul Mackerras * Changes to accomodate Power Macintoshes. * Cort Dougan diff -Nru a/arch/ppc/treeboot/Makefile b/arch/ppc/treeboot/Makefile --- a/arch/ppc/treeboot/Makefile Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,57 +0,0 @@ -# -# Copyright (c) 1999 Grant Erickson -# -# Module name: Makefile -# -# Description: -# Makefile for the IBM "tree" evaluation board Linux kernel -# boot loaders. -# - -HOSTCFLAGS = -O -I$(TOPDIR)/include - -GZIP = gzip -vf9 -RM = rm -f -MKEVIMG = mkevimg -l -MKIRIMG = mkirimg - -CFLAGS = -O -fno-builtin -I$(TOPDIR)/include -LD_ARGS = -e _start -T ld.script -Ttext 0x00200000 -Bstatic - -OBJS = crt0.o main.o misc.o irSect.o ../coffboot/string.o ../coffboot/zlib.o -LIBS = - -treeboot: $(OBJS) ld.script - $(LD) -o $@ $(LD_ARGS) $(OBJS) $(LIBS) - -zImage: vmlinux.img - -zImage.initrd: vmlinux.initrd.img - -treeboot.image: treeboot vmlinux.gz - $(OBJCOPY) --add-section=image=vmlinux.gz treeboot $@ - -treeboot.initrd: treeboot.image ramdisk.image.gz - $(OBJCOPY) --add-section=initrd=ramdisk.image.gz treeboot.image $@ - -vmlinux.img: treeboot.image - $(OBJDUMP) --syms treeboot.image | grep irSectStart > irSectStart.txt - $(MKIRIMG) treeboot.image treeboot.image.out irSectStart.txt - $(MKEVIMG) treeboot.image.out $@ - $(RM) treeboot.image treeboot.image.out irSectStart.txt - -vmlinux.initrd.img: treeboot.initrd - $(OBJDUMP) --all-headers treeboot.initrd | grep irSectStart > irSectStart.txt - $(MKIRIMG) treeboot.initrd treeboot.initrd.out irSectStart.txt - $(MKEVIMG) treeboot.initrd.out $@ - $(RM) treeboot.initrd treeboot.initrd.out irSectStart.txt - -vmlinux.gz: $(TOPDIR)/vmlinux - $(OBJCOPY) -S -O binary $(TOPDIR)/vmlinux vmlinux - $(GZIP) vmlinux - -clean: - rm -f treeboot treeboot.image treeboot.initrd irSectStart.txt vmlinux.* *.o - -fastdep: - diff -Nru a/arch/ppc/treeboot/crt0.S b/arch/ppc/treeboot/crt0.S --- a/arch/ppc/treeboot/crt0.S Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 1997 Paul Mackerras - * Initial Power Macintosh COFF version. - * Copyright (c) 1999 Grant Erickson - * Modifications for IBM PowerPC 400-class processor evaluation - * boards. - * - * Module name: crt0.S - * - * Description: - * Boot loader execution entry point. Clears out .bss section as per - * ANSI C requirements. Invalidates and flushes the caches over the - * range covered by the boot loader's .text section. Sets up a stack - * below the .text section entry point. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include "../kernel/ppc_asm.tmpl" - - .text - - .globl _start -_start: - ## Clear out the BSS as per ANSI C requirements - - lis r7,_end@ha # - addi r7,r7,_end@l # r7 = &_end - lis r8,__bss_start@ha # - addi r8,r8,__bss_start@l # r8 = &_bss_start - - ## Determine how large an area, in number of words, to clear - - subf r7,r8,r7 # r7 = &_end - &_bss_start + 1 - addi r7,r7,3 # r7 += 3 - srwi. r7,r7,2 # r7 = size in words. - beq 2f # If the size is zero, do not bother - addi r8,r8,-4 # r8 -= 4 - mtctr r7 # SPRN_CTR = number of words to clear - li r0,0 # r0 = 0 -1: stwu r0,4(r8) # Clear out a word - bdnz 1b # If we are not done yet, keep clearing - - ## Flush and invalidate the caches for the range in memory covering - ## the .text section of the boot loader - -2: lis r9,_start@h # r9 = &_start - lis r8,_etext@ha # - addi r8,r8,_etext@l # r8 = &_etext -3: dcbf r0,r9 # Flush the data cache - icbi r0,r9 # Invalidate the instruction cache - addi r9,r9,0x10 # Increment by one cache line - cmplwi cr0,r9,r8 # Are we at the end yet? - blt 3b # No, keep flushing and invalidating - - ## Set up the stack - - lis r9,_start@h # r9 = &_start (text section entry) - addi r9,r9,_start@l - subi r1,r9,64 # Start the stack 64 bytes below _start - clrrwi r1,r1,4 # Make sure it is aligned on 16 bytes. - li r0,0 - stwu r0,-16(r1) - mtlr r9 - - b start # All done, start the real work. diff -Nru a/arch/ppc/treeboot/elf.pl b/arch/ppc/treeboot/elf.pl --- a/arch/ppc/treeboot/elf.pl Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,33 +0,0 @@ -# -# ELF header field numbers -# - -$e_ident = 0; # Identification bytes / magic number -$e_type = 1; # ELF file type -$e_machine = 2; # Target machine type -$e_version = 3; # File version -$e_entry = 4; # Start address -$e_phoff = 5; # Program header file offset -$e_shoff = 6; # Section header file offset -$e_flags = 7; # File flags -$e_ehsize = 8; # Size of ELF header -$e_phentsize = 9; # Size of program header -$e_phnum = 10; # Number of program header entries -$e_shentsize = 11; # Size of section header -$e_shnum = 12; # Number of section header entries -$e_shstrndx = 13; # Section header table string index - -# -# Section header field numbers -# - -$sh_name = 0; # Section name -$sh_type = 1; # Section header type -$sh_flags = 2; # Section header flags -$sh_addr = 3; # Virtual address -$sh_offset = 4; # File offset -$sh_size = 5; # Section size -$sh_link = 6; # Miscellaneous info -$sh_info = 7; # More miscellaneous info -$sh_addralign = 8; # Memory alignment -$sh_entsize = 9; # Entry size if this is a table diff -Nru a/arch/ppc/treeboot/irSect.c b/arch/ppc/treeboot/irSect.c --- a/arch/ppc/treeboot/irSect.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,36 +0,0 @@ -/* - * - * Copyright (c) 1999 Grant Erickson - * - * Module name: irSect.c - * - * Description: - * Defines variables to hold the absolute starting address and size - * of the Linux kernel "image" and the initial RAM disk "initrd" - * sections within the boot loader. - * - */ - -#include "irSect.h" - - -/* - * The order of globals below must not change. If more globals are added, - * you must change the script 'mkirimg' accordingly. - * - */ - -/* - * irSectStart must be at beginning of file - */ -unsigned int irSectStart = 0xdeadbeaf; - -unsigned int imageSect_start = 0; -unsigned int imageSect_size = 0; -unsigned int initrdSect_start = 0; -unsigned int initrdSect_size = 0; - -/* - * irSectEnd must be at end of file - */ -unsigned int irSectEnd = 0xdeadbeaf; diff -Nru a/arch/ppc/treeboot/irSect.h b/arch/ppc/treeboot/irSect.h --- a/arch/ppc/treeboot/irSect.h Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,32 +0,0 @@ -/* - * - * Copyright (c) 1999 Grant Erickson - * - * Module name: irSect.h - * - * Description: - * Defines variables to hold the absolute starting address and size - * of the Linux kernel "image" and the initial RAM disk "initrd" - * sections within the boot loader. - * - */ - -#ifndef __IRSECT_H__ -#define __IRSECT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -extern unsigned int imageSect_start; -extern unsigned int imageSect_size; - -extern unsigned int initrdSect_start; -extern unsigned int initrdSect_size; - - -#ifdef __cplusplus -} -#endif - -#endif /* __IRSECT_H__ */ diff -Nru a/arch/ppc/treeboot/ld.script b/arch/ppc/treeboot/ld.script --- a/arch/ppc/treeboot/ld.script Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,68 +0,0 @@ -OUTPUT_ARCH(powerpc) -SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib); SEARCH_DIR(/usr/local/powerpc-any-elf/lib); -/* Do we need any of these for elf? - __DYNAMIC = 0; */ -SECTIONS -{ - /* Read-only sections, merged into text segment: */ - . = + SIZEOF_HEADERS; - .interp : { *(.interp) } - .hash : { *(.hash) } - .dynsym : { *(.dynsym) } - .dynstr : { *(.dynstr) } - .rel.text : { *(.rel.text) } - .rela.text : { *(.rela.text) } - .rel.data : { *(.rel.data) } - .rela.data : { *(.rela.data) } - .rel.rodata : { *(.rel.rodata) } - .rela.rodata : { *(.rela.rodata) } - .rel.got : { *(.rel.got) } - .rela.got : { *(.rela.got) } - .rel.ctors : { *(.rel.ctors) } - .rela.ctors : { *(.rela.ctors) } - .rel.dtors : { *(.rel.dtors) } - .rela.dtors : { *(.rela.dtors) } - .rel.bss : { *(.rel.bss) } - .rela.bss : { *(.rela.bss) } - .rel.plt : { *(.rel.plt) } - .rela.plt : { *(.rela.plt) } - .init : { *(.init) } =0 - .plt : { *(.plt) } - .text : - { - *(.text) - *(.rodata) - *(.rodata1) - *(.got1) - } - .fini : { *(.fini) } =0 - .ctors : { *(.ctors) } - .dtors : { *(.dtors) } - _etext = .; - PROVIDE (etext = .); - /* Read-write section, merged into data segment: */ - . = (. + 0x0FFF) & 0xFFFFF000; - .data : - { - *(.data) - *(.data1) - *(.sdata) - *(.sdata2) - *(.got.plt) *(.got) - *(.dynamic) - CONSTRUCTORS - } - _edata = .; - PROVIDE (edata = .); - __bss_start = .; - .bss : - { - *(.sbss) *(.scommon) - *(.dynbss) - *(.bss) - *(COMMON) - } - _end = . ; - PROVIDE (end = .); -} - diff -Nru a/arch/ppc/treeboot/main.c b/arch/ppc/treeboot/main.c --- a/arch/ppc/treeboot/main.c Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,240 +0,0 @@ -/* - * Copyright (c) 1997 Paul Mackerras - * Initial Power Macintosh COFF version. - * Copyright (c) 1999 Grant Erickson - * Modifications for an ELF-based IBM evaluation board version. - * - * Module name: main.c - * - * Description: - * This module does most of the real work for the boot loader. It - * checks the variables holding the absolute start address and size - * of the Linux kernel "image" and initial RAM disk "initrd" sections - * and if they are present, moves them to their "proper" locations. - * - * For the Linux kernel, "proper" is physical address 0x00000000. - * For the RAM disk, "proper" is the image's size below the top - * of physical memory. The Linux kernel may be in either raw - * binary form or compressed with GNU zip (aka gzip). - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - */ - -#include - -#include "../coffboot/nonstdio.h" -#include "../coffboot/zlib.h" -#include "irSect.h" - - -/* Preprocessor Defines */ - -/* - * Location of the IBM boot ROM function pointer address for retrieving - * the board information structure. - */ - -#define BOARD_INFO_VECTOR 0xFFFE0B50 - -#define RAM_SIZE (4 * 1024 * 1024) - -#define RAM_PBASE 0x00000000 -#define RAM_PEND (RAM_PBASE + RAM_SIZE) - -#define RAM_VBASE 0xC0000000 -#define RAM_VEND (RAM_VBASE + RAM_SIZE) - -#define RAM_START RAM_PBASE -#define RAM_END RAM_PEND -#define RAM_FREE (imageSect_start + imageSect_size + initrdSect_size) - -#define PROG_START RAM_START - - -/* Function Macros */ - -#define ALIGN_UP(x, align) (((x) + ((align) - 1)) & ~((align) - 1)) - - -/* Global Variables */ - -/* Needed by zalloc and zfree for allocating memory */ - -char *avail_ram; /* Indicates start of RAM available for heap */ -char *end_avail; /* Indicates end of RAM available for heap */ - -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). - */ - -static char *cmdline = ""; - - -/* Function Prototypes */ - -void *zalloc(void *x, unsigned items, unsigned size); -void zfree(void *x, void *addr, unsigned nb); - -void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp); - -void printf () {} -void pause () {} -void exit () {} - - -void start(void) -{ - void *options; - int ns, oh, i; - unsigned long sa, len; - void *dst; - unsigned char *im; - unsigned long initrd_start, initrd_size; - bd_t *(*get_board_info)(void) = - (bd_t *(*)(void))(*(unsigned long *)BOARD_INFO_VECTOR); - bd_t *bip = NULL; - - if ((bip = get_board_info()) != NULL) - memcpy(&board_info, bip, sizeof(bd_t)); - - /* setup_bats(RAM_START); */ - - /* Init RAM disk (initrd) section */ - - if (initrdSect_start != 0 && (initrd_size = initrdSect_size) != 0) { - initrd_start = (RAM_END - initrd_size) & ~0xFFF; - - printf("Initial RAM disk at 0x%08x (%u bytes)\n", - initrd_start, initrd_size); - - memcpy((char *)initrd_start, - (char *)(initrdSect_start), - initrdSect_size); - - end_avail = (char *)initrd_start; - } else { - initrd_start = initrd_size = 0; - end_avail = (char *)RAM_END; - } - - /* Linux kernel image section */ - - im = (unsigned char *)(imageSect_start); - len = imageSect_size; - dst = (void *)PROG_START; - - /* Check for the gzip archive magic numbers */ - - if (im[0] == 0x1f && im[1] == 0x8b) { - - /* The gunzip routine needs everything nice and aligned */ - - void *cp = (void *)ALIGN_UP(RAM_FREE, 8); - avail_ram = (void *)(cp + ALIGN_UP(len, 8)); - memcpy(cp, im, len); - - /* I'm not sure what the 0x200000 parameter is for, but it works. */ - - gunzip(dst, 0x200000, cp, (int *)&len); - } else { - memmove(dst, im, len); - } - - flush_cache(dst, len); - - sa = (unsigned long)dst; - - (*(void (*)())sa)(&board_info, - initrd_start, - initrd_start + initrd_size, - cmdline, - cmdline + strlen(cmdline)); - - pause(); -} - -void *zalloc(void *x, unsigned items, unsigned size) -{ - void *p = avail_ram; - - size *= items; - size = ALIGN_UP(size, 8); - avail_ram += size; - if (avail_ram > end_avail) { - printf("oops... out of memory\n"); - pause(); - } - return p; -} - -void zfree(void *x, void *addr, unsigned nb) -{ - -} - -#define HEAD_CRC 2 -#define EXTRA_FIELD 4 -#define ORIG_NAME 8 -#define COMMENT 0x10 -#define RESERVED 0xe0 - -#define DEFLATED 8 - -void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp) -{ - z_stream s; - int r, i, flags; - - /* skip header */ - i = 10; - flags = src[3]; - if (src[2] != DEFLATED || (flags & RESERVED) != 0) { - printf("bad gzipped data\n"); - exit(); - } - if ((flags & EXTRA_FIELD) != 0) - i = 12 + src[10] + (src[11] << 8); - if ((flags & ORIG_NAME) != 0) - while (src[i++] != 0) - ; - if ((flags & COMMENT) != 0) - while (src[i++] != 0) - ; - if ((flags & HEAD_CRC) != 0) - i += 2; - if (i >= *lenp) { - printf("gunzip: ran out of data in header\n"); - exit(); - } - printf("done 1\n"); - s.zalloc = zalloc; - s.zfree = zfree; - r = inflateInit2(&s, -MAX_WBITS); - if (r != Z_OK) { - printf("inflateInit2 returned %d\n", r); - exit(); - } - s.next_in = src + i; - s.avail_in = *lenp - i; - s.next_out = dst; - s.avail_out = dstlen; - printf("doing inflate\n"); - r = inflate(&s, Z_FINISH); - printf("done inflate\n"); - if (r != Z_OK && r != Z_STREAM_END) { - printf("inflate returned %d\n", r); - exit(); - } - *lenp = s.next_out - (unsigned char *) dst; - printf("doing end\n"); - inflateEnd(&s); -} diff -Nru a/arch/ppc/treeboot/misc.S b/arch/ppc/treeboot/misc.S --- a/arch/ppc/treeboot/misc.S Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,40 +0,0 @@ -/* - * Copyright (C) Paul Mackerras 1997. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#include "../kernel/ppc_asm.tmpl" - - .text - -/* - * Flush the dcache and invalidate the icache for a range of addresses. - * - * flush_cache(addr, len) - */ - .global flush_cache -flush_cache: - mfpvr r5 # Get processor version register - extrwi r5,r5,16,0 # Get the version bits - cmpwi cr0,r5,0x0020 # Is this a 403-based processor? - beq 1f # Yes, it is - li r5,32 # It is not a 403, set to 32 bytes - addi r4,r4,32-1 # len += line_size - 1 - srwi. r4,r4,5 # Convert from bytes to lines - b 2f -1: li r5,16 # It is a 403, set to 16 bytes - addi r4,r4,16-1 # len += line_size - 1 - srwi. r4,r4,4 # Convert from bytes to lines -2: mtctr r4 # Set-up the counter register - beqlr # If it is 0, we are done -3: dcbf r0,r3 # Flush and invalidate the data line - icbi r0,r3 # Invalidate the instruction line - add r3,r3,r5 # Move to the next line - bdnz 3b # Are we done yet? - sync - isync - blr # Return to the caller diff -Nru a/arch/ppc/treeboot/mkevimg b/arch/ppc/treeboot/mkevimg --- a/arch/ppc/treeboot/mkevimg Mon May 21 17:07:03 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,437 +0,0 @@ -#!/usr/bin/perl - -# -# Copyright (c) 1998-1999 TiVo, Inc. -# All rights reserved. -# -# Copyright (c) 1999 Grant Erickson -# Major syntactic and usability rework. -# -# Module name: mkevimg -# -# Description: -# Converts an ELF output file from the linker into the format used by -# the IBM evaluation board ROM Monitor to load programs from a host -# onto the evaluation board. The ELF file must be an otherwise execut- -# able file (with the text and data addresses bound at link time) and -# have space reserved after the entry point for the load information -# block: -# -# typedef struct boot_block { -# unsigned long magic; 0x0052504F -# unsigned long dest; Target address of the image -# unsigned long num_512blocks; Size, rounded-up, in 512 byte blocks -# unsigned long debug_flag; Run the debugger or image after load -# unsigned long entry_point; The image address to jump to after load -# unsigned long reserved[3]; -# } boot_block_t; -# -# - -use File::Basename; -use Getopt::Std; - -# -# usage() -# -# Description: -# This routine prints out the proper command line usage for this program -# -# Input(s): -# status - Flag determining what usage information will be printed and what -# the exit status of the program will be after the information is -# printed. -# -# Output(s): -# N/A -# -# Returns: -# This subroutine does not return. -# - -sub usage { - my($status); - $status = $_[0]; - - printf("Usage: %s [-hlvV] \n", - $program); - - if ($status != 0) { - printf("Try `%s -h' for more information.\n", $program); - } - - if ($status != 1) { - print(" -h Print out this message and exit.\n"); - print(" -l Linux mode; if present, copy 'image' and 'initrd' sections.\n"); - print(" -v Verbose. Print out lots of ELF information.\n"); - print(" -V Print out version information and exit.\n"); - } - - exit($status); -} - -# -# version() -# -# Description: -# This routine prints out program version information -# -# Input(s): -# N/A -# -# Output(s): -# N/A -# -# Returns: -# This subroutine does not return. -# - -sub version { - print("mkevimg Version 1.1.0\n"); - print("Copyright (c) 1998-1999 TiVo, Inc.\n"); - print("Copyright (c) 1999 Grant Erickson \n"); - - exit (0); -} - -# -# file_check() -# -# Description: -# This routine checks an input file to ensure that it exists, is a -# regular file, and is readable. -# -# Input(s): -# file - Input file to be checked. -# -# Output(s): -# N/A -# -# Returns: -# 0 if the file exists, is a regular file, and is readable, otherwise -1. -# - -sub file_check { - my($file); - $file = $_[0]; - - if (!(-e $file)) { - printf("The file \"%s\" does not exist.\n", $file); - return (-1); - } elsif (!(-f $file)) { - printf("The file \"%s\" is not a regular file.\n", $file); - return (-1); - } elsif (!(-r $file)) { - printf("The file \"%s\" is not readable.\n", $file); - return (-1); - } - - return (0); -} - -# -# decode_options() -# -# Description: -# This routine steps through the command-line arguments, parsing out -# recognzied options. -# -# Input(s): -# N/A -# -# Output(s): -# N/A -# -# Returns: -# N/A -# - -sub decode_options { - - if (!getopts("hlvV")) { - usage(1); - } - - if ($opt_h) { - usage(0); - } - - if ($opt_l) { - $linux = 1; - } - - if ($opt_V) { - version(); - exit (0); - } - - if ($opt_v) { - $verbose = 1; - } - - if (!($ifile = shift(@ARGV))) { - usage(1); - } - - if (!($ofile = shift(@ARGV))) { - usage (1); - } - - if (file_check($ifile)) { - exit(1); - } - -} - -# -# ELF file and section header field numbers -# - -require 'elf.pl'; - -# -# Main program body -# - -{ - $program = basename($0); - - decode_options(); - - open(ELF, "<$ifile") || die "Cannot open input file"; - - $ifilesize = (-s $ifile); - - if ($verbose) { - print("Output file: $ofile\n"); - print("Input file: $ifile, $ifilesize bytes.\n"); - } - - if (read(ELF, $ibuf, $ifilesize) != $ifilesize) { - print("Failed to read input file!\n"); - exit(1); - } - - # - # Parse ELF header - # - - @eh = unpack("a16n2N5n6", $ibuf); - - # - # Make sure this is actually a PowerPC ELF file. - # - - if (substr($eh[$e_ident], 0, 4) ne "\177ELF") { - printf("The file \"%s\" is not an ELF file.\n", $ifile); - exit (1); - } elsif ($eh[$e_machine] != 20) { - printf("The file \"%s\" is not a PowerPC ELF file.\n", $ifile); - exit (1); - } - - if ($verbose) { - print("File header:\n"); - printf(" Identifier: %s\n", $eh[$e_ident]); - printf(" Type: %d\n", $eh[$e_type]); - printf(" Machine: %d\n", $eh[$e_machine]); - printf(" Version: %d\n", $eh[$e_version]); - printf(" Entry point: 0x%08x\n", $eh[$e_entry]); - printf(" Program header offset: 0x%x\n", $eh[$e_phoff]); - printf(" Section header offset: 0x%x\n", $eh[$e_shoff]); - printf(" Flags: 0x%08x\n", $eh[$e_flags]); - printf(" Header size: %d\n", $eh[$e_ehsize]); - printf(" Program entry size: %d\n", $eh[$e_phentsize]); - printf(" Program table entries: %d\n", $eh[$e_phnum]); - printf(" Section header size: %d\n", $eh[$e_shentsize]); - printf(" Section table entries: %d\n", $eh[$e_shnum]); - printf(" String table section: %d\n", $eh[$e_shstrndx]); - } - - # - # Find the section header for the string table. - # - - $strtable_section_offset = $eh[$e_shoff] + - $eh[$e_shstrndx] * $eh[$e_shentsize]; - - if ($verbose) { - printf("String table section header offset: 0x%x\n", - $strtable_section_offset); - } - - # - # Find the start of the string table. - # - - @strh = unpack("N10", substr($ibuf, $strtable_section_offset, - $eh[$e_shentsize])); - - if ($verbose) { - printf("Section name strings start at: 0x%x, %d bytes.\n", - $strh[$sh_offset], $strh[$sh_size]); - } - - $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]); - - # Grab each section header and find '.text' and '.bss' sections in - # particular. - - if ($verbose) { - print("Section headers:\n"); - print("Idx Name Size Address File off Algn\n"); - print("--- ------------------------ -------- -------- -------- ----\n"); - } - - $off = $eh[$e_shoff]; - - for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) { - @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize])); - - # Take the first section name from the array returned by split. - - ($name) = split(/\000/, substr($names, $sh[$sh_name])); - - if ($verbose) { - printf("%3d %-24s %8x %08x %08x %4d\n", - $i, $name, $sh[$sh_size], $sh[$sh_addr], - $sh[$sh_offset], $sh[$sh_addralign]); - } - - # Attempt to find the .text and .bss sections - - if ($name =~ /^\.bss$/) { - ($bss_addr, $bss_offset, $bss_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - - } elsif ($name =~ /^\.text$/) { - ($text_addr, $text_offset, $text_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - - } elsif ($linux && ($name =~ /^\image$/)) { - $image_found = 1; - - ($image_addr, $image_offset, $image_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - - } elsif ($linux && ($name =~ /^\initrd$/)) { - $initrd_found = 1; - - ($initrd_addr, $initrd_offset, $initrd_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - - } - } - - printf("Text section - Address: 0x%08x, Size: 0x%08x\n", - $text_addr, $text_size); - printf("Bss section - Address: 0x%08x, Size: 0x%08x\n", - $bss_addr, $bss_size); - - if ($linux) { - if ($image_found) { - printf("Image section - Address: 0x%08x, Size: 0x%08x\n", - $image_addr, $image_size); - } - - if ($initrd_found) { - printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n", - $initrd_addr, $initrd_size); - } - } - - # - # Open output file - # - - open(BOOT, ">$ofile") || die "Cannot open output file"; - - # - # Compute image size - # - - $output_size = $bss_offset - $text_offset + $bss_size; - - if ($linux && $image_found) { - $output_size += $image_size; - } - - if ($linux && $initrd_found) { - $output_size += $initrd_size; - } - - $num_blocks = $output_size / 512 + 1; - - # - # Write IBM PowerPC evaluation board boot_block_t header - # - - $header = pack("H8N7", "0052504f", $text_addr, $num_blocks, 0, - $text_addr, 0, 0, 0); - - $bytes = length($header); - - if (($resid = syswrite(BOOT, $header, $bytes)) != $bytes) { - die("Could not write boot image header to output file."); - } - - printf("Entry point = 0x%08x\n", $text_addr); - printf("Image size = 0x%08x (%d bytes) (%d blocks).\n", - $output_size, $output_size, $num_blocks); - - # - # Write image starting after ELF and program headers and - # continuing to beginning of bss - # - - $bytes = $bss_offset - $text_offset + $bss_size; - - if (($resid = syswrite(BOOT, $ibuf, $bytes, $text_offset)) != $bytes) { - die("Could not write boot image to output file.\n"); - } - - # - # If configured, write out the image and initrd sections as well - # - - if ($linux) { - if ($image_found) { - $bytes = $image_size; - if (($resid = syswrite(BOOT, $ibuf, $bytes, $image_offset)) != $bytes) { - die("Could not write boot image to output file.\n"); - } - } - - if ($initrd_found) { - $bytes = $initrd_size; - if (($resid = syswrite(BOOT, $ibuf, $bytes, $initrd_offset)) != $bytes) { - die("Could not write boot image to output file.\n"); - } - } - } - - # - # Pad to a multiple of 512 bytes - # - - $pad_size = 512 - (length($header) + $output_size) % 512; - - if ($verbose) { - print("Padding boot image by an additional $pad_size bytes.\n"); - } - - $pad_string = pack(("H8","deadbeef") x 128); - - syswrite(BOOT, $pad_string, $pad_size) or - die "Could not pad boot image in output file.\n"; - - # - # Clean-up and leave - # - - close(BOOT); - - print("\nBoot image file \"$ofile\" built successfully.\n\n"); - - exit(0); -} diff -Nru a/arch/ppc/treeboot/mkirimg b/arch/ppc/treeboot/mkirimg --- a/arch/ppc/treeboot/mkirimg Mon May 21 17:07:04 2001 +++ /dev/null Wed Dec 31 16:00:00 1969 @@ -1,367 +0,0 @@ -#!/usr/bin/perl -# -# Copyright (c) 1998-1999 TiVo, Inc. -# Original ELF parsing code. -# -# Copyright (c) 1999 Grant Erickson -# Original code from 'mkevimg'. -# -# Module name: mkirimg -# -# Description: -# Reads an ELF file and assigns global variables 'imageSect_start', -# 'imageSect_size', 'initrdSect_start', and 'initrdSect_size' from -# the "image" and "initrd" section header information. It then -# rewrites the input ELF file with assigned globals to an output -# file. -# -# An input file, "irSectStart.txt" has the memory address of -# 'irSectStart'. The irSectStart memory address is used to find -# the global variables in the ".data" section of the ELF file. -# The 'irSectStart' and the above global variables are defined -# in "irSect.c". -# -# - -use File::Basename; -use Getopt::Std; - -# -# usage() -# -# Description: -# This routine prints out the proper command line usage for this program -# -# Input(s): -# status - Flag determining what usage information will be printed and what -# the exit status of the program will be after the information is -# printed. -# -# Output(s): -# N/A -# -# Returns: -# This subroutine does not return. -# - -sub usage { - my($status); - $status = $_[0]; - - printf("Usage: %s [-hvV] \n", - $program); - - if ($status != 0) { - printf("Try `%s -h' for more information.\n", $program); - } - - if ($status != 1) { - print(" -h Print out this message and exit.\n"); - print(" -v Verbose. Print out lots of ELF information.\n"); - print(" -V Print out version information and exit.\n"); - } - - exit($status); -} - -# -# version() -# -# Description: -# This routine prints out program version information -# -# Input(s): -# N/A -# -# Output(s): -# N/A -# -# Returns: -# This subroutine does not return. -# - -sub version { - print("mkirimg Version 1.1.0\n"); - print("Copyright (c) 1998-1999 TiVo, Inc.\n"); - print("Copyright (c) 1999 Grant Erickson \n"); - - exit (0); -} - -# -# file_check() -# -# Description: -# This routine checks an input file to ensure that it exists, is a -# regular file, and is readable. -# -# Input(s): -# file - Input file to be checked. -# -# Output(s): -# N/A -# -# Returns: -# 0 if the file exists, is a regular file, and is readable, otherwise -1. -# - -sub file_check { - my($file); - $file = $_[0]; - - if (!(-e $file)) { - printf("The file \"%s\" does not exist.\n", $file); - return (-1); - } elsif (!(-f $file)) { - printf("The file \"%s\" is not a regular file.\n", $file); - return (-1); - } elsif (!(-r $file)) { - printf("The file \"%s\" is not readable.\n", $file); - return (-1); - } - - return (0); -} - -# -# decode_options() -# -# Description: -# This routine steps through the command-line arguments, parsing out -# recognzied options. -# -# Input(s): -# N/A -# -# Output(s): -# N/A -# -# Returns: -# N/A -# - -sub decode_options { - - if (!getopts("hvV")) { - usage(1); - } - - if ($opt_h) { - usage(0); - } - - if ($opt_V) { - version(); - exit (0); - } - - if ($opt_v) { - $verbose = 1; - } - - if (!($ElfFile = shift(@ARGV))) { - usage(1); - } - - if (!($OutputFile = shift(@ARGV))) { - usage (1); - } - - if (!($IrFile = shift(@ARGV))) { - usage (1); - } - - if (file_check($ElfFile)) { - exit(1); - } - - if (file_check($IrFile)) { - exit(1); - } -} - -# -# ELF file and section header field numbers -# - -require 'elf.pl'; - -# -# Main program body -# - -{ - $program = basename($0); - decode_options(); - - open(ELF, "<$ElfFile") || die "Cannot open input file"; - open(OUTPUT, ">$OutputFile") || die "Cannot open output file"; - open(IR, "$IrFile") || die "Cannot open input file"; - - $ElfFilesize = (-s $ElfFile); - - if (read(ELF, $ibuf, $ElfFilesize) != $ElfFilesize) { - print("Failed to read ELF input file!\n"); - exit(1); - } - - if (read(IR, $irbuf, 8) != 8) { - print("Failed to read Ir input file!\n"); - exit(1); - } - - # - # Parse ELF header - # - - @eh = unpack("a16n2N5n6", $ibuf); - - # - # Make sure this is actually a PowerPC ELF file. - # - - if (substr($eh[$e_ident], 0, 4) ne "\177ELF") { - printf("The file \"%s\" is not an ELF file.\n", $ElfFile); - exit (1); - } elsif ($eh[$e_machine] != 20) { - printf("The file \"%s\" is not a PowerPC ELF file.\n", $ElfFile); - exit (1); - } - - # - # Find the section header for the string table. - # - - $strtable_section_offset = $eh[$e_shoff] + - - $eh[$e_shstrndx] * $eh[$e_shentsize]; - - if ($verbose) { - printf("String table section header offset: 0x%x\n", - $strtable_section_offset); - } - - # - # Find the start of the string table. - # - - @strh = unpack("N10", substr($ibuf, $strtable_section_offset, - $eh[$e_shentsize])); - - if ($verbose) { - printf("Section name strings start at: 0x%x, %d bytes.\n", - $strh[$sh_offset], $strh[$sh_size]); - } - - $names = substr($ibuf, $strh[$sh_offset], $strh[$sh_size]); - - # Grab each section header and find '.data', 'image', and - # 'initrd' sections in particular. - - $off = $eh[$e_shoff]; - $imageFound = 0; - $initrdFound = 0; - - for($i = 0; $i < $eh[$e_shnum]; $i++, $off += $eh[$e_shentsize]) { - @sh = unpack("N10", substr($ibuf, $off, $eh[$e_shentsize])); - - # Take the first section name from the array returned by split. - - ($name) = split(/\000/, substr($names, $sh[$sh_name])); - - # Attempt to find the .data, image, and initrd sections - - if ($name =~ /^\image$/) { - ($image_addr, $image_offset, $image_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - $imageFound = 1; - - } elsif ($name =~ /^\initrd$/) { - ($initrd_addr, $initrd_offset, $initrd_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - $initrdFound = 1; - - } elsif ($name =~ /^\.data$/) { - ($data_addr, $data_offset, $data_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - - } elsif ($name =~ /^\.bss$/) { - ($bss_addr, $bss_offset, $bss_size) = - ($sh[$sh_addr], $sh[$sh_offset], $sh[$sh_size]); - - } - } - - if ($verbose) { - printf("Data section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n", - $data_addr, $data_size, $data_offset); - printf("Bss section - Address: 0x%08x, Size: 0x%08x, File Offset 0x%08x\n", - $bss_addr, $bss_size, $bss_offset); - } - - if ($verbose) { - if ($imageFound) { - printf("Image section - Address: 0x%08x, Size: 0x%08x\n", - $image_addr, $image_size); - } else { - printf("Image section not found in file: $ElfFile\n"); - } - - if ($initrdFound) { - printf("Initrd section - Address: 0x%08x, Size: 0x%08x\n", - $initrd_addr, $initrd_size); - } else { - printf("Initrd section not found in file: $ElfFile\n"); - } - } - - # get file offset of irSectStart - - $irSectStartoffset = hex ($irbuf); - - if ($verbose) { - printf("irSectStartOffset Address: 0x%08x\n", $irSectStartoffset); - } - - # get the offset of global variables - - $initialOffset = ($irSectStartoffset - $data_addr) + $data_offset + 4; - - # write modified values to OUTPUT file - - syswrite(OUTPUT, $ibuf, $initialOffset); - - if ($imageFound) { - $testN = pack ("N2", $bss_addr + $bss_size, $image_size); - syswrite(OUTPUT, $testN, length($testN)); - printf("Updated symbol \"imageSect_start\" to 0x%08x\n", - $bss_addr + $bss_size); - printf("Updated symbol \"imageSect_size\" to 0x%08x\n", $image_size); - } else { - syswrite(OUTPUT, $ibuf, 8, $initialOffset); - } - - if ($initrdFound) { - $testN = pack ("N2", $bss_addr + $bss_size + $image_size, $initrd_size); - syswrite(OUTPUT, $testN, length($testN)); - printf("Updated symbol \"initrdSect_start\" to 0x%08x\n", - $bss_addr + $bss_size + $image_size); - printf("Updated symbol \"initrdSect_size\" to 0x%08x\n", $initrd_size); - } else { - syswrite(OUTPUT, $ibuf,8, $initialOffset + 8); - } - - syswrite(OUTPUT, $ibuf, $ElfFilesize - ($initialOffset + 16), - $initialOffset + 16); - - # - # Clean-up and leave - # - - close (ELF); - close (OUTPUT); - close (IR); - - exit (0); -} - diff -Nru a/arch/ppc/xmon/Makefile b/arch/ppc/xmon/Makefile --- a/arch/ppc/xmon/Makefile Mon May 21 17:07:04 2001 +++ b/arch/ppc/xmon/Makefile Mon May 21 17:07:04 2001 @@ -1,3 +1,5 @@ +# BK Id: %F% %I% %G% %U% %#% +# # Makefile for xmon O_TARGET := x.o diff -Nru a/arch/ppc/xmon/adb.c b/arch/ppc/xmon/adb.c --- a/arch/ppc/xmon/adb.c Mon May 21 17:07:05 2001 +++ b/arch/ppc/xmon/adb.c Mon May 21 17:07:05 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Copyright (C) 1996 Paul Mackerras. */ #include "nonstdio.h" diff -Nru a/arch/ppc/xmon/ansidecl.h b/arch/ppc/xmon/ansidecl.h --- a/arch/ppc/xmon/ansidecl.h Mon May 21 17:07:04 2001 +++ b/arch/ppc/xmon/ansidecl.h Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ /* ANSI and traditional C compatability macros Copyright 1991, 1992 Free Software Foundation, Inc. This file is part of the GNU C Library. diff -Nru a/arch/ppc/xmon/nonstdio.h b/arch/ppc/xmon/nonstdio.h --- a/arch/ppc/xmon/nonstdio.h Mon May 21 17:07:03 2001 +++ b/arch/ppc/xmon/nonstdio.h Mon May 21 17:07:03 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ typedef int FILE; extern FILE *xmon_stdin, *xmon_stdout; #define EOF (-1) diff -Nru a/arch/ppc/xmon/ppc-dis.c b/arch/ppc/xmon/ppc-dis.c --- a/arch/ppc/xmon/ppc-dis.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/xmon/ppc-dis.c Mon May 21 17:07:03 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ /* ppc-dis.c -- Disassemble PowerPC instructions Copyright 1994 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support diff -Nru a/arch/ppc/xmon/ppc-opc.c b/arch/ppc/xmon/ppc-opc.c --- a/arch/ppc/xmon/ppc-opc.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/xmon/ppc-opc.c Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ /* ppc-opc.c -- PowerPC opcode list Copyright 1994 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support diff -Nru a/arch/ppc/xmon/ppc.h b/arch/ppc/xmon/ppc.h --- a/arch/ppc/xmon/ppc.h Mon May 21 17:07:04 2001 +++ b/arch/ppc/xmon/ppc.h Mon May 21 17:07:04 2001 @@ -1,3 +1,6 @@ +/* + * BK Id: %F% %I% %G% %U% %#% + */ /* ppc.h -- Header file for PowerPC opcode table Copyright 1994 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support diff -Nru a/arch/ppc/xmon/privinst.h b/arch/ppc/xmon/privinst.h --- a/arch/ppc/xmon/privinst.h Mon May 21 17:07:04 2001 +++ b/arch/ppc/xmon/privinst.h Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Copyright (C) 1996 Paul Mackerras. */ #include diff -Nru a/arch/ppc/xmon/setjmp.c b/arch/ppc/xmon/setjmp.c --- a/arch/ppc/xmon/setjmp.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/xmon/setjmp.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Copyright (C) 1996 Paul Mackerras. * * NB this file must be compiled with -O2. diff -Nru a/arch/ppc/xmon/start.c b/arch/ppc/xmon/start.c --- a/arch/ppc/xmon/start.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/xmon/start.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Copyright (C) 1996 Paul Mackerras. */ #include diff -Nru a/arch/ppc/xmon/start_8xx.c b/arch/ppc/xmon/start_8xx.c --- a/arch/ppc/xmon/start_8xx.c Mon May 21 17:07:04 2001 +++ b/arch/ppc/xmon/start_8xx.c Mon May 21 17:07:04 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Copyright (C) 1996 Paul Mackerras. * Copyright (C) 2000 Dan Malek. * Quick hack of Paul's code to make XMON work on 8xx processors. Lots diff -Nru a/arch/ppc/xmon/subr_prf.c b/arch/ppc/xmon/subr_prf.c --- a/arch/ppc/xmon/subr_prf.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/xmon/subr_prf.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Written by Cort Dougan to replace the version originally used * by Paul Mackerras, which came from NetBSD and thus had copyright * conflicts with Linux. diff -Nru a/arch/ppc/xmon/xmon.c b/arch/ppc/xmon/xmon.c --- a/arch/ppc/xmon/xmon.c Mon May 21 17:07:03 2001 +++ b/arch/ppc/xmon/xmon.c Mon May 21 17:07:03 2001 @@ -1,4 +1,7 @@ /* + * BK Id: %F% %I% %G% %U% %#% + */ +/* * Routines providing a simple monitor for use on the PowerMac. * * Copyright (C) 1996 Paul Mackerras. @@ -1016,7 +1019,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 Mon May 21 17:07:04 2001 +++ b/drivers/Makefile Mon May 21 17:07:04 2001 @@ -23,7 +23,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 Mon May 21 17:07:03 2001 +++ b/drivers/block/swim3.c Mon May 21 17:07:03 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 Mon May 21 17:07:03 2001 +++ b/drivers/char/keyboard.c Mon May 21 17:07:03 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 +#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 Mon May 21 17:07:05 2001 +++ b/drivers/i2c/i2c-core.c Mon May 21 17:07:05 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 Mon May 21 17:07:05 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 Mon May 21 17:07:03 2001 +++ b/drivers/ide/ide-features.c Mon May 21 17:07:03 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/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c --- a/drivers/macintosh/mac_hid.c Mon May 21 17:07:03 2001 +++ b/drivers/macintosh/mac_hid.c Mon May 21 17:07:03 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 Mon May 21 17:07:04 2001 +++ b/drivers/macintosh/mac_keyb.c Mon May 21 17:07:04 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 Mon May 21 17:07:04 2001 +++ b/drivers/macintosh/macserial.c Mon May 21 17:07:04 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 */ @@ -3119,7 +3135,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 Mon May 21 17:07:05 2001 +++ b/drivers/macintosh/macserial.h Mon May 21 17:07:05 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/pci/Makefile b/drivers/pci/Makefile --- a/drivers/pci/Makefile Mon May 21 17:07:04 2001 +++ b/drivers/pci/Makefile Mon May 21 17:07:04 2001 @@ -22,6 +22,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_PPC) += setup-bus.o setup-irq.o ifndef CONFIG_X86 obj-y += syscall.o diff -Nru a/drivers/pci/pci.c b/drivers/pci/pci.c --- a/drivers/pci/pci.c Mon May 21 17:07:04 2001 +++ b/drivers/pci/pci.c Mon May 21 17:07:04 2001 @@ -1185,8 +1185,15 @@ /* Go find them, Rover! */ for (devfn = 0; devfn < 0x100; devfn += 8) { - dev0.devfn = devfn; - pci_scan_slot(&dev0); +#if defined(CONFIG_SANDPOINT) + if ((bus->number != 0) || (PCI_SLOT(devfn) != 12)) +#elif defined(CONFIG_ZX4500) + if ((bus->number != 0) || (PCI_SLOT(devfn) != 20)) +#endif + { + dev0.devfn = devfn; + pci_scan_slot(&dev0); + } } /* diff -Nru a/drivers/pci/pci.ids b/drivers/pci/pci.ids --- a/drivers/pci/pci.ids Mon May 21 17:07:04 2001 +++ b/drivers/pci/pci.ids Mon May 21 17:07:04 2001 @@ -1069,6 +1069,13 @@ 000e Hydra Mac I/O 0010 Heathrow Mac I/O 0017 Paddington Mac I/O + 0018 UniNorth FireWire + 0019 KeyLargo USB + 001e UniNorth PCI + 001f UniNorth PCI + 0020 UniNorth AGP + 0021 UniNorth GMAC + 0022 KeyLargo Mac I/O 106c Hyundai Electronics America 8801 Dual Pentium ISA/PCI Motherboard 8802 PowerPC ISA/PCI Motherboard diff -Nru a/drivers/scsi/sym53c8xx_defs.h b/drivers/scsi/sym53c8xx_defs.h --- a/drivers/scsi/sym53c8xx_defs.h Mon May 21 17:07:04 2001 +++ b/drivers/scsi/sym53c8xx_defs.h Mon May 21 17:07:04 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/sound/dmasound/Makefile b/drivers/sound/dmasound/Makefile --- a/drivers/sound/dmasound/Makefile Mon May 21 17:07:04 2001 +++ b/drivers/sound/dmasound/Makefile Mon May 21 17:07:04 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 Mon May 21 17:07:04 2001 +++ b/drivers/sound/dmasound/dmasound.h Mon May 21 17:07:04 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 Mon May 21 17:07:03 2001 +++ b/drivers/sound/dmasound/dmasound_atari.c Mon May 21 17:07:03 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 Mon May 21 17:07:04 2001 +++ b/drivers/sound/dmasound/dmasound_awacs.c Mon May 21 17:07:04 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 Mon May 21 17:07:04 2001 +++ b/drivers/sound/dmasound/dmasound_core.c Mon May 21 17:07:04 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 Mon May 21 17:07:03 2001 +++ b/drivers/video/aty128.h Mon May 21 17:07:03 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 Mon May 21 17:07:04 2001 +++ b/drivers/video/aty128fb.c Mon May 21 17:07:04 2001 @@ -67,6 +67,9 @@ #ifdef CONFIG_FB_COMPAT_XPMAC #include #endif +#ifdef CONFIG_BOOTX_TEXT +#include +#endif /* CONFIG_BOOTX_TEXT */ #include